"""Memorious CLI - command line interface for crawler management."""

from typing import Annotated, Optional

import typer
from anystore.logging import get_logger
from procrastinate.jobs import DeleteJobCondition
from rich.console import Console

from memorious.core import init_memorious, settings
from memorious.logic.crawler import get_crawler
from memorious.settings import VERSION
from memorious.tasks import app as procrastinate_app

log = get_logger(__name__)
console = Console(stderr=True)

cli = typer.Typer(no_args_is_help=True, pretty_exceptions_enable=settings.debug)


@cli.callback(invoke_without_command=True)
def main(
    version: Annotated[
        Optional[bool], typer.Option("--version", "-v", help="Show version")
    ] = False,
    settings_: Annotated[
        Optional[bool], typer.Option("--settings", help="Show current settings")
    ] = False,
):
    """Crawler framework for documents and structured scrapers."""
    if version:
        console.print(f"memorious {VERSION}")
        raise typer.Exit()
    if settings_:
        console.print(settings)

    init_memorious()


@cli.command("run")
def run_crawler(
    uri: Annotated[str, typer.Argument(help="URI or path to crawler YAML config file")],
    continue_on_error: Annotated[
        bool,
        typer.Option(
            "--continue-on-error", help="Don't stop crawler execution on error"
        ),
    ] = False,
    flush: Annotated[
        bool,
        typer.Option("--flush", help="Delete all existing data before execution"),
    ] = False,
    concurrency: Annotated[
        int,
        typer.Option(
            "--concurrency",
            "-c",
            help="Number of concurrent jobs (use >1 for I/O-bound crawlers)",
        ),
    ] = 1,
    wait: Annotated[
        bool,
        typer.Option(
            "--wait",
            "-w",
            help="Keep worker running after jobs complete (until interrupted)",
        ),
    ] = False,
    idle_timeout: Annotated[
        int,
        typer.Option(
            "--idle-timeout",
            "-t",
            help=(
                "Auto-stop after N seconds of inactivity "
                "(default: 30 for concurrency>1, 0 to disable)"
            ),
        ),
    ] = 30,
    clear_runs: Annotated[
        bool,
        typer.Option(
            "--clear-runs/--no-clear-runs",
            help="Cancel remaining tasks from previous runs before starting",
        ),
    ] = True,
):
    """Run a crawler from a YAML config file."""
    crawler = get_crawler(uri)
    if flush:
        crawler.flush()

    # Convert 0 to None to let Crawler.run() apply defaults
    effective_idle_timeout = idle_timeout if idle_timeout > 0 else None

    crawler.log.info(
        f"[{crawler.name}] Starting Memorious crawler ...",
        continue_on_error=continue_on_error,
        flush=flush,
        concurrency=concurrency,
        wait=wait,
        idle_timeout=effective_idle_timeout,
        clear_runs=clear_runs,
    )
    crawler.run(
        continue_on_error=continue_on_error,
        concurrency=concurrency,
        wait=wait,
        idle_timeout=effective_idle_timeout,
        clear_runs=clear_runs,
    )
    crawler.log.info(f"[{crawler.name}] Crawler completed.")


@cli.command("worker")
def worker(
    concurrency: Annotated[
        int,
        typer.Option(
            "--concurrency",
            "-c",
            help="Number of concurrent jobs (use >1 for I/O-bound crawlers)",
        ),
    ] = 1,
):
    """Start the procrastinate worker to process crawler jobs."""
    console.print(f"Starting memorious worker with concurrency={concurrency}")
    procrastinate_app.run_worker(
        wait=True,
        concurrency=concurrency,
        delete_jobs=DeleteJobCondition.SUCCESSFUL,
    )


@cli.command("cancel")
def cancel(
    uri: Annotated[str, typer.Argument(help="URI or path to crawler YAML config file")],
):
    """Cancel pending jobs for a crawler."""
    crawler = get_crawler(uri)
    crawler.cancel()
    console.print(f"Crawler [bold]{crawler.name}[/bold] cancelled")


@cli.command("flush")
def flush_crawler(
    uri: Annotated[str, typer.Argument(help="URI or path to crawler YAML config file")],
):
    """Delete all data and tags generated by a crawler."""
    crawler = get_crawler(uri)
    crawler.flush()
    console.print(f"Crawler [bold]{crawler.name}[/bold] data flushed")


if __name__ == "__main__":
    cli()
