#!/usr/bin/env python3
"""Build or remove the local reviewed-document FTS5 index; never run by the dashboard."""

from __future__ import annotations

import argparse
import sqlite3
from pathlib import Path

from dashboard_v5.document_chunks import iter_document_chunks

SCHEMA_VERSION = "health_document_fts_v2"


def _require_fts5(connection: sqlite3.Connection) -> None:
    row = connection.execute(
        "SELECT 1 FROM pragma_module_list WHERE name='fts5' LIMIT 1"
    ).fetchone()
    if row is None:
        raise RuntimeError("sqlite_fts5_unavailable")


def _write_probe_fts5(connection: sqlite3.Connection) -> None:
    _require_fts5(connection)
    try:
        connection.execute("CREATE VIRTUAL TABLE temp.__fts5_probe USING fts5(content)")
        connection.execute("DROP TABLE temp.__fts5_probe")
    except sqlite3.Error as error:
        raise RuntimeError("sqlite_fts5_unavailable") from error


def _prepare(connection: sqlite3.Connection) -> None:
    _write_probe_fts5(connection)
    connection.execute(
        "CREATE TABLE IF NOT EXISTS health_document_fts_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)"
    )
    connection.execute(
        "CREATE VIRTUAL TABLE IF NOT EXISTS health_document_fts USING fts5(document_id UNINDEXED, chunk_no UNINDEXED, title, category, institution, document_type, content, tokenize='unicode61')"
    )
    connection.execute(
        "INSERT OR REPLACE INTO health_document_fts_meta(key,value) VALUES('schema_version',?)",
        (SCHEMA_VERSION,),
    )


def rebuild(database: Path) -> int:
    connection = sqlite3.connect(database)
    try:
        connection.execute("BEGIN IMMEDIATE")
        _prepare(connection)
        connection.execute("DELETE FROM health_document_fts")
        rows = connection.execute(
            "SELECT id,kategorie,institution,daten_typ,extrahierte_inhalte FROM dokumente WHERE review_status='geprueft' ORDER BY id"
        ).fetchall()
        inserted = 0
        for document_id, category, institution, document_type, text in rows:
            if not isinstance(text, str) or not text.strip():
                continue
            title = f"Dokument · {str(category or 'Ohne Kategorie')[:80]}"
            for chunk in iter_document_chunks(text):
                connection.execute(
                    "INSERT INTO health_document_fts(document_id,chunk_no,title,category,institution,document_type,content) VALUES(?,?,?,?,?,?,?)",
                    (
                        str(document_id),
                        chunk.number,
                        title,
                        str(category or "")[:80],
                        str(institution or "")[:120],
                        str(document_type or "")[:20],
                        chunk.text,
                    ),
                )
                inserted += 1
        connection.commit()
        return inserted
    except Exception:
        connection.rollback()
        raise
    finally:
        connection.close()


def check(database: Path) -> int:
    connection = sqlite3.connect(f"file:{database.resolve()}?mode=ro", uri=True)
    try:
        _require_fts5(connection)
        row = connection.execute(
            "SELECT value FROM health_document_fts_meta WHERE key='schema_version'"
        ).fetchone()
        if row is None or row[0] != SCHEMA_VERSION:
            raise RuntimeError("fts_schema_not_ready")
        count = connection.execute(
            "SELECT COUNT(*) FROM health_document_fts"
        ).fetchone()[0]
        print(f"fts_check=ok chunks={count}")
        return 0
    finally:
        connection.close()


def drop(database: Path) -> None:
    connection = sqlite3.connect(database)
    try:
        connection.execute("BEGIN IMMEDIATE")
        connection.execute("DROP TABLE IF EXISTS health_document_fts")
        connection.execute("DROP TABLE IF EXISTS health_document_fts_meta")
        connection.commit()
    except Exception:
        connection.rollback()
        raise
    finally:
        connection.close()


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        description="local reviewed-document FTS5 maintenance"
    )
    parser.add_argument("--db", type=Path, required=True)
    mode = parser.add_mutually_exclusive_group(required=True)
    mode.add_argument("--check", action="store_true")
    mode.add_argument("--rebuild", action="store_true")
    mode.add_argument(
        "--drop",
        action="store_true",
        help="documented rollback: remove only FTS schema",
    )
    args = parser.parse_args(argv)
    if args.check:
        return check(args.db)
    if args.drop:
        drop(args.db)
        print("fts_drop=ok")
        return 0
    print(f"fts_rebuild=ok chunks={rebuild(args.db)}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
