import sys, os, unicodedata
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import curriculum as C
strip = lambda s: "".join(c for c in unicodedata.normalize("NFD", s) if unicodedata.category(c) != "Mn").lower()
bad = []
for lid, a in C.ACTIVITIES.values():
    d, t = a["data"], a["type"]
    if t == "sound_pick":
        good = sum(1 for i in d["items"] if i["correct"])
        if good == 0 or good != d["count"] or len(d["items"]) < 3: bad.append((a["id"], f"pick count={d['count']} good={good} n={len(d['items'])}"))
    if t in ("fill_letter", "spell", "listen_choose", "match", "memory", "mcq", "word_order", "fill_word", "true_false", "speak"):
        key = {"mcq": "questions", "match": "pairs", "memory": "pairs"}.get(t, "items")
        if len(d[key]) < 2: bad.append((a["id"], f"{t} only {len(d[key])}"))
    if t == "letter_spot":
        tot = sum(1 for w in d["words"] for ch in w["word"] if strip(ch) == d["letter"])
        if tot == 0 or len(d["words"]) < 3: bad.append((a["id"], f"spot total={tot} words={len(d['words'])}"))
    if t == "mcq":
        for q in d["questions"]:
            if q["answer"] not in q["choices"] or len(set(q["choices"])) != len(q["choices"]): bad.append((a["id"], "mcq answer/dupe: " + q["q"]))
    if t == "fill_word":
        for it in d["items"]:
            if it["answer"] not in d["bank"] or "___" not in it["text"]: bad.append((a["id"], "fill_word: " + it["text"]))
    if t == "listen_choose":
        for it in d["items"]:
            if it["answer"] not in it["choices"]: bad.append((a["id"], "listen answer missing"))
    if t == "fill_letter":
        for it in d["items"]:
            if not it["blanks"]: bad.append((a["id"], "no blanks: " + it["word"]))
            ch = it.get("choices") or d.get("choices")
            for b in it["blanks"]:
                if strip(it["word"][b]) not in [strip(c) for c in ch]: bad.append((a["id"], f"letter {it['word'][b]} of {it['word']} not in choices {ch}"))
    if t == "match":
        lefts = [p["text"] for p in d["pairs"]]
        if len(set(lefts)) != len(lefts): bad.append((a["id"], "duplicate match labels"))
    # --- junior types (level 4)
    if t == "speed_round":
        for q in d["items"]:
            if q["answer"] not in q["choices"] or len(set(q["choices"])) != len(q["choices"]): bad.append((a["id"], "speed answer/dupe: " + q["q"]))
        if d["target"] > len(d["items"]): bad.append((a["id"], "speed target > items"))
    if t == "type_answer":
        for it in d["items"]:
            if it["text"].count("___") != len(it["blanks"]) or not all(all(x.strip() for x in b) for b in it["blanks"]): bad.append((a["id"], "blanks: " + it["text"]))
    if t == "rewrite":
        for it in d["items"]:
            if not it["from"].strip() or not all(x.strip() for x in it["answers"]): bad.append((a["id"], "rewrite empty"))
            if strip(it["from"]) == strip(it["answers"][0]): bad.append((a["id"], "rewrite unchanged: " + it["from"]))
    if t == "error_hunt":
        for it in d["items"]:
            if not 0 <= it["wrong"] < len(it["words"]) or (it["words"][it["wrong"]] == it["fix"] if it.get("case") else strip(it["words"][it["wrong"]]) == strip(it["fix"])): bad.append((a["id"], "hunt: " + " ".join(it["words"])))
    if t == "conjugate":
        for it in d["items"]:
            if any(not r["answer"].strip() for r in it["rows"]): bad.append((a["id"], "conjugate empty row " + it["verb"]))
    if t == "sort":
        ids = {b["id"] for b in d["bins"]}
        if any(i["bin"] not in ids for i in d["items"]): bad.append((a["id"], "sort bin missing"))
for b in bad: print(b)
print(len(bad), "problems")
