"""SAX circuit simulation tool handler.

This module provides the handler for running SAX circuit simulations
on photonic components, with fallback to the old API.
"""

from __future__ import annotations

import json
from typing import Any

from mcp.types import Tool

from .base import EndpointMapping, ToolHandler, add_project_param

__all__ = ["SimulateComponentHandler"]


class SimulateComponentHandler(ToolHandler):
    """Handler for running SAX circuit simulations.

    Supports both the new SAX API (/api/sax/{name}/simulate) and
    falls back to the old API (/api/simulate) if the new endpoint
    returns 404.
    """

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

    @property
    def definition(self) -> Tool:
        return Tool(
            name="simulate_component",
            description=(
                "Run a SAX circuit simulation on a photonic component by name. "
                "This simulates the optical behavior of the component using its "
                "SAX model. Returns S-parameters showing how light propagates "
                "through the component's ports. Use this to analyze component "
                "performance before fabrication. Supports customizing both layout "
                "parameters (e.g., {'length_mmi': 12, 'gap_mmi': 0.3}) and SAX "
                "model simulation settings (e.g., {'wl': [1.5, 1.55, 1.6], 'loss': 0.2})."
            ),
            inputSchema=add_project_param(
                {
                    "type": "object",
                    "properties": {
                        "name": {
                            "type": "string",
                            "description": (
                                "Name of the component/cell to simulate. The component "
                                "must have a SAX model defined."
                            ),
                        },
                        "layout": {
                            "type": "object",
                            "description": (
                                "Optional component-specific geometric parameters. "
                                "Use this to customize the component's physical dimensions "
                                "before simulation. Example: {'length_mmi': 12, 'gap_mmi': 0.3}. "
                                "Default is empty (use default layout parameters)."
                            ),
                        },
                        "model": {
                            "type": "object",
                            "description": (
                                "Optional SAX simulation settings. Use this to configure "
                                "simulation parameters like wavelength sweeps or loss values. "
                                "Example: {'wl': [1.5, 1.55, 1.6], 'loss': 0.2}. "
                                "Default is empty (use default model parameters)."
                            ),
                        },
                        "how": {
                            "type": "string",
                            "enum": ["from_layout", "from_netlist"],
                            "description": (
                                "Simulation method. 'from_layout' simulates from the physical "
                                "layout geometry (default). 'from_netlist' simulates from the "
                                "hierarchical netlist representation."
                            ),
                        },
                    },
                    "required": ["name"],
                }
            ),
        )

    @property
    def mapping(self) -> EndpointMapping:
        return EndpointMapping(method="POST", path="/api/sax/{name}/simulate")

    def transform_request(self, args: dict[str, Any]) -> dict[str, Any]:
        """Transform simulate_component MCP args to FastAPI request body.

        Supports both new SAX API (/api/sax/{name}/simulate) and falls back
        to old API (/api/simulate) if the new endpoint returns 404.

        Args:
            args: MCP tool arguments

        Returns:
            Dict with 'path', 'json_data' for new API and fallback data for old API
        """
        name = args["name"]
        layout = args.get("layout", {})
        model = args.get("model", {})
        how = args.get("how", "from_layout")

        return {
            "path": f"/api/sax/{name}/simulate",
            "json_data": {
                "layout": layout,
                "model": model,
                "from_netlist": how == "from_netlist",
            },
            "fallback_path": "/api/simulate",
            "fallback_json_data": {
                "name": name,
                "layout": layout,
                "model": model,
                "how": how,
            },
        }

    def transform_response(self, response: Any) -> dict[str, Any]:
        """Transform simulate_component response for LLM consumption.

        Returns only the file path and token estimate instead of the full
        S-parameter data, which can be extremely large (500k+ tokens).

        Args:
            response: FastAPI response containing simulation results

        Returns:
            Dict with file path, token estimate, and metadata
        """
        if not isinstance(response, dict):
            return {"error": f"Unexpected response type: {type(response).__name__}"}

        # Estimate tokens (rough heuristic: ~4 chars per token)
        json_str = json.dumps(response)
        estimated_tokens = len(json_str) // 4

        file_path = response.get("file_path")

        return {
            "file_path": file_path,
            "estimated_tokens": estimated_tokens,
            "message": f"Simulation complete. Results saved to: {file_path}",
            "note": "Use the Read tool to view the simulation results at this path.",
            "simulation_id": response.get("simulation_id"),
            "cached": response.get("cached", False),
        }
