"""Handler for run_drc command."""

import json
import subprocess
import tempfile
from pathlib import Path


def handle_run_drc(kicad_info: dict, args: dict) -> dict:
    """Run DRC on a PCB file using kicad-cli and parse JSON results."""
    if not kicad_info.get("installed"):
        return {
            "success": False,
            "error": "KiCad not installed",
            "_hint": "Report to the user and ask them to install KiCad from https://www.kicad.org/download/, then retry.",
        }

    file_path = args.get("filePath", "")
    if not file_path:
        return {"success": False, "error": "No filePath specified"}

    pcb_path = Path(file_path)
    if not pcb_path.exists():
        return {
            "success": False,
            "error": f"PCB file not found: {file_path}",
            "_hint": "The path may exist on Docker but not on the Windows host. Use push_file to copy from Docker first, or verify the host-side path.",
        }

    cli_exe = kicad_info.get("kicad_cli_exe")
    if not cli_exe or not Path(cli_exe).exists():
        return {
            "success": False,
            "error": "kicad-cli not found",
            "_hint": "Report to the user and ask them to reinstall KiCad — kicad-cli is missing from the installation.",
        }

    # Create a temp file for the JSON output
    tmp_fd, output_path = tempfile.mkstemp(suffix=".json")
    import os
    os.close(tmp_fd)

    try:
        cmd = [
            cli_exe,
            "pcb", "drc",
            "--format", "json",
            "--severity-all",
            "--all-track-errors",
            "--output", output_path,
            str(pcb_path),
        ]

        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=120,
        )

        output_file = Path(output_path)
        if not output_file.exists() or output_file.stat().st_size == 0:
            return {
                "success": False,
                "error": f"DRC produced no output. stderr: {result.stderr}",
            }

        with open(output_path, "r", encoding="utf-8") as f:
            drc_data = json.load(f)

        violations = _parse_violations(drc_data)

        total = len(violations)
        errors = sum(1 for v in violations if v["severity"] == "error")
        warnings = sum(1 for v in violations if v["severity"] == "warning")

        return {
            "success": True,
            "output": f"DRC complete: {errors} error(s), {warnings} warning(s), {total} total",
            "data": {
                "violations": violations,
                "summary": {
                    "total": total,
                    "errors": errors,
                    "warnings": warnings,
                },
                "source_file": str(pcb_path),
            },
        }

    except subprocess.TimeoutExpired:
        return {"success": False, "error": "DRC timed out after 120 seconds"}
    except json.JSONDecodeError as e:
        return {"success": False, "error": f"Failed to parse DRC JSON output: {e}"}
    except Exception as e:
        return {"success": False, "error": f"DRC failed: {e}"}
    finally:
        try:
            Path(output_path).unlink(missing_ok=True)
        except OSError:
            pass


def _parse_violations(drc_data: dict) -> list:
    """Extract structured violation list from DRC JSON output."""
    violations = []

    for v in drc_data.get("violations", []):
        violation = {
            "type": v.get("type", "unknown"),
            "severity": v.get("severity", "warning"),
            "description": v.get("description", ""),
            "items": [],
        }
        for item in v.get("items", []):
            violation["items"].append({
                "description": item.get("description", ""),
                "pos": item.get("pos", {}),
            })
        violations.append(violation)

    for v in drc_data.get("unconnected_items", []):
        violation = {
            "type": "unconnected_items",
            "severity": v.get("severity", "error"),
            "description": v.get("description", ""),
            "items": [],
        }
        for item in v.get("items", []):
            violation["items"].append({
                "description": item.get("description", ""),
                "pos": item.get("pos", {}),
            })
        violations.append(violation)

    return violations