"""Sample project tool handlers.

These tools allow AI assistants to browse and read sample files
from GDSFactory+ General PDK sample projects.
"""

from __future__ import annotations

import json
import logging
from typing import TYPE_CHECKING, Any

from mcp.types import TextContent, Tool

from ..config import get_gfp_api_key
from ..samples import (
    GENERAL_PDK_PROJECTS,
    get_sample_file_content,
    list_sample_projects,
)
from .base import ToolHandler

if TYPE_CHECKING:
    from ..client import FastAPIClient

__all__ = ["ListSamplesHandler", "GetSampleFileHandler"]

logger = logging.getLogger(__name__)

_API_KEY_ERROR = {
    "error": "GFP API key not configured",
    "instructions": (
        "Set the GFP_API_KEY environment variable or configure "
        "~/.gdsfactory/gdsfactoryplus.toml with your API key. "
        "Get your key at: https://api.gdsfactory.com/api-keys/list"
    ),
}


class ListSamplesHandler(ToolHandler):
    """Handler for listing sample files from General PDK projects.

    Downloads project ZIPs from the registry and returns file listings.
    This is a registry-only tool that doesn't use the FastAPI backend.
    """

    @property
    def name(self) -> str:
        return "list_samples"

    @property
    def definition(self) -> Tool:
        return Tool(
            name="list_samples",
            description=(
                "List all available sample files from GDSFactory+ General PDK "
                "sample projects. Returns file listings for the basic and full "
                "public PDK projects. Requires a GFP API key."
            ),
            inputSchema={
                "type": "object",
                "properties": {},
            },
        )

    async def handle(
        self,
        arguments: dict[str, Any],
        client: FastAPIClient,
    ) -> list[TextContent]:
        """List sample files from all General PDK projects.

        Args:
            arguments: MCP tool arguments (unused).
            client: FastAPI client (unused, samples come from registry).

        Returns:
            List containing TextContent with project file listings.
        """
        api_key = get_gfp_api_key()
        if not api_key:
            return [TextContent(type="text", text=json.dumps(_API_KEY_ERROR))]

        try:
            projects = await list_sample_projects(api_key)
            result = {
                "projects": [{"name": p.name, "files": p.files} for p in projects]
            }
            return [TextContent(type="text", text=json.dumps(result, indent=2))]
        except Exception as e:
            error_msg = f"Failed to fetch samples: {e!s}"
            logger.exception(error_msg)
            return [
                TextContent(
                    type="text",
                    text=json.dumps({"error": error_msg}),
                )
            ]


class GetSampleFileHandler(ToolHandler):
    """Handler for reading a specific sample file's content.

    Downloads a project ZIP and extracts the requested file.
    This is a registry-only tool that doesn't use the FastAPI backend.
    """

    @property
    def name(self) -> str:
        return "get_sample_file"

    @property
    def definition(self) -> Tool:
        return Tool(
            name="get_sample_file",
            description=(
                "Get the content of a specific sample file from a GDSFactory+ "
                "General PDK project. Use list_samples first to discover "
                "available files. Requires a GFP API key."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "project": {
                        "type": "string",
                        "description": (
                            "Sample project name "
                            "(e.g., 'photonics--basic--public--pdk')."
                        ),
                    },
                    "path": {
                        "type": "string",
                        "description": (
                            "File path within the project ZIP "
                            "(as returned by list_samples)."
                        ),
                    },
                },
                "required": ["project", "path"],
            },
        )

    async def handle(
        self,
        arguments: dict[str, Any],
        client: FastAPIClient,
    ) -> list[TextContent]:
        """Get the content of a specific sample file.

        Args:
            arguments: MCP tool arguments with 'project' and 'path'.
            client: FastAPI client (unused, samples come from registry).

        Returns:
            List containing TextContent with file content and metadata.
        """
        api_key = get_gfp_api_key()
        if not api_key:
            return [TextContent(type="text", text=json.dumps(_API_KEY_ERROR))]

        project = arguments.get("project")
        path = arguments.get("path")

        if not project or not path:
            return [
                TextContent(
                    type="text",
                    text=json.dumps(
                        {"error": "Both 'project' and 'path' parameters are required"}
                    ),
                )
            ]

        try:
            sample_file = await get_sample_file_content(api_key, project, path)
            result = {
                "project": sample_file.project,
                "path": sample_file.path,
                "content": sample_file.content,
                "metadata": {"mime_type": sample_file.mime_type},
            }
            return [TextContent(type="text", text=json.dumps(result, indent=2))]
        except ValueError:
            return [
                TextContent(
                    type="text",
                    text=json.dumps(
                        {
                            "error": f"Unknown sample project: {project}",
                            "available_projects": GENERAL_PDK_PROJECTS,
                        }
                    ),
                )
            ]
        except KeyError:
            return [
                TextContent(
                    type="text",
                    text=json.dumps(
                        {
                            "error": f"File not found in project: {path}",
                            "suggestion": ("Use list_samples to see available files."),
                        }
                    ),
                )
            ]
        except Exception as e:
            error_msg = f"Failed to fetch sample file: {e!s}"
            logger.exception(error_msg)
            return [
                TextContent(
                    type="text",
                    text=json.dumps({"error": error_msg}),
                )
            ]
