"""
Board layer command implementations for KiCAD interface
"""

import logging
from typing import Any, Dict, Optional

import pcbnew

logger = logging.getLogger("kicad_interface")


class BoardLayerCommands:
    """Handles board layer operations"""

    def __init__(self, board: Optional[pcbnew.BOARD] = None):
        """Initialize with optional board instance"""
        self.board = board

    def add_layer(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """Add a new layer to the PCB"""
        try:
            if not self.board:
                return {
                    "success": False,
                    "message": "No board is loaded",
                    "errorDetails": "Load or create a board first",
                }

            name = params.get("name")
            layer_type = params.get("type")
            position = params.get("position")
            number = params.get("number")

            if not name or not layer_type or not position:
                return {
                    "success": False,
                    "message": "Missing parameters",
                    "errorDetails": "name, type, and position are required",
                }

            # Determine layer ID based on position and number
            layer_id = None
            if position == "inner":
                if number is None:
                    return {
                        "success": False,
                        "message": "Missing layer number",
                        "errorDetails": "number is required for inner layers",
                    }
                layer_id = pcbnew.In1_Cu + (number - 1)
            elif position == "top":
                layer_id = pcbnew.F_Cu
            elif position == "bottom":
                layer_id = pcbnew.B_Cu

            if layer_id is None:
                return {
                    "success": False,
                    "message": "Invalid layer position",
                    "errorDetails": "position must be 'top', 'bottom', or 'inner'",
                }

            # Enable inner copper layers by increasing copper layer count (KiCAD 9.0 API)
            if position == "inner":
                current_count = self.board.GetCopperLayerCount()
                needed_count = 2 + (number or 0)  # F.Cu + B.Cu + inner layers
                if needed_count > current_count:
                    self.board.SetCopperLayerCount(needed_count)

            # Set layer properties directly on board (GetLayerStack removed in KiCAD 9.0)
            self.board.SetLayerName(layer_id, name)
            self.board.SetLayerType(layer_id, self._get_layer_type(layer_type))

            return {
                "success": True,
                "message": f"Added layer: {name}",
                "layer": {"name": name, "type": layer_type, "position": position, "number": number},
            }

        except Exception as e:
            logger.error(f"Error adding layer: {str(e)}")
            return {"success": False, "message": "Failed to add layer", "errorDetails": str(e)}

    def set_active_layer(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """Set the active layer for PCB operations"""
        try:
            if not self.board:
                return {
                    "success": False,
                    "message": "No board is loaded",
                    "errorDetails": "Load or create a board first",
                }

            layer = params.get("layer")
            if not layer:
                return {
                    "success": False,
                    "message": "No layer specified",
                    "errorDetails": "layer parameter is required",
                }

            # Find layer ID by name
            layer_id = self.board.GetLayerID(layer)
            if layer_id < 0:
                return {
                    "success": False,
                    "message": "Layer not found",
                    "errorDetails": f"Layer '{layer}' does not exist",
                }

            # Set active layer
            self.board.SetActiveLayer(layer_id)

            return {
                "success": True,
                "message": f"Set active layer to: {layer}",
                "layer": {"name": layer, "id": layer_id},
            }

        except Exception as e:
            logger.error(f"Error setting active layer: {str(e)}")
            return {
                "success": False,
                "message": "Failed to set active layer",
                "errorDetails": str(e),
            }

    def get_layer_list(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """Get a list of all layers in the PCB"""
        try:
            if not self.board:
                return {
                    "success": False,
                    "message": "No board is loaded",
                    "errorDetails": "Load or create a board first",
                }

            layers = []
            for layer_id in range(pcbnew.PCB_LAYER_ID_COUNT):
                if self.board.IsLayerEnabled(layer_id):
                    layers.append(
                        {
                            "name": self.board.GetLayerName(layer_id),
                            "type": self._get_layer_type_name(self.board.GetLayerType(layer_id)),
                            "id": layer_id,
                            # Note: isActive removed - GetActiveLayer() doesn't exist in KiCAD 9.0
                            # Active layer is a UI concept not applicable to headless scripting
                        }
                    )

            return {"success": True, "layers": layers}

        except Exception as e:
            logger.error(f"Error getting layer list: {str(e)}")
            return {"success": False, "message": "Failed to get layer list", "errorDetails": str(e)}

    def _get_layer_type(self, type_name: str) -> int:
        """Convert layer type name to KiCAD layer type constant"""
        type_map = {
            "copper": pcbnew.LT_SIGNAL,
            "technical": pcbnew.LT_SIGNAL,
            "user": pcbnew.LT_SIGNAL,  # LT_USER removed in KiCAD 9.0, use LT_SIGNAL instead
            "signal": pcbnew.LT_SIGNAL,
        }
        return type_map.get(type_name.lower(), pcbnew.LT_SIGNAL)

    def _get_layer_type_name(self, type_id: int) -> str:
        """Convert KiCAD layer type constant to name"""
        type_map = {
            pcbnew.LT_SIGNAL: "signal",
            pcbnew.LT_POWER: "power",
            pcbnew.LT_MIXED: "mixed",
            pcbnew.LT_JUMPER: "jumper",
        }
        # Note: LT_USER was removed in KiCAD 9.0
        return type_map.get(type_id, "unknown")
