#!/usr/bin/env python3
"""
step_processor.py — CLI entry point for the STEP File Processor skill.

Default run: thumbnails + BOM + auto-translate if Chinese labels detected.

Usage:
  python step_processor.py <file.step> [options]

See SKILL.md or --help for full option reference.
"""
import argparse
import logging
import sys
from pathlib import Path


def _setup_logging(verbose: bool):
    level = logging.DEBUG if verbose else logging.INFO
    fmt = "%(levelname)-5s %(name)s: %(message)s" if verbose else "%(levelname)-5s %(message)s"
    logging.basicConfig(level=level, format=fmt, stream=sys.stdout)


def _parse_args():
    p = argparse.ArgumentParser(
        description="STEP File Processor — thumbnails, BOM, translation, geometry queries",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=__doc__,
    )
    p.add_argument("step_file", help="Path to .step or .stp file")

    # Output control
    p.add_argument("--no-thumbnails", dest="thumbnails", action="store_false", default=True,
                   help="Skip PNG thumbnail generation")
    p.add_argument("--no-bom", dest="bom", action="store_false", default=True,
                   help="Skip BOM CSV export")
    p.add_argument("--translate", dest="translate", action="store_true", default=None,
                   help="Force translation even if auto-detect is off")
    p.add_argument("--no-translate", dest="translate", action="store_false",
                   help="Skip translation even if Chinese labels are detected")

    # Thumbnail options
    p.add_argument("--resolution", default="1024x768",
                   help="Thumbnail resolution WxH (default: 1024x768)")
    p.add_argument("--views", default=None,
                   help="Comma-separated views: front,bottom,left,right,iso_left,iso_right")

    # Query modes
    p.add_argument("--query", default=None, metavar="QUERY",
                   help='Run a single geometric query and exit, e.g. "list all holes"')
    p.add_argument("--repl", action="store_true",
                   help="Launch interactive geometry query REPL")

    # Diagram
    p.add_argument("--diagram", action="store_true",
                   help="Generate external dimensional diagram")
    p.add_argument("--diagram-mode",
                   choices=["enclosure_only", "enclosure_plus_mounting", "mounting_only"],
                   default="enclosure_only",
                   help="Diagram mode (default: enclosure_only)")
    p.add_argument("--diagram-style", choices=["line_drawing", "rendered"], default=None,
                   help="Diagram style (auto-selected if omitted)")
    p.add_argument("--diagram-pdf", action="store_true",
                   help="Also export diagram as PDF")
    p.add_argument("--diagram-variants", action="store_true",
                   help="Render one diagram per mounting variant")
    p.add_argument("--mapping", default=None, metavar="JSON_FILE",
                   help="Parts mapping JSON file for diagram mode")
    p.add_argument("--datablock", default=None, metavar="MD_FILE",
                   help="Datablock .md file for diagram title block")

    # Misc
    p.add_argument("--verbose", "-v", action="store_true",
                   help="Show backend selection, fallback notices, timing")

    return p.parse_args()


def main():
    args = _parse_args()
    _setup_logging(args.verbose)
    log = logging.getLogger("step_processor")

    step_path = Path(args.step_file).expanduser().resolve()
    if not step_path.exists():
        log.error(f"File not found: {step_path}")
        sys.exit(1)
    if step_path.suffix.lower() not in (".step", ".stp"):
        log.warning(f"Unexpected extension '{step_path.suffix}' — continuing anyway")

    # ── Load ─────────────────────────────────────────────────────────────────
    log.info(f"Loading: {step_path.name}")
    from modules.loader import load_step
    model = load_step(step_path)
    if model is None:
        log.error("Failed to load STEP file. Check that build123d or FreeCAD is installed.")
        log.error("See INSTALL.md for setup instructions.")
        sys.exit(1)
    log.info(f"[{model.backend}] Loaded: {step_path.name}")

    # ── Query mode (single) ──────────────────────────────────────────────────
    if args.query:
        from modules.query_engine import run_query
        result = run_query(model, args.query)
        print(result)
        return

    # ── REPL mode ────────────────────────────────────────────────────────────
    if args.repl:
        from modules.query_engine import repl
        repl(model, step_path)
        return

    # ── BOM ──────────────────────────────────────────────────────────────────
    bom_df = None
    if args.bom:
        from modules.bom import extract_bom, save_bom_xlsx
        bom_df = extract_bom(model)
        xlsx_path = save_bom_xlsx(bom_df, step_path)
        log.info(f"BOM XLSX → {xlsx_path}")

    # ── Translation ──────────────────────────────────────────────────────────
    if bom_df is not None:
        from modules.translator import has_chinese, translate_bom, get_translation_map
        needs_translation = args.translate
        if needs_translation is None:
            # Auto-detect
            needs_translation = bom_df["part_name_original"].apply(has_chinese).any()
            if needs_translation:
                log.info("Chinese part names detected — auto-translating")

        if needs_translation:
            import os
            if not os.environ.get("ANTHROPIC_API_KEY"):
                log.warning("ANTHROPIC_API_KEY not set — skipping translation")
            else:
                bom_df = translate_bom(bom_df, model_name=step_path.stem)
                from modules.bom import save_bom_xlsx
                save_bom_xlsx(bom_df, step_path)  # overwrite with translated version
                translation_map = get_translation_map(bom_df)
                if translation_map:
                    from modules.rewriter import rewrite_step
                    rewrite_step(step_path, translation_map)

    # ── Thumbnails ───────────────────────────────────────────────────────────
    if args.thumbnails:
        try:
            w, h = (int(x) for x in args.resolution.split("x"))
        except ValueError:
            log.warning(f"Invalid resolution '{args.resolution}' — using 1024x768")
            w, h = 1024, 768
        views = [v.strip() for v in args.views.split(",")] if args.views else None
        from modules.renderer import render_views
        thumb_results = render_views(model, step_path, views=views, width=w, height=h)
        if thumb_results:
            log.info(f"Thumbnails: {len(thumb_results)} PNG(s) written")
        else:
            log.warning("No thumbnails generated (pyrender unavailable or mesh failed)")

    # ── External dimensional diagram ─────────────────────────────────────────
    if args.diagram:
        from modules.external_diagram import step_external_diagram
        options = {
            "pdf": args.diagram_pdf,
            "render_variants": args.diagram_variants,
        }
        if args.diagram_style:
            options["style"] = args.diagram_style
        meta = step_external_diagram(
            path=str(step_path),
            mode=args.diagram_mode,
            mapping_file=args.mapping,
            datablock_file=args.datablock,
            options=options,
        )
        if meta:
            log.info(f"Diagram → {step_path.stem}__external-diagram.svg")
            if args.diagram_pdf:
                log.info(f"Diagram PDF → {step_path.stem}__external-diagram.pdf")

    # ── Summary ──────────────────────────────────────────────────────────────
    log.info("Done.")
    _print_summary(step_path, model, bom_df, args)


def _print_summary(step_path: Path, model, bom_df, args):
    print(f"\n{'─'*60}")
    print(f"  {step_path.name}  [{model.backend}]")
    if bom_df is not None:
        print(f"  BOM: {len(bom_df)} parts → {step_path.stem}_bom.xlsx")
    en_path = step_path.parent / f"{step_path.stem}_EN.step"
    if en_path.exists():
        print(f"  Translated STEP → {en_path.name}")
    if args.thumbnails:
        thumb_count = sum(1 for ext in ["_front.png", "_rear.png", "_left.png",
                                         "_right.png", "_iso_left.png", "_iso_right.png"]
                          if (step_path.parent / f"{step_path.stem}{ext}").exists())
        print(f"  Thumbnails: {thumb_count} PNG(s)")
    if args.diagram:
        diag = step_path.parent / f"{step_path.stem}__external-diagram.svg"
        if diag.exists():
            print(f"  Diagram → {diag.name}")
    print(f"{'─'*60}\n")


if __name__ == "__main__":
    main()
