"""Typer CLI entrypoint for Luca Assistant."""

from __future__ import annotations

import typer
from rich.console import Console

from luca_assistant.db import init_db
from luca_assistant.db.engine import get_session
from luca_assistant.db.seed import seed_all

app = typer.Typer(name="luca", help="Luca - Credit card optimization assistant (撸卡助手)")

console = Console()


@app.command()
def init() -> None:
    """Initialize database and seed with card data."""
    _ensure_db()
    console.print("[green]Database initialized and seeded successfully.[/green]")


@app.command()
def cards(bank: str | None = typer.Option(None, help="Filter by bank")) -> None:
    """List all cards in the database."""
    _ensure_db()
    from luca_assistant.db.models import Card

    session = get_session()
    try:
        q = session.query(Card).filter(Card.is_active.is_(True)).order_by(Card.bank, Card.name)
        if bank:
            q = q.filter(Card.bank.ilike(f"%{bank}%"))
        cards_list = q.all()

        if not cards_list:
            console.print("[yellow]No cards found.[/yellow]")
            return

        from rich.table import Table

        table = Table(title="Credit Cards")
        table.add_column("Bank", style="cyan")
        table.add_column("Name", style="white")
        table.add_column("Network")
        table.add_column("Annual Fee", justify="right")
        table.add_column("Business", justify="center")

        for card in cards_list:
            table.add_row(
                card.bank,
                card.name,
                card.network,
                f"${card.annual_fee}",
                "Y" if card.is_business else "",
            )

        console.print(table)
    finally:
        session.close()


@app.command(name="import")
def import_data(
    source: str = typer.Option(
        "offer-optimist", help="Data source (offer-optimist, cfpb)"
    ),
    force: bool = typer.Option(False, "--force", "-f", help="Re-download even if cached"),
    status: bool = typer.Option(False, "--status", "-s", help="Show import status only"),
) -> None:
    """Import card data from external sources."""
    _ensure_db()

    if source == "offer-optimist":
        from luca_assistant.db.importers import OfferOptimistImporter

        importer = OfferOptimistImporter()

        if status:
            cache = importer.get_cache_path()
            if cache.exists():
                import time

                age_hours = (time.time() - cache.stat().st_mtime) / 3600
                console.print(
                    f"[cyan]offer-optimist[/cyan]: cached at {cache} ({age_hours:.1f}h old)"
                )
            else:
                console.print("[yellow]offer-optimist: no cached data[/yellow]")

            from luca_assistant.db.models import Card

            session = get_session()
            try:
                count = session.query(Card).count()
                console.print(f"  Cards in database: {count}")
            finally:
                session.close()
            return

        try:
            with console.status("Downloading Offer Optimist YAML..."):
                path = importer.download(force=force)

            with console.status("Parsing YAML..."):
                data = importer.parse(path)

            session = get_session()
            try:
                with console.status("Importing cards..."):
                    result = importer.import_cards(session, data)
                    session.commit()

                console.print("[green]Import complete:[/green]")
                console.print(f"  Cards created: {result.cards_created}")
                console.print(f"  Cards updated: {result.cards_updated}")
                console.print(f"  Offers created: {result.offers_created}")
                console.print(f"  Benefits created: {result.benefits_created}")
                console.print(f"  Skipped (discontinued): {result.skipped_discontinued}")
                if result.errors:
                    console.print(f"  [yellow]Errors: {len(result.errors)}[/yellow]")
                    for err in result.errors[:5]:
                        console.print(f"    {err}")
            finally:
                session.close()

        except Exception as e:
            console.print(f"[red]Import failed: {e}[/red]")
            raise typer.Exit(1)
    elif source == "cfpb":
        from luca_assistant.db.importers import CFPBImporter

        cfpb = CFPBImporter()

        if status:
            cache = cfpb.get_cache_path()
            if cache.exists():
                import time

                age_hours = (time.time() - cache.stat().st_mtime) / 3600
                console.print(f"[cyan]cfpb[/cyan]: cached at {cache} ({age_hours:.1f}h old)")
            else:
                console.print("[yellow]cfpb: no cached data[/yellow]")
            return

        try:
            with console.status("Downloading CFPB TCCP XLSX..."):
                path = cfpb.download(force=force)

            with console.status("Parsing XLSX..."):
                data = cfpb.parse(path)

            session = get_session()
            try:
                with console.status("Enriching cards with CFPB data..."):
                    result = cfpb.import_cards(session, data)
                    session.commit()

                console.print("[green]CFPB import complete:[/green]")
                console.print(f"  Total CFPB rows: {result.total_rows}")
                console.print(f"  Cards enriched: {result.cards_enriched}")
                console.print(f"  Not matched: {result.cards_not_matched}")
                if result.errors:
                    console.print(f"  [yellow]Errors: {len(result.errors)}[/yellow]")
                    for err in result.errors[:5]:
                        console.print(f"    {err}")
            finally:
                session.close()

        except Exception as e:
            console.print(f"[red]CFPB import failed: {e}[/red]")
            raise typer.Exit(1)
    else:
        console.print(f"[red]Unknown source: {source}. Available: offer-optimist, cfpb[/red]")
        raise typer.Exit(1)


def _ensure_db() -> None:
    """Initialize DB and seed if needed."""
    init_db()
    session = get_session()
    try:
        seed_all(session)
    finally:
        session.close()


if __name__ == "__main__":
    app()
