"""Handler for BOM (Bill of Materials) generation from schematics."""

import sys
from pathlib import Path


def handle_generate_bom(kicad_info: dict, args: dict) -> dict:
    """Generate a BOM from a schematic file.

    Groups components by value + footprint, counts quantities,
    and returns a structured BOM.
    """
    sys.path.insert(0, str(Path(__file__).parent.parent))
    from parsers.schematic import parse_schematic

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

    sch_path = Path(file_path)
    if not sch_path.exists():
        return {
            "success": False,
            "error": f"Schematic 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.",
        }

    try:
        data = parse_schematic(sch_path)
    except Exception as e:
        return {"success": False, "error": f"Failed to parse schematic: {e}"}

    # Filter: only in_bom, non-power components
    power_uuids = {ps["uuid"] for ps in data["power_symbols"]}
    components = [
        c for c in data["components"]
        if c["in_bom"] and c["uuid"] not in power_uuids and not c["dnp"]
    ]

    # Group by value + footprint
    groups = {}
    for comp in components:
        key = (comp["value"], comp["footprint"])
        if key not in groups:
            groups[key] = {
                "value": comp["value"],
                "footprint": comp["footprint"],
                "references": [],
                "lib_id": comp["lib_id"],
                "description": comp["properties"].get("Description", ""),
                "manufacturer": comp["properties"].get("Manufacturer", ""),
                "mpn": comp["properties"].get("MPN", comp["properties"].get("Manufacturer_Part_Number", "")),
                "datasheet": comp["properties"].get("Datasheet", ""),
            }
        groups[key]["references"].append(comp["reference"])

    # Sort references naturally within each group
    bom = []
    for group in groups.values():
        group["references"].sort(key=_natural_sort_key)
        group["quantity"] = len(group["references"])
        group["reference_list"] = ", ".join(group["references"])
        bom.append(group)

    # Sort BOM by reference prefix then number
    bom.sort(key=lambda g: _natural_sort_key(g["references"][0] if g["references"] else ""))

    # DNP items (reported separately)
    dnp_items = [
        {"reference": c["reference"], "value": c["value"], "footprint": c["footprint"]}
        for c in data["components"]
        if c["dnp"] and c["uuid"] not in power_uuids
    ]

    total_unique = len(bom)
    total_parts = sum(g["quantity"] for g in bom)

    return {
        "success": True,
        "output": f"BOM: {total_unique} unique part(s), {total_parts} total",
        "data": {
            "bom": bom,
            "summary": {
                "unique_parts": total_unique,
                "total_parts": total_parts,
                "dnp_count": len(dnp_items),
            },
            "dnp_items": dnp_items,
        },
    }


def _natural_sort_key(s: str):
    """Sort key that handles mixed alpha-numeric strings naturally.

    E.g., R1, R2, R10 sort correctly instead of R1, R10, R2.
    """
    import re
    parts = re.split(r'(\d+)', s)
    return [int(p) if p.isdigit() else p.lower() for p in parts]
