"""Frontend API extraction schema."""

from maeris_mcp.schemas.registry import Schema
from maeris_mcp.types.protocol import ExtractionInstructions, OperationType


def _payload_field_schema() -> dict:
    """Return the schema for payload fields."""
    return {
        "type": "object",
        "required": ["name", "type", "required"],
        "properties": {
            "name": {"type": "string", "description": "Field name"},
            "type": {"type": "string", "description": "TypeScript type"},
            "required": {"type": "boolean", "description": "Whether field is required"},
            "description": {"type": "string", "description": "Field description"},
            "children": {"type": "array", "description": "Nested fields for objects"},
        },
    }


def api_extraction_schema() -> Schema:
    """Return the JSON schema for frontend API extraction."""
    return Schema(
        id="frontend-api-v1",
        name="Frontend API Extraction",
        description="Schema for extracting API calls from frontend code",
        applicable_operations=[OperationType.EXTRACT_APIS],
        json_schema={
            "$schema": "http://json-schema.org/draft-07/schema#",
            "title": "FrontendAPIExtraction",
            "description": "Structured data about API calls in frontend code",
            "type": "object",
            "required": ["projectName", "rootPath", "apis"],
            "properties": {
                "projectName": {"type": "string", "description": "Name of the project"},
                "rootPath": {"type": "string", "description": "Root path of the project"},
                "httpClients": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "HTTP client libraries detected (axios, fetch, ky, etc.)",
                },
                "apis": {
                    "type": "array",
                    "description": "List of extracted API calls",
                    "items": {
                        "type": "object",
                        "required": ["name", "endpoint", "method", "callSites"],
                        "properties": {
                            "name": {"type": "string", "description": "Descriptive name for this API call"},
                            "endpoint": {"type": "string", "description": "API endpoint URL or pattern (e.g., /api/users/:id)"},
                            "baseUrl": {"type": "string", "description": "Base URL if configured (e.g., from environment variable name)"},
                            "method": {
                                "type": "string",
                                "enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"],
                                "description": "HTTP method",
                            },
                            "headers": {
                                "type": "array",
                                "description": "HTTP headers sent with request",
                                "items": {
                                    "type": "object",
                                    "required": ["name", "isRequired"],
                                    "properties": {
                                        "name": {"type": "string", "description": "Header name"},
                                        "value": {"type": "string", "description": "Static value description if known (not actual value)"},
                                        "source": {"type": "string", "description": "Where value comes from (env, state, constant)"},
                                        "isRequired": {"type": "boolean", "description": "Whether header is always sent"},
                                    },
                                },
                            },
                            "queryParams": {
                                "type": "array",
                                "description": "URL query parameters",
                                "items": {
                                    "type": "object",
                                    "required": ["name", "type", "required"],
                                    "properties": {
                                        "name": {"type": "string", "description": "Parameter name"},
                                        "type": {"type": "string", "description": "TypeScript type"},
                                        "required": {"type": "boolean", "description": "Whether required"},
                                        "description": {"type": "string", "description": "What this parameter is for"},
                                    },
                                },
                            },
                            "pathParams": {
                                "type": "array",
                                "description": "URL path parameters (e.g., :id in /users/:id)",
                                "items": {
                                    "type": "object",
                                    "required": ["name", "type"],
                                    "properties": {
                                        "name": {"type": "string", "description": "Parameter name"},
                                        "type": {"type": "string", "description": "TypeScript type"},
                                        "description": {"type": "string", "description": "What this parameter represents"},
                                    },
                                },
                            },
                            "requestPayload": {
                                "type": "object",
                                "description": "Request body structure",
                                "properties": {
                                    "contentType": {"type": "string", "description": "Content-Type (application/json, multipart/form-data, etc.)"},
                                    "typeName": {"type": "string", "description": "TypeScript interface/type name if defined"},
                                    "isArray": {"type": "boolean", "description": "Whether payload is an array"},
                                    "fields": {"type": "array", "items": _payload_field_schema(), "description": "Fields in the request payload"},
                                },
                            },
                            "responsePayload": {
                                "type": "object",
                                "description": "Expected response structure",
                                "properties": {
                                    "contentType": {"type": "string", "description": "Response Content-Type"},
                                    "typeName": {"type": "string", "description": "TypeScript type name"},
                                    "isArray": {"type": "boolean", "description": "Whether response is an array"},
                                    "fields": {"type": "array", "items": _payload_field_schema(), "description": "Fields in the response"},
                                },
                            },
                            "auth": {
                                "type": "object",
                                "description": "Authentication configuration",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": ["none", "bearer", "basic", "api_key", "oauth", "custom"],
                                        "description": "Authentication mechanism type",
                                    },
                                    "headerName": {"type": "string", "description": "Header name for auth (e.g., Authorization, X-API-Key)"},
                                    "tokenSource": {"type": "string", "description": "Where token/credentials come from (e.g., localStorage, context, env var name)"},
                                },
                            },
                            "callSites": {
                                "type": "array",
                                "description": "Locations where this API is called",
                                "items": {
                                    "type": "object",
                                    "required": ["filePath"],
                                    "properties": {
                                        "filePath": {"type": "string", "description": "Relative file path"},
                                        "componentName": {"type": "string", "description": "Component name if called from component"},
                                        "functionName": {"type": "string", "description": "Function name if called from function"},
                                        "hookName": {"type": "string", "description": "Hook name if called from hook"},
                                        "lineNumber": {"type": "integer", "description": "Line number (approximate)"},
                                    },
                                },
                            },
                            "description": {"type": "string", "description": "What this API does"},
                            "tags": {"type": "array", "items": {"type": "string"}, "description": "Categorization tags (e.g., user, auth, payment)"},
                            "isDeprecated": {"type": "boolean", "description": "Whether the API is marked as deprecated"},
                            "errorHandling": {"type": "string", "description": "How errors are handled (try-catch, .catch, error boundary)"},
                        },
                    },
                },
            },
        },
        instructions=ExtractionInstructions(
            overview="Extract all API calls from frontend code without including actual implementation code or sensitive data.",
            steps=[
                "1. Identify HTTP client usage (fetch, axios, ky, got, superagent, etc.)",
                "2. Find all API call locations in components, hooks, services, and utilities",
                "3. Extract endpoint URL patterns (replace dynamic values with placeholders like :id)",
                "4. Determine HTTP method for each call",
                "5. Identify headers being sent (names and sources only, not actual values)",
                "6. Extract request/response payload structures from TypeScript types or JSDoc",
                "7. Detect authentication patterns (bearer tokens, API keys, cookies, etc.)",
                "8. Map call sites to components/functions/hooks where API is used",
                "9. Look for error handling patterns around API calls",
                "10. Identify any query parameters and path parameters",
            ],
            field_guidance={
                "endpoint": "Use URL patterns with placeholders like :id, :userId for dynamic segments. Never include actual IDs, query values, or sensitive data.",
                "baseUrl": "Reference the environment variable name or config key, not the actual URL value.",
                "headers": "List header names and describe where values come from (e.g., 'from localStorage', 'from auth context'). Never include actual header values, tokens, or secrets.",
                "auth": "Describe the auth mechanism type and where credentials are sourced. Never include actual tokens, keys, or credentials.",
                "requestPayload": "List field names and TypeScript types. Never include actual data values or examples with real data.",
                "responsePayload": "List expected response structure using types from the codebase. Never include actual response data.",
                "callSites": "List file paths relative to project root and function/component names where API is called.",
                "queryParams": "List parameter names and types. Do not include actual values.",
                "pathParams": "List path parameter names (e.g., 'id' from '/users/:id') and their types.",
            },
            privacy_notes=[
                "NEVER include actual API keys, tokens, passwords, or credentials",
                "NEVER include actual request/response data values or examples",
                "NEVER include environment variable values, only variable names (e.g., 'REACT_APP_API_URL' not 'https://api.example.com')",
                "Use placeholders like :id, :userId for dynamic URL segments",
                "Only include type information and field names, not actual business data",
                "Do not expose internal API paths that could reveal security-sensitive infrastructure",
                "Reference auth token sources (e.g., 'from localStorage key: token') not actual tokens",
            ],
        ),
    )
