"""Command-line interface for Impakt."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path


def main(argv: list[str] | None = None) -> None:
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="impakt",
        description="Impakt — Crash test data analysis, visualization, and reporting",
    )

    subparsers = parser.add_subparsers(dest="command", help="Available commands")

    # --- serve ---
    serve_parser = subparsers.add_parser("serve", help="Launch the web UI")
    serve_parser.add_argument("path", help="Path to test data directory")
    serve_parser.add_argument("--template", "-t", help="Template to apply")
    serve_parser.add_argument("--port", "-p", type=int, default=8050, help="Port (default: 8050)")
    serve_parser.add_argument("--debug", action="store_true", help="Enable debug mode")

    # --- info ---
    info_parser = subparsers.add_parser("info", help="Show test metadata")
    info_parser.add_argument("path", help="Path to test data directory")

    # --- channels ---
    ch_parser = subparsers.add_parser("channels", help="List channels")
    ch_parser.add_argument("path", help="Path to test data directory")
    ch_parser.add_argument("--pattern", "-p", help="Filter by pattern")
    ch_parser.add_argument("--tree", action="store_true", help="Show as tree")

    # --- evaluate ---
    eval_parser = subparsers.add_parser("evaluate", help="Run injury criteria evaluation")
    eval_parser.add_argument("path", help="Path to test data directory")
    eval_parser.add_argument(
        "--protocol", choices=["euro_ncap", "us_ncap", "iihs"], default="euro_ncap"
    )
    eval_parser.add_argument("--output", "-o", help="Output PDF path")

    # --- report ---
    report_parser = subparsers.add_parser("report", help="Generate a report")
    report_parser.add_argument("path", help="Path to test data directory")
    report_parser.add_argument("--template", "-t", help="Report template")
    report_parser.add_argument("--output", "-o", required=True, help="Output PDF path")

    args = parser.parse_args(argv)

    if args.command == "serve":
        _cmd_serve(args)
    elif args.command == "info":
        _cmd_info(args)
    elif args.command == "channels":
        _cmd_channels(args)
    elif args.command == "evaluate":
        _cmd_evaluate(args)
    elif args.command == "report":
        _cmd_report(args)
    else:
        parser.print_help()


def _cmd_serve(args: argparse.Namespace) -> None:
    from impakt.script.api import Session
    from impakt.web.app import create_app

    session = Session.open(args.path)
    if args.template:
        session.apply_template(args.template)

    app = create_app(session)
    print(f"Impakt web UI running at http://localhost:{args.port}")
    app.run(debug=args.debug, port=args.port)


def _cmd_info(args: argparse.Namespace) -> None:
    from impakt.script.api import Session

    session = Session.open(args.path)
    m = session.metadata

    print(f"Test: {m.test_number}")
    if m.test_date:
        print(f"Date: {m.test_date}")
    if m.test_facility:
        print(f"Facility: {m.test_facility}")
    if m.vehicle.make:
        print(f"Vehicle: {m.vehicle.year} {m.vehicle.make} {m.vehicle.model}")
    if m.dummy.dummy_type:
        print(f"Dummy: {m.dummy.dummy_type} ({m.dummy.position})")
    if m.impact.test_type:
        print(f"Impact: {m.impact.test_type} @ {m.impact.speed_kmh} km/h")
    print(f"Channels: {len(session)}")
    print(f"Groups: {len(session.groups())}")


def _cmd_channels(args: argparse.Namespace) -> None:
    from impakt.script.api import Session

    session = Session.open(args.path)

    if args.tree:
        tree = session.channel_tree()
        for obj, locations in sorted(tree.items()):
            print(f"\n{obj}")
            for loc, measurements in sorted(locations.items()):
                print(f"  {loc}")
                for meas, channels in sorted(measurements.items()):
                    print(f"    {meas}")
                    for ch in channels:
                        print(f"      {ch.name}  ({ch.unit}, {ch.n_samples} pts)")
    else:
        channels = session.find(args.pattern) if args.pattern else list(session.data)
        for ch in sorted(channels, key=lambda c: c.name):
            desc = ch.code.description if ch.code.is_valid else ch.name
            print(f"  {ch.name:<20} {desc:<50} {ch.unit:<10} {ch.n_samples} pts")


def _cmd_evaluate(args: argparse.Namespace) -> None:
    from impakt.script.api import Session
    from impakt.criteria import hic, clip_3ms, nij, chest_deflection, femur_load

    session = Session.open(args.path)

    # Auto-detect channels and compute criteria
    # (This is a simplified version — a real implementation would use
    #  the template system to know which channels to use)
    print(f"Evaluating {session.test_id} with {args.protocol}...")
    print("(Full auto-detection not yet implemented — use the scripting API)")


def _cmd_report(args: argparse.Namespace) -> None:
    print("Report generation not yet available via CLI. Use the scripting API.")


if __name__ == "__main__":
    main()
