import json
import re
from pathlib import Path

TAX = Path(r"E:/2026/plytixmage_dbs_data/kitchen_cabinets_taxonomy.json")
BROCHURE = Path(r"E:/2026/plytixmage_dbs_data/Brochure_Data")
OUT = Path(r"E:/2026/plytixmage_dbs_data/audit_reports/general_catalog_collections_gap.json")

# Curated from PDF kitchen cabinetry pages (manual cleanup of extract)
PDF_COLLECTIONS = [
    "Harriet Pearl White",
    "Anna Snow White",
    "Anna Stone Gray",
    "Anna Natural Rift White Oak",
    "Anna Caramel Harvest",
    "Eleanor Snow White",
    "Eleanor Ocean Blue",
    "Maya Snow White",
    "Maya Natural Rift White Oak",
    "Maya Black Rift White Oak",
    "Cooper Slate Gray",
    "Merrill Polar White",
    "Hurston Midnight Espresso",
    "Johnson Sandstone",
    "Belmont Drift White",
    "Belmont Toffee Pecan",
    "Chesapeake Golden Oak",
    "Metro Mist",  # Fabuwood Metro Mist
    "Metro Frost",  # Quest/Fabuwood Metro Frost in catalog as Metro Frost
    "Galaxy Horizon",
    "Hallmark Frost",
    "Riley",
    "Sanibel",
    "Plymouth Espresso Maple",
]


def norm(s: str) -> str:
    s = re.sub(r"\s+", " ", s.strip().lower())
    s = s.replace("&", "and")
    return re.sub(r"[^a-z0-9 ]+", "", s)


def load_taxonomy():
    data = json.loads(TAX.read_text(encoding="utf-8"))
    by_norm = {}
    for code, row in (data.get("collections") or {}).items():
        name = row.get("display_name") or row.get("name") or code
        by_norm[norm(name)] = {"code": code, "name": name}
        by_norm[norm(code.replace("-", " "))] = {"code": code, "name": name}
    return by_norm


def load_brochure():
    out = {}
    for path in sorted(BROCHURE.glob("*.json")):
        payload = json.loads(path.read_text(encoding="utf-8"))
        coll = payload.get("collection") if isinstance(payload.get("collection"), dict) else {}
        stem = path.stem
        for suf in ("_0226", "_0326", "_0426", "_site"):
            stem = stem.replace(suf, "")
        fname = re.sub(r"(?<=[a-z])(?=[A-Z])", " ", stem)
        name = coll.get("name") or coll.get("display_name") or fname
        code = coll.get("code") or coll.get("collection_code") or ""
        row = {"name": name, "code": code, "file": path.name}
        out[norm(name)] = row
        out[norm(fname)] = row
        if code:
            out[norm(code)] = row
        # aliases
        if "fabuwood" in norm(fname):
            short = norm(fname.replace("fabuwood", "").strip())
            out[short] = row
        if "quest" in norm(fname):
            short = norm(fname.replace("quest", "").strip())
            out[short] = row
    return out


def lookup(maps, name):
    key = norm(name)
    if key in maps:
        return maps[key]
    tokens = set(key.split())
    best = None
    best_n = 0
    for k, v in maps.items():
        kt = set(k.split())
        if not kt:
            continue
        if tokens <= kt or kt <= tokens:
            n = len(tokens & kt)
            if n > best_n:
                best = v
                best_n = n
    return best


tax = load_taxonomy()
bro = load_brochure()

rows = []
for name in PDF_COLLECTIONS:
    t = lookup(tax, name)
    b = lookup(bro, name)
    rows.append(
        {
            "name": name,
            "in_taxonomy": bool(t),
            "in_brochure": bool(b),
            "taxonomy": t,
            "brochure": b,
        }
    )

# Local collections not in PDF curated list
pdf_keys = {norm(n) for n in PDF_COLLECTIONS}
tax_names = {}
data = json.loads(TAX.read_text(encoding="utf-8"))
for code, row in (data.get("collections") or {}).items():
    name = row.get("display_name") or row.get("name") or code
    tax_names[norm(name)] = {"code": code, "name": name}

brochure_names = {}
for path in sorted(BROCHURE.glob("*.json")):
    payload = json.loads(path.read_text(encoding="utf-8"))
    coll = payload.get("collection") if isinstance(payload.get("collection"), dict) else {}
    stem = path.stem
    for suf in ("_0226", "_0326", "_0426", "_site"):
        stem = stem.replace(suf, "")
    fname = re.sub(r"(?<=[a-z])(?=[A-Z])", " ", stem)
    name = coll.get("name") or coll.get("display_name") or fname
    brochure_names[norm(name)] = {"name": name, "file": path.name}

extra_tax = [v for k, v in tax_names.items() if k not in pdf_keys]
extra_bro = []
seen = set()
for k, v in brochure_names.items():
    if v["file"] in seen:
        continue
    seen.add(v["file"])
    if k not in pdf_keys:
        # check fuzzy
        if not lookup({kk: True for kk in pdf_keys}, v["name"]):
            extra_bro.append(v)

report = {
    "pdf_collections": rows,
    "missing_in_taxonomy": [r for r in rows if not r["in_taxonomy"]],
    "missing_in_brochure": [r for r in rows if not r["in_brochure"]],
    "in_taxonomy_not_in_pdf": extra_tax,
    "in_brochure_not_in_pdf": extra_bro,
}
OUT.write_text(json.dumps(report, indent=2), encoding="utf-8")

print("PDF kitchen collections (curated):", len(PDF_COLLECTIONS))
print()
print(f"{'Collection':40} {'TAX':5} {'BROCHURE':8}")
print("-" * 60)
for r in rows:
    print(f"{r['name']:40} {'yes' if r['in_taxonomy'] else 'NO':5} {'yes' if r['in_brochure'] else 'NO':8}")

print("\nMissing in taxonomy_json:")
for r in report["missing_in_taxonomy"]:
    print(" -", r["name"])

print("\nMissing in Brochure_Data:")
for r in report["missing_in_brochure"]:
    print(" -", r["name"], f"(file={r['brochure']['file']})" if r["brochure"] else "")

print("\nIn taxonomy but not in this catalog PDF:")
for r in extra_tax:
    print(" -", r["name"], f"({r['code']})")

print("\nIn Brochure_Data but not in this catalog PDF:")
for r in extra_bro:
    print(" -", r["name"], f"[{r['file']}]")

print("\nwrote", OUT)
