"""ASA CLI v2 — main entrypoint.

Usage: asa <command> [options]
"""

import typer

from .. import __version__

app = typer.Typer(
    name="asa",
    help="ASA CLI — Architecture Stabilization Engine for AI-built apps.",
    no_args_is_help=True,
)

# Slice subcommand group
slice_app = typer.Typer(
    name="slice",
    help="Slice management commands.",
    no_args_is_help=True,
)
app.add_typer(slice_app, name="slice")

# Spec subcommand group
spec_app = typer.Typer(
    name="spec",
    help="Architecture spec commands.",
    no_args_is_help=True,
)
app.add_typer(spec_app, name="spec")

# UI subcommand group
ui_app = typer.Typer(
    name="ui",
    help="UI generation commands. [Advanced]",
    no_args_is_help=True,
)
app.add_typer(ui_app, name="ui")


@app.command("init")
def init_cmd(
    name: str = typer.Option(None, "--name", "-n", help="Project name"),
) -> None:
    """Initialize a new ASA project (runnable Next.js App Router starter)."""
    from .init_cmd import run_init
    run_init(name)


@app.command("scan")
def scan_cmd(
    path: str = typer.Argument(".", help="Path to project root"),
    json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
    no_url: bool = typer.Option(False, "--no-url", help="Skip web bridge URL"),
) -> None:
    """Scan repository for structural risk — AI Chaos Index diagnostic."""
    from .scan import run_scan
    run_scan(path, json_output=json_output, no_url=no_url)


@app.command("install")
def install_cmd(
    module_name: str = typer.Argument(..., help="Module to install (e.g., auth-basic)"),
) -> None:
    """Install an ASA foundation module."""
    from .install import run_install
    run_install(module_name)


@app.command("lint")
def lint_cmd(
    target: str = typer.Argument(None, help="Slice to lint (e.g., invoices/create). Omit for whole project."),
    strict: bool = typer.Option(False, "--strict", help="Strict mode (warnings become errors)"),
) -> None:
    """Lint project for boundary violations, contract integrity, and security."""
    from .lint import run_lint
    run_lint(target, strict=strict)


@app.command("stabilize")
def stabilize_cmd(
    dry_run: bool = typer.Option(False, "--dry-run", help="Run only scan + infer + plan. Nothing is written."),
    skip_bridge: bool = typer.Option(False, "--skip-bridge", help="Skip bridge/repair step"),
    yes: bool = typer.Option(False, "--yes", "-y", help="Non-interactive mode"),
) -> None:
    """Full stabilization flow: scan → infer → plan → apply → bridge → verify."""
    from .stabilize import stabilize
    stabilize(dry_run=dry_run, skip_bridge=skip_bridge, yes=yes)


@app.command("plan")
def plan_cmd() -> None:
    """Dry-run — show what 'asa apply' would do."""
    from .plan_cmd import plan
    plan()


@app.command("apply")
def apply_cmd(
    force: bool = typer.Option(False, "--force", help="Force overwrite existing files"),
) -> None:
    """Apply foundation architecture from .asa/spec.yaml."""
    from .apply import apply
    apply(force=force)


@app.command("verify")
def verify_cmd(
    ci: bool = typer.Option(False, "--ci", help="CI mode: JSON output, strict exit codes"),
) -> None:
    """Verify project architecture against .asa/spec.yaml."""
    from .verify import verify
    verify(ci=ci)


@app.command("repair")
def repair_cmd(
    auto: bool = typer.Option(False, "--auto", help="Auto-apply safe fixes"),
    review: bool = typer.Option(True, "--review/--no-review", help="Show suggestions for manual review"),
) -> None:
    """Detect architecture drift and propose fixes."""
    from .repair import repair
    repair(auto=auto, review=review)


@spec_app.command("infer")
def spec_infer_cmd(
    path: str = typer.Argument(".", help="Path to project root"),
    force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing spec.yaml"),
) -> None:
    """Generate draft .asa/spec.yaml from existing repository."""
    from .spec.infer import spec_infer
    spec_infer(path=path, force=force)


@app.command("deploy")
def deploy_cmd(
    check: bool = typer.Option(False, "--check", help="Check only, do not deploy"),
    staging: bool = typer.Option(False, "--staging", help="Deploy to Vercel preview"),
    prod: bool = typer.Option(False, "--prod", help="Deploy to production (v1.1)"),
    verbose: bool = typer.Option(False, "--verbose", help="Verbose output"),
) -> None:
    """Architecture-safe deployment (Vercel + Supabase)."""
    from .deploy import run_deploy
    run_deploy(check=check, staging=staging, prod=prod, verbose=verbose)


# --- Slice subcommands ---

@slice_app.command("new")
def slice_new_cmd(
    domain_slice: str = typer.Argument(..., help="Slice identifier (e.g., invoices/create)"),
    slice_type: str = typer.Option("route", "--type", "-t", help="Slice type: route, webhook, internal-service"),
    no_ui: bool = typer.Option(False, "--no-ui", help="Skip UI generation"),
    no_repo: bool = typer.Option(False, "--no-repo", help="Skip repository generation"),
) -> None:
    """Create a new vertical slice (FE + BE + contract)."""
    from .slice.new import run_slice_new
    run_slice_new(domain_slice, slice_type=slice_type, no_ui=no_ui, no_repo=no_repo)


@slice_app.command("update")
def slice_update_cmd(
    domain_slice: str = typer.Argument(..., help="Slice identifier (e.g., invoices/create)"),
) -> None:
    """Regenerate slice after spec/contract change (preserves user code)."""
    from .slice.update import run_slice_update
    run_slice_update(domain_slice)


@slice_app.command("plan")
def slice_plan_cmd(
    spec_file: str = typer.Argument(..., help="Path to functional spec file"),
) -> None:
    """Propose slice architecture from functional specification."""
    from .slice.plan import run_slice_plan
    run_slice_plan(spec_file)


@slice_app.command("split")
def slice_split_cmd(
    domain_slice: str = typer.Argument(..., help="Slice identifier to analyze"),
) -> None:
    """Analyze oversized slice and propose split."""
    from .slice.split import run_slice_split
    run_slice_split(domain_slice)


@slice_app.command("build")
def slice_build_cmd(
    domain_slice: str = typer.Argument(..., help="Slice identifier"),
) -> None:
    """Run internal build pipeline (contract → zod → skeleton). [Advanced]"""
    from .slice.build import run_slice_build
    run_slice_build(domain_slice)


@slice_app.command("sync")
def slice_sync_cmd() -> None:
    """Validate and synchronize all contracts. [Advanced]"""
    from .slice.sync import run_slice_sync
    run_slice_sync()


@slice_app.command("analyze")
def slice_analyze_cmd(
    domain_slice: str = typer.Argument(..., help="Slice identifier"),
) -> None:
    """Detailed slice analysis (LOC, imports, coupling). [Advanced]"""
    from .slice.analyze import run_slice_analyze
    run_slice_analyze(domain_slice)


@ui_app.command("generate")
def ui_generate_cmd(
    domain_slice: str = typer.Argument(..., help="Slice identifier (e.g., invoices/create)"),
) -> None:
    """Regenerate frontend part of a slice (hook + component). [Advanced]"""
    from .ui.generate import run_ui_generate
    run_ui_generate(domain_slice)


@app.callback(invoke_without_command=True)
def version_callback(
    version: bool = typer.Option(False, "--version", "-v", help="Show version", is_eager=True),
) -> None:
    if version:
        typer.echo(f"asa {__version__}")
        raise typer.Exit()


def main() -> None:
    """CLI entrypoint."""
    app()


if __name__ == "__main__":
    main()
