from __future__ import annotations

from pathlib import Path
import argparse
import hashlib
import json
import sqlite3
import sys

ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "src"
sys.path.insert(0, str(SRC))

from ai_archive.paths import INDEX_DIR


def quote_fts_query(query: str) -> str:
    return '"' + query.replace('"', '""') + '"'


def fingerprint(text: str) -> str:
    normalized = " ".join(text.lower().split())
    return hashlib.sha256(normalized.encode("utf-8")).hexdigest()


def infer_memory_type(text: str, title: str) -> str:
    hay = f"{title}\n{text}".lower()
    if any(term in hay for term in ["voice", "style", "tone", "writing"]):
        return "writing_voice"
    if any(term in hay for term in ["barely, but here", "barely but here", "bbh"]):
        return "project_context"
    if any(term in hay for term in ["offer", "assessment", "$599", "landing page"]):
        return "offer"
    if any(term in hay for term in ["decided", "decision", "chose", "instead of"]):
        return "decision"
    return "source_excerpt"


def infer_sensitivity(text: str) -> str:
    hay = text.lower()
    sensitive_terms = ["therapy", "therapist", "depression", "mental health", "trauma", "password", "api key", "secret key", "token"]
    if any(term in hay for term in sensitive_terms):
        return "sensitive"
    return "private"


def main() -> int:
    parser = argparse.ArgumentParser(description="Export archive search results as reviewable Open Brain memory candidates.")
    parser.add_argument("query", help="Literal phrase/query to search in the local archive")
    parser.add_argument("--limit", type=int, default=25)
    parser.add_argument("--source")
    parser.add_argument("--project")
    parser.add_argument("--output", default=str(ROOT / "normalized" / "memory_candidates.jsonl"))
    args = parser.parse_args()

    conn = sqlite3.connect(INDEX_DIR / "archive.db")
    conn.row_factory = sqlite3.Row
    try:
        sql = """
        SELECT c.chunk_id, c.conversation_id, c.source, c.title, c.message_start, c.message_end, c.text, c.metadata_json
        FROM chunks_fts f
        JOIN chunks c ON c.rowid = f.rowid
        WHERE chunks_fts MATCH ?
        """
        params: list[object] = [quote_fts_query(args.query)]
        if args.source:
            sql += " AND c.source = ?"
            params.append(args.source)
        sql += " LIMIT ?"
        params.append(args.limit)
        rows = conn.execute(sql, params).fetchall()
    finally:
        conn.close()

    out = Path(args.output)
    out.parent.mkdir(parents=True, exist_ok=True)
    written = 0
    with out.open("a", encoding="utf-8") as fh:
        for row in rows:
            md = json.loads(row["metadata_json"] or "{}")
            text = row["text"]
            memory_type = infer_memory_type(text, row["title"])
            project = args.project
            if not project and ("barely, but here" in text.lower() or "barely but here" in text.lower()):
                project = "Barely, But Here"
            candidate = {
                "content": text[:1800],
                "metadata": {
                    "memory_type": memory_type,
                    "durability": "long_term" if memory_type in {"writing_voice", "project_context", "offer", "decision"} else "medium_term",
                    "confidence": "medium",
                    "sensitivity": infer_sensitivity(text),
                    "source": row["source"],
                    "source_archive": "ai-archive",
                    "source_conversation_id": row["conversation_id"],
                    "source_chunk_id": row["chunk_id"],
                    "source_raw_path": md.get("raw_path"),
                    "source_message_range": f"{row['message_start']}-{row['message_end']}",
                    "project": project,
                    "topics": [args.query],
                    "created_from": "archive_search_candidate",
                    "review_status": "candidate",
                    "source_memory_fingerprint": fingerprint(text[:1800]),
                },
            }
            fh.write(json.dumps(candidate, ensure_ascii=False) + "\n")
            written += 1
    print(f"wrote {written} candidates to {out}")
    return 0


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