"""abreka wiki search — find pages by keyword or regex."""

from __future__ import annotations

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

from abreka.config import find_abreka_dir
from abreka.text_match import parse_query
from abreka.wiki import load_wiki_pages


_SNIPPET_RADIUS = 60


def _snippet(body: str, match_start: int, match_end: int) -> str:
    start = max(0, match_start - _SNIPPET_RADIUS)
    end = min(len(body), match_end + _SNIPPET_RADIUS)
    snippet = body[start:end].replace("\n", " ")
    prefix = "…" if start > 0 else ""
    suffix = "…" if end < len(body) else ""
    return f"{prefix}{snippet}{suffix}"


@click.command("search")
@click.argument("query")
@click.option("--tag", default=None, help="Restrict to pages with this tag.")
def search_cmd(query: str, tag: str | None):
    """Search wiki pages over slug, title, tags, summary, body."""
    abreka_dir = find_abreka_dir()
    try:
        pattern = parse_query(query)
    except ValueError as exc:
        raise click.ClickException(str(exc))

    matches: list[tuple[str, str, str]] = []
    for page in load_wiki_pages(abreka_dir):
        if tag and tag not in page.tags:
            continue
        haystack_meta = " ".join(
            [page.slug, page.title, page.summary, " ".join(page.tags)]
        )
        body_match = pattern.search(page.body)
        if pattern.search(haystack_meta) or body_match:
            if body_match:
                snippet = _snippet(page.body, body_match.start(), body_match.end())
            else:
                snippet = page.summary or page.title
            matches.append((page.slug, page.title, snippet))

    if not matches:
        click.echo("No matches.")
        return

    console = Console()
    table = Table(show_header=True, header_style="bold")
    table.add_column("Slug", style="bold")
    table.add_column("Title")
    table.add_column("Match")
    for slug, title, snippet in matches:
        table.add_row(slug, title, snippet)
    console.print(table)
