"""Single-point electromagnetic simulation verification script.

Loads the MARS SSSR baseline model, runs one magnetic calculation
with the model's default operating point, and extracts Phase 1 core
metrics: average torque, torque ripple (%), system efficiency,
total losses.

Usage:
    python scripts/run_single.py
    python scripts/run_single.py --model models/MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot
    python scripts/run_single.py --quit  (close Motor-CAD after run)

All source is ASCII.
"""

from __future__ import annotations

import argparse
import json
import os
import sys
import time
from datetime import datetime
from pathlib import Path

# Add project root to sys.path so we can import src.solver_core.
PROJECT_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from src.solver_core import (  # noqa: E402
    MotorCADSolver,
    METRIC_LABELS,
    REQUIRED_METRICS,
)

DEFAULT_MODEL = PROJECT_ROOT / "models" / "MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot"
DEFAULT_OUTPUT = PROJECT_ROOT / "output"


def _log(text: str) -> None:
    stamp = datetime.now().strftime("%H:%M:%S")
    print(f"[{stamp}] {text}", flush=True)


def main() -> int:
    parser = argparse.ArgumentParser(description="Single-point Motor-CAD simulation")
    parser.add_argument("--model", type=str, default=str(DEFAULT_MODEL),
                        help="Path to .mot model file")
    parser.add_argument("--output-dir", type=str, default=str(DEFAULT_OUTPUT),
                        help="Directory for raw export and result JSON")
    parser.add_argument("--quit", action="store_true",
                        help="Close Motor-CAD after simulation (default: keep open)")
    args = parser.parse_args()

    model_path = Path(args.model)
    if not model_path.exists():
        print(f"ERROR: Model file not found: {model_path}")
        return 1

    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    _log("=" * 60)
    _log("PCB Axial Flux Motor - Single Point Simulation")
    _log("=" * 60)
    _log(f"Model: {model_path.name}")
    _log(f"Output: {output_dir}")
    _log("")

    solver = MotorCADSolver(log_cb=_log)
    result = {}

    try:
        solver.connect()
        _log("")
        _log("Running single-point simulation (model default operating point)...")
        _log("")

        result = solver.run_single(
            model_path=model_path,
            params=None,  # use model default operating point
            output_dir=output_dir,
            tag="single",
        )

        _log("")
        _log("=" * 60)
        _log("RESULTS")
        _log("=" * 60)
        _log(f"Status: {result['status']}")
        _log(f"Solve time: {result['solve_time_s']}s")
        if result.get("error"):
            _log(f"Error: {result['error']}")
        _log("")

        metrics = result.get("metrics", {})

        # Print Phase 1 required metrics first.
        _log("--- Phase 1 Core Metrics ---")
        for key in REQUIRED_METRICS:
            label = METRIC_LABELS.get(key, key)
            value = metrics.get(key, "N/A")
            if isinstance(value, float):
                _log(f"  {label}: {value:.4f}")
            else:
                _log(f"  {label}: {value}")
        _log("")

        # Print all other extracted metrics.
        other = {k: v for k, v in metrics.items() if k not in REQUIRED_METRICS}
        if other:
            _log("--- Additional Metrics ---")
            for key, value in other.items():
                label = METRIC_LABELS.get(key, key)
                if isinstance(value, float):
                    _log(f"  {label}: {value:.4f}")
                else:
                    _log(f"  {label}: {value}")
            _log("")

        # Save result JSON.
        ts = datetime.now().strftime("%Y%m%d_%H%M%S")
        result_path = output_dir / f"single_result_{ts}.json"
        with open(result_path, "w", encoding="utf-8") as f:
            json.dump(result, f, indent=2, ensure_ascii=False)
        _log(f"Result saved: {result_path}")

        if result["status"] == "OK":
            _log("")
            _log("SUCCESS: All Phase 1 required metrics extracted.")
        elif result["status"] == "UNCERTAIN":
            _log("")
            _log("WARNING: Some required metrics missing - check raw export.")
        else:
            _log("")
            _log("FAILED: Simulation or extraction failed.")

    except KeyboardInterrupt:
        _log("Interrupted by user.")
    except Exception as exc:
        _log(f"FATAL: {type(exc).__name__}: {exc}")
        import traceback
        _log(traceback.format_exc())
        return 1
    finally:
        if args.quit:
            solver.disconnect()
        else:
            _log("")
            _log("Motor-CAD kept open for manual inspection.")
            _log("Use --quit flag to auto-close.")

    _log("")
    _log("Done.")
    return 0 if result.get("status") in ("OK", "UNCERTAIN") else 1


if __name__ == "__main__":
    sys.exit(main())
