"""
Processor module - transforms validated documents into enriched records
ready for storage and retrieval.
"""
import re
from storage import load_index, save_processed


STOPWORDS = {"the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with"}


def normalize_text(text: str) -> str:
    """Lowercase, strip extra whitespace, remove control characters."""
    text = text.lower().strip()
    text = re.sub(r"\s+", " ", text)
    text = re.sub(r"[^\x20-\x7e]", "", text)
    return text


def extract_keywords(text: str) -> list:
    """Pull non-stopword tokens from text, deduplicated."""
    tokens = re.findall(r"\b[a-z]{3,}\b", normalize_text(text))
    seen = set()
    keywords = []
    for t in tokens:
        if t not in STOPWORDS and t not in seen:
            seen.add(t)
            keywords.append(t)
    return keywords


def enrich_document(doc: dict) -> dict:
    """Add keyword index and cross-references to a validated document."""
    text_blob = " ".join([
        doc.get("title", ""),
        " ".join(doc.get("sections", [])),
        " ".join(doc.get("paragraphs", [])),
    ])
    doc["keywords"] = extract_keywords(text_blob)
    doc["cross_refs"] = find_cross_references(doc)
    return doc


def find_cross_references(doc: dict) -> list:
    """Look up the index and return IDs of related documents by keyword overlap."""
    index = load_index()
    keywords = set(doc.get("keywords", []))
    refs = []
    for record_id, entry in index.items():
        other_keywords = set(entry.get("keywords", []))
        overlap = keywords & other_keywords
        if len(overlap) >= 3:
            refs.append({"id": record_id, "shared_keywords": list(overlap)})
    return refs


def process_and_save(doc: dict) -> str:
    """Enrich a validated document and persist it. Returns the record ID."""
    enriched = enrich_document(doc)
    record_id = save_processed(enriched)
    return record_id


def reprocess_all() -> int:
    """Re-enrich all records in the index. Returns count of records updated."""
    index = load_index()
    count = 0
    for record_id, doc in index.items():
        process_and_save(doc)
        count += 1
    return count
