"""abreka exp search — search over experiments."""

from __future__ import annotations

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

from abreka.config import find_abreka_dir, load_index
from abreka.persistence import experiment_dir
from abreka.text_match import parse_query


@click.command("search")
@click.argument("query")
@click.option("--status", "-s", multiple=True, help="Filter by status (repeatable).")
@click.option("--tag", "-t", multiple=True, help="Filter by tag (repeatable).")
def search_cmd(query: str, status: tuple[str, ...], tag: tuple[str, ...]):
    """Search experiments by hypothesis, method, and findings.

    Plain queries use word-boundary matching (case-insensitive).
    Wrap in slashes for regex: /pattern/ or /pattern/i for case-insensitive.

    Examples:

        abreka exp search SAM          # matches "SAM" but not "SAME"

        abreka exp search "/CNN|RNN/i" # regex, case-insensitive
    """
    abreka_dir = find_abreka_dir()
    index = load_index(abreka_dir)

    try:
        pattern = parse_query(query)
    except ValueError as exc:
        raise click.ClickException(str(exc))

    if not index:
        click.echo("No experiments yet.")
        return

    matches = []

    for eid, entry in index.items():
        # Apply status filter
        if status and entry.get("status") not in status:
            continue

        # Apply tag filter
        if tag and not set(tag).intersection(entry.get("tags", [])):
            continue

        # Search hypothesis, method, and tags from index
        fields = [
            entry.get("hypothesis", ""),
            entry.get("method", ""),
            *entry.get("tags", []),
        ]

        # Also search findings.md if it exists
        findings_path = experiment_dir(abreka_dir, eid) / "findings.md"
        if findings_path.is_file():
            fields.append(findings_path.read_text())

        if any(pattern.search(f) for f in fields):
            matches.append(entry)

    if not matches:
        click.echo(f"No experiments matching '{query}'")
        return

    console = Console()
    table = Table(show_header=True, header_style="bold")
    table.add_column("ID", style="bold")
    table.add_column("Status")
    table.add_column("Hypothesis", max_width=60)

    for e in matches:
        table.add_row(e["id"], e["status"], e.get("hypothesis", "")[:60])

    console.print(table)
