"""bggpipe — shelf photos to BoardGameGeek collection, in six stages."""

from __future__ import annotations

from pathlib import Path
from typing import Annotated

import typer

from bggpipe.config import DEFAULT_REVIEW_PORT, load_config

app = typer.Typer(
    help="Shelf-to-BGG collection pipeline.",
    no_args_is_help=True,
)

ConfigOpt = Annotated[
    Path | None,
    typer.Option("--config", help="Path to config.toml (default: ./config.toml)"),
]


@app.command()
def init(config: ConfigOpt = None) -> None:
    """Guided first-run setup: folders, config, credentials, browser."""
    from bggpipe.init_wizard import run_init

    cfg = load_config(config)
    run_init(cfg)


@app.command()
def extract(
    only: Annotated[
        str | None, typer.Option("--only", help="Re-run a single photo")
    ] = None,
    force: Annotated[
        bool, typer.Option("--force", help="Re-extract every photo (ignore cache)")
    ] = False,
    config: ConfigOpt = None,
) -> None:
    """Stage 1: extract game titles + edition cues from shelf photos."""
    from bggpipe.extract import run_extract

    cfg = load_config(config)
    run_extract(cfg, only=only, force=force)


@app.command()
def resolve(
    force: Annotated[
        bool, typer.Option("--force", help="Re-resolve titles already in matches.csv")
    ] = False,
    config: ConfigOpt = None,
) -> None:
    """Stage 2: match extracted titles to BGG IDs and versions."""
    from bggpipe.resolve import run_resolve

    cfg = load_config(config)
    run_resolve(cfg, force=force)


@app.command()
def review(
    web: Annotated[
        bool, typer.Option("--web", help="Serve the review UI on localhost")
    ] = False,
    port: Annotated[
        int, typer.Option("--port", help="Port for --web")
    ] = DEFAULT_REVIEW_PORT,
    dev: Annotated[
        bool, typer.Option("--dev", help="With --web: restart on source changes")
    ] = False,
    config: ConfigOpt = None,
) -> None:
    """Stage 3: human review of ambiguous/unmatched items."""
    cfg = load_config(config)
    if web:
        from bggpipe.webreview import run_web_review

        run_web_review(cfg, port=port, dev=dev, config_path=config)
    else:
        from bggpipe.review import run_review

        run_review(cfg)


@app.command()
def web(
    port: Annotated[
        int, typer.Option("--port", help="Port to serve on")
    ] = DEFAULT_REVIEW_PORT,
    dev: Annotated[
        bool, typer.Option("--dev", help="Restart on source changes")
    ] = False,
    no_browser: Annotated[
        bool, typer.Option("--no-browser", help="Don't open a browser tab")
    ] = False,
    lan: Annotated[
        bool,
        typer.Option(
            "--lan",
            help="Also serve to your local network behind a per-run access "
            "key (trusted networks only)",
        ),
    ] = False,
    config: ConfigOpt = None,
) -> None:
    """The whole pipeline in a local web UI: photos, stages, review."""
    from bggpipe.webreview import run_web_review

    cfg = load_config(config)
    run_web_review(
        cfg,
        port=port,
        dev=dev,
        lan=lan,
        config_path=config,
        landing="/",
        open_browser=not no_browser,
    )


@app.command()
def diff(config: ConfigOpt = None) -> None:
    """Stage 4: diff approved matches against the existing BGG collection."""
    from bggpipe.diff import run_diff

    cfg = load_config(config)
    run_diff(cfg)


@app.command()
def upload(
    dry_run: Annotated[
        bool, typer.Option("--dry-run", help="Show the queue without a browser")
    ] = False,
    verify: Annotated[
        bool, typer.Option("--verify", help="Re-fetch the collection and cross-check")
    ] = False,
    retry_failed: Annotated[
        bool, typer.Option("--retry-failed", help="Re-attempt previously failed games")
    ] = False,
    limit: Annotated[
        int | None, typer.Option("--limit", help="Upload at most N games this run")
    ] = None,
    headless: Annotated[
        bool,
        typer.Option(
            "--headless",
            help="Run the browser headless (Cloudflare may block login)",
        ),
    ] = False,
    config: ConfigOpt = None,
) -> None:
    """Stage 5: add games to the BGG collection via Playwright."""
    from bggpipe.upload import run_upload

    cfg = load_config(config)
    run_upload(
        cfg,
        dry_run=dry_run,
        verify=verify,
        retry_failed=retry_failed,
        limit=limit,
        headless=headless,
    )


@app.command()
def enrich(
    refresh: Annotated[
        bool,
        typer.Option("--refresh", help="Re-fetch metadata (ranks/ratings drift)"),
    ] = False,
    config: ConfigOpt = None,
) -> None:
    """Stage 6: fetch full game + version metadata into games.json."""
    from bggpipe.enrich import run_enrich

    cfg = load_config(config)
    run_enrich(cfg, refresh=refresh)
