"""CLI command: asa stabilize — hero command orchestrating the full stabilization flow.

Flow:
  Step 1: Scan → ACI score
  Step 2: Spec Infer → draft .asa/spec.yaml
  Step 3: Plan → dry-run
  Step 4: Apply → install foundation
  Step 5: Bridge (upgrade mode) → repair suggestions
  Step 6: Verify → architecture check
"""

from pathlib import Path

import typer

from ..core import logging as log
from ..core.paths import find_project_root


def stabilize(
    dry_run: bool = typer.Option(False, "--dry-run", help="Run only steps 1-3 (scan, infer, plan). Nothing is written."),
    skip_bridge: bool = typer.Option(False, "--skip-bridge", help="Skip bridge/repair step (step 5)"),
    yes: bool = typer.Option(False, "--yes", "-y", help="Non-interactive mode — skip confirmations"),
) -> None:
    """Orchestrate full architecture stabilization: scan → infer → plan → apply → bridge → verify.

    This is the hero command for upgrading an existing chaos app to
    ASA architecture. Each step pauses for confirmation unless --yes is used.
    """
    project_root = find_project_root()

    log.header("ASA Stabilize — Architecture Stabilization Engine")
    log.info(f"Project: {project_root}")
    print()

    # --- Step 1: Scan ---
    log.header("Step 1/6: Scan")
    _step_scan(project_root)

    if not yes:
        if not typer.confirm("Continue to spec inference?", default=True):
            raise typer.Exit(code=0)

    # --- Step 2: Spec Infer ---
    log.header("Step 2/6: Spec Infer")
    spec = _step_spec_infer(project_root)

    if not yes:
        log.info(f"Review .asa/spec.yaml and edit if needed.")
        if not typer.confirm("Spec looks good? Continue to plan?", default=True):
            raise typer.Exit(code=0)

    # --- Step 3: Plan ---
    log.header("Step 3/6: Plan")
    _step_plan(project_root)

    if dry_run:
        log.info("Dry-run complete. No files were modified.")
        raise typer.Exit(code=0)

    if not yes:
        if not typer.confirm("Apply these changes?", default=True):
            raise typer.Exit(code=0)

    # --- Step 4: Apply ---
    log.header("Step 4/6: Apply")
    _step_apply(project_root)

    # --- Step 5: Bridge ---
    if not skip_bridge:
        log.header("Step 5/6: Bridge / Repair")
        _step_repair(project_root)
    else:
        log.info("Step 5/6: Bridge — skipped (--skip-bridge)")

    # --- Step 6: Verify ---
    log.header("Step 6/6: Verify")
    exit_code = _step_verify(project_root)

    print()
    if exit_code == 0:
        log.success("Stabilization complete — architecture verified.")
        log.info("Next steps:")
        log.detail("1. Review any remaining bridge suggestions")
        log.detail("2. Create your first business slice: asa slice new {domain}/{slice}")
        log.detail("3. Set up CI: add 'asa verify --ci' to your GitHub Actions")
    else:
        log.warning("Stabilization partially complete — some manual items remain.")
        log.info("Run 'asa repair --review' to see remaining items.")

    raise typer.Exit(code=exit_code)


def _step_scan(project_root: Path) -> None:
    """Run asa scan."""
    from ..engine.scanner.scanner import RepoScanner

    scanner = RepoScanner()
    result = scanner.scan(project_root)
    aci = round(result.aci)
    log.info(f"AI Chaos Index: {aci}/100 ({result.band.value})")

    if aci > 60:
        log.warning(f"High chaos score ({aci}). Stabilization recommended.")
    elif aci > 30:
        log.info(f"Moderate chaos score ({aci}). Foundation will help.")
    else:
        log.success(f"Low chaos score ({aci}). Architecture is in decent shape.")


def _step_spec_infer(project_root: Path):
    """Run spec inference and return parsed spec."""
    from ..engine.spec.inferrer import infer_spec
    from ..engine.spec.parser import spec_to_yaml
    from ..core.fs import safe_write_file

    spec_path = project_root / ".asa" / "spec.yaml"

    spec = infer_spec(project_root)

    # Write draft spec
    header = """# ASA Architecture Spec v0.1 — DRAFT (auto-inferred by asa stabilize)
# ⚠️  Review and edit before proceeding.

"""
    yaml_content = header + spec_to_yaml(spec)
    safe_write_file(spec_path, yaml_content, overwrite=True)
    log.success(f"Draft spec written to: {spec_path}")

    return spec


def _step_plan(project_root: Path) -> None:
    """Run asa plan (dry-run)."""
    from ..engine.spec.parser import load_spec
    from ..engine.applier.planner import generate_plan, print_plan

    spec = load_spec(project_root)
    if spec is None:
        log.error("No spec found — inference may have failed.")
        return
    plan_data = generate_plan(project_root, spec)
    print_plan(plan_data)


def _step_apply(project_root: Path) -> None:
    """Run asa apply."""
    from ..engine.spec.parser import load_spec
    from ..engine.applier.applier import apply_foundation

    spec = load_spec(project_root)
    if spec is None:
        log.error("No spec found — cannot apply.")
        return
    errors = apply_foundation(project_root, spec)
    if errors > 0:
        log.warning(f"Apply had {errors} errors — continuing with remaining steps.")


def _step_repair(project_root: Path) -> None:
    """Run asa repair --review."""
    from ..engine.spec.parser import load_spec
    from ..engine.repairer.repairer import detect_all_issues, repair_issues

    spec = load_spec(project_root)
    if spec is None:
        return
    errors, warnings = detect_all_issues(project_root, spec)
    all_issues = errors + warnings
    if not all_issues:
        log.success("No drift detected.")
        return
    log.info(f"Found {len(all_issues)} issues ({len(errors)} errors, {len(warnings)} warnings)")
    manual_items = repair_issues(project_root, spec, errors, warnings, auto=False)
    if manual_items:
        log.warning(f"{len(manual_items)} items require manual intervention")


def _step_verify(project_root: Path) -> int:
    """Run asa verify and return exit code."""
    from ..engine.spec.parser import load_spec
    from ..engine.verifier.verifier import verify_project

    spec = load_spec(project_root)
    if spec is None:
        log.error("Cannot verify — spec not found after apply.")
        return 2

    return verify_project(project_root, spec)
