"""Click CLI entry point for mykb."""

from pathlib import Path

import click
from rich.console import Console
from rich.table import Table

console = Console()


@click.group()
@click.option('-c', '--config-dir', type=click.Path(), default=None, help='Config directory (default: ~/.mykb)')
def cli(config_dir):
    """MYKB — Local CLI search engine for personal knowledge bases."""
    if config_dir:
        from mykb.core.config import set_config_dir

        set_config_dir(Path(config_dir).expanduser().resolve())


# --- collection commands ---


@cli.group()
def collection():
    """Manage collections."""
    pass


@collection.command('add')
@click.argument('path')
@click.option('--name', '-n', required=True, help='Collection name')
@click.option('--source', '-s', default='obsidian', help='Source type (default: obsidian)')
@click.option('--mask', default='**/*.md', help='Glob pattern for files')
@click.option('--exclude', '-e', multiple=True, help='Exclude patterns')
@click.option('--description', '-d', default='', help='Description')
def collection_add(path, name, source, mask, exclude, description):
    """Add a new collection."""
    from mykb.core.collection import add_collection

    col = add_collection(
        name=name,
        path=path,
        mask=mask,
        exclude=list(exclude),
        description=description,
        source=source,
    )
    console.print(f"[green]Added collection '{name}'[/green]")
    console.print(f'  Source: {col.source}')
    console.print(f'  Path: {col.path}')
    console.print(f'  Mask: {col.mask}')
    if col.exclude:
        console.print(f'  Exclude: {", ".join(col.exclude)}')


@collection.command('ls')
def collection_ls():
    """List all collections."""
    from mykb.core.collection import list_collections

    collections = list_collections()
    if not collections:
        console.print('[yellow]No collections configured.[/yellow]')
        return

    table = Table(title='Collections')
    table.add_column('Name', style='bold cyan')
    table.add_column('Path')
    table.add_column('Mask')
    table.add_column('Description')

    for name, col in collections.items():
        table.add_row(name, col.path, col.mask, col.description)

    console.print(table)


@collection.command('rm')
@click.argument('name')
def collection_rm(name):
    """Remove a collection."""
    from mykb.core.collection import remove_collection

    remove_collection(name)
    console.print(f"[green]Removed collection '{name}'[/green]")


# --- index command ---


@cli.command()
@click.option('--full', is_flag=True, help='Force full re-index')
@click.option('--collection', '-c', 'collection_name', default=None, help='Index specific collection')
@click.option('--embed', is_flag=True, help='Generate embeddings during indexing (via daemon)')
def index(full, collection_name, embed):
    """Index documents from collections into Meilisearch."""
    if embed:
        # Use daemon for embedding
        from mykb.client import DaemonClient
        from mykb.core.collection import list_collections

        client = DaemonClient()

        if collection_name:
            collections = [collection_name]
        else:
            collections = list(list_collections().keys())

        if not collections:
            console.print('[yellow]No collections configured.[/yellow]')
            return

        total_chunks = 0
        for col in collections:
            console.print(f'[bold]Indexing {col}...[/bold]')
            result = client.index_collection(col, full=full, with_embeddings=True)
            console.print(f'  Indexed {result["chunks"]} chunks in {result["elapsed"]:.2f}s')
            total_chunks += result['chunks']

        console.print(f'[bold green]Total indexed: {total_chunks} chunks[/bold green]')
    else:
        # Direct indexing without embeddings
        from mykb.core.indexer import run_index

        run_index(collection_name=collection_name, full=full, embed_fn=None)


# --- embed command ---


@cli.command()
@click.option('--full', is_flag=True, help='Force full re-embedding')
@click.option('--collection', '-c', 'collection_name', default=None, help='Embed specific collection')
def embed(full, collection_name):
    """Generate/update embeddings for indexed documents (via daemon)."""
    from mykb.client import DaemonClient
    from mykb.core.collection import list_collections

    client = DaemonClient()

    if collection_name:
        collections = [collection_name]
    else:
        collections = list(list_collections().keys())

    if not collections:
        console.print('[yellow]No collections configured.[/yellow]')
        return

    total_updated = 0
    for col in collections:
        console.print(f'[bold]Embedding {col}...[/bold]')
        result = client.embed_collection(col, full=full)
        console.print(f'  Updated {result["updated"]} documents')
        total_updated += result['updated']

    console.print(f'[bold green]Total updated: {total_updated} documents[/bold green]')


# --- search commands ---


def _search_options(f):
    """Common search options decorator."""
    f = click.option('-n', '--num', default=5, type=int, help='Number of results')(f)
    f = click.option('-c', '--collection', 'collection_name', default=None, help='Filter by collection')(f)
    f = click.option('--json', 'as_json', is_flag=True, help='Output as JSON')(f)
    f = click.option('--full', is_flag=True, help='Show full chunk content')(f)
    return f


@cli.command()
@click.argument('query')
@_search_options
def search(query, num, collection_name, as_json, full):
    """BM25 full-text search."""
    from mykb.core.api import get_api
    from mykb.core.search import format_results_json, format_results_rich

    api = get_api()
    results = api.search_bm25(query, limit=num, collection=collection_name)
    if as_json:
        click.echo(format_results_json(results))
    else:
        format_results_rich(results, show_full=full)


@cli.command()
@click.argument('query')
@_search_options
def vsearch(query, num, collection_name, as_json, full):
    """Vector semantic search (via daemon)."""
    from mykb.client import DaemonClient
    from mykb.core.search import format_results_json, format_results_rich

    client = DaemonClient()
    results = client.vector_search(query, limit=num, collection=collection_name)
    if as_json:
        click.echo(format_results_json(results))
    else:
        format_results_rich(results, show_full=full)


@cli.command('query')
@click.argument('query_text')
@_search_options
@click.option('--ratio', default=0.5, type=float, help='Semantic ratio (0=BM25, 1=vector)')
def hybrid_query(query_text, num, collection_name, as_json, full, ratio):
    """Hybrid search (BM25 + vector, via daemon)."""
    from mykb.client import DaemonClient
    from mykb.core.search import format_results_json, format_results_rich

    client = DaemonClient()
    results = client.hybrid_search(query_text, limit=num, collection=collection_name, semantic_ratio=ratio)
    if as_json:
        click.echo(format_results_json(results))
    else:
        format_results_rich(results, show_full=full)


# --- get command ---


@cli.command()
@click.argument('path')
def get(path):
    """Get original document content by source path."""
    from mykb.core.collection import list_collections

    collections = list_collections()
    for name, col in collections.items():
        full_path = Path(col.path) / path
        if full_path.exists():
            content = full_path.read_text(encoding='utf-8')
            console.print(content)
            return

    console.print(f'[red]File not found in any collection: {path}[/red]')


# --- status command ---


@cli.command()
def status():
    """Show index status, collection info, and document counts."""
    from mykb.core.api import get_api
    from mykb.core.collection import list_collections
    from mykb.core.config import get_backend_config
    from mykb.sources import get_source

    # Collections info
    collections = list_collections()
    console.print('[bold]Collections:[/bold]')
    if not collections:
        console.print('  [yellow]None configured[/yellow]')
    else:
        for name, col in collections.items():
            source = get_source(col.source, name, col.model_dump())
            item_count = sum(1 for _ in source.scan())
            console.print(f'  [cyan]{name}[/cyan] ({col.source}): {col.path} ({item_count} items)')

    # Backend info
    backend_type, _ = get_backend_config()
    console.print(f'\n[bold]Backend ({backend_type}):[/bold]')

    api = get_api()
    backend = api.ensure_backend()
    health = backend.health_check()
    console.print(f'  Status: [green]{health.get("status", "unknown")}[/green]')

    if 'url' in health:
        console.print(f'  URL: {health["url"]}')

    stats = backend.get_stats('mykb')
    doc_count = stats.get('total_documents', 0)
    console.print(f'  Documents: {doc_count}')


# --- daemon commands ---


@cli.group()
def daemon():
    """Manage the mykb daemon."""
    pass


@daemon.command('start')
@click.option('--foreground', '-f', is_flag=True, help='Run in foreground (do not daemonize)')
def daemon_start(foreground):
    """Start the daemon."""
    from mykb.daemon import start_daemon

    if foreground:
        console.print('[bold]Starting daemon in foreground...[/bold]')
        console.print('[dim]Press Ctrl+C to stop[/dim]')
    else:
        console.print('[bold]Starting daemon...[/bold]')

    success = start_daemon(foreground=foreground)

    if not foreground:
        if success:
            from mykb.daemon.process import get_daemon_status

            status = get_daemon_status()
            console.print(f'[green]Daemon started[/green] (PID: {status["pid"]})')
            console.print(f'  URL: {status["url"]}')
            console.print(f'  Log: {status["log_file"]}')
        else:
            console.print('[red]Failed to start daemon[/red]')
            raise SystemExit(1)


@daemon.command('stop')
def daemon_stop():
    """Stop the daemon."""
    from mykb.daemon import stop_daemon

    console.print('[bold]Stopping daemon...[/bold]')
    success = stop_daemon()

    if success:
        console.print('[green]Daemon stopped[/green]')
    else:
        console.print('[red]Failed to stop daemon[/red]')
        raise SystemExit(1)


@daemon.command('status')
def daemon_status():
    """Show daemon status."""
    from mykb.daemon import get_daemon_status

    status = get_daemon_status()

    if status['running']:
        console.print(f'[bold green]Daemon is running[/bold green]')
        console.print(f'  PID: {status["pid"]}')
        console.print(f'  URL: {status["url"]}')

        if status.get('health'):
            health = status['health']
            console.print(f'  Model: {health.get("model_name", "unknown")}')
            console.print(f'  Model loaded: {health.get("model_loaded", False)}')
            console.print(f'  Backend: {health.get("backend", "unknown")}')
            uptime = health.get('uptime', 0)
            console.print(f'  Uptime: {uptime:.0f}s')
    else:
        console.print('[yellow]Daemon is not running[/yellow]')

    console.print(f'\n[dim]PID file: {status["pid_file"]}[/dim]')
    console.print(f'[dim]Log file: {status["log_file"]}[/dim]')
