"""
Verified Word Database — Source of Truth for Phonetic Patterns.

Each entry: word -> {pattern, vowel_sound, notes}

Pattern codes:
    short_a, short_e, short_i, short_o, short_u
    long_a_cvc e, long_e_cvc e, long_i_cvc e, long_o_cvc e, long_u_cvc e
    long_a_ai, long_a_ay, long_e_ee, long_e_ea, long_o_oa, long_o_ow, long_u_ew
    digraph_sh, digraph_ch, digraph_th, digraph_wh, digraph_ph, digraph_ck
    soft_c_ci, soft_c_ce, soft_c_cy, soft_g_ge, soft_g_gi, soft_g_gy
    r_control_ar, r_control_er, r_control_ir, r_control_or, r_control_ur
    double_consonant, irregular
    # Morphological (prefixes/suffixes — Weeks 9-11)
    prefix_un, prefix_re, prefix_dis
    suffix_s, suffix_es, suffix_ed, suffix_ing, suffix_er, suffix_est
    suffix_ly, suffix_ful, suffix_less, suffix_ment, suffix_ion, suffix_able, suffix_ive
    suffix_ous, suffix_ious  # Week 14: -ous (enormous), -ious (delicious)
    # Special rules
    ie_rule  # i before e (Week 13 irregulars)
    # Homophones (Week 12)
    homophone
    # Multi-pattern words (taught from different angles in different weeks)
    #   e.g., rainbow: long_a_ai (W3) / long_o_ow (W4)
"""

from dataclasses import dataclass
from typing import Dict, List, Optional


@dataclass
class WordEntry:
    word: str
    pattern: str
    vowel_sound: str
    notes: str = ""
    priority: int = 1


_VERIFIED_WORDS: Dict[str, WordEntry] = {}


def _add(word: str, pattern: str, vowel_sound: str, notes: str = ""):
    _VERIFIED_WORDS[word.lower().strip()] = WordEntry(word, pattern, vowel_sound, notes)


# ===== Week 1: Short Vowels (multi-syllable) =====
_add("basket", "short_a", "a→/æ/", "multi-syllable: BAS-ket")
_add("garden", "short_a", "a→/æ/", "multi-syllable: GAR-den")
_add("animal", "short_a", "a→/æ/", "multi-syllable: AN-i-mal")
_add("elephant", "short_e", "e→/ɛ/", "multi-syllable: EL-e-phent")
_add("helmet", "short_e", "e→/ɛ/", "multi-syllable: HEL-met")
_add("insect", "short_i", "i→/ɪ/", "multi-syllable: IN-sect")
_add("kitten", "double_consonant", "tt→short_i", "double tt keeps i short — also short_i")
_add("winter", "r_control_er", "er→/ɚ/", "multi-syllable: WIN-ter — r-controlled 'er'")
_add("octopus", "short_o", "o→/ɔ/", "multi-syllable: OK-to-pus")
_add("doctor", "r_control_or", "or→/ɚ/", "multi-syllable: DAK-ter — reduced 'or'")
_add("umbrella", "short_u", "u→/ʌ/", "multi-syllable: um-BREL-a")
_add("bubble", "short_u", "u→/ʌ/", "multi-syllable: BUB-uhl")
_add("blanket", "short_a", "a→/æ/", "short a + k ending")
_add("smooth", "digraph_th", "th→/θ/", "consonant digraph at end")


# ===== Week 2: Silent E (CVCe) =====
_add("rescue", "long_u_cvc e", "u_e→/juː/", "CVCe")
_add("invite", "long_i_cvc e", "i_e→/aɪ/", "CVCe")
_add("behave", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("polite", "long_i_cvc e", "i_e→/aɪ/", "CVCe")
_add("debate", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("strange", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("create", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("devote", "long_o_cvc e", "o_e→/oʊ/", "CVCe")
_add("relieve", "long_e_cvc e", "ie→/iː/", "also i before e, silent e pattern")
_add("divide", "long_i_cvc e", "i_e→/aɪ/", "CVCe")
_add("escape", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("remote", "long_o_cvc e", "o_e→/oʊ/", "CVCe")
_add("cat", "short_a", "a→/æ/", "CVC")
_add("bed", "short_e", "e→/ɛ/", "CVC")
_add("sit", "short_i", "i→/ɪ/", "CVC")
_add("hot", "short_o", "o→/ɔ/", "CVC")
_add("cup", "short_u", "u→/ʌ/", "CVC")
_add("mad", "short_a", "a→/æ/", "CVC")
_add("red", "short_e", "e→/ɛ/", "CVC")
_add("big", "short_i", "i→/ɪ/", "CVC")
_add("dog", "short_o", "o→/ɔ/", "CVC")
_add("run", "short_u", "u→/ʌ/", "CVC")
_add("hat", "short_a", "a→/æ/", "CVC")
_add("pen", "short_e", "e→/ɛ/", "CVC")


# ===== Week 2: Silent E (CVCe) =====
_add("cake", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("bike", "long_i_cvc e", "i_e→/aɪ/", "CVCe")
_add("home", "long_o_cvc e", "o_e→/oʊ/", "CVCe")
_add("cube", "long_u_cvc e", "u_e→/juː/", "CVCe")
_add("hope", "long_o_cvc e", "o_e→/oʊ/", "CVCe")
_add("like", "long_i_cvc e", "i_e→/aɪ/", "CVCe")
_add("made", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("ride", "long_i_cvc e", "i_e→/aɪ/", "CVCe")
_add("rose", "long_o_cvc e", "o_e→/oʊ/", "CVCe")
_add("tame", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("tape", "long_a_cvc e", "a_e→/eɪ/", "CVCe")
_add("time", "long_i_cvc e", "i_e→/aɪ/", "CVCe")


# ===== Week 3: Vowel Teams =====
_add("rain", "long_a_ai", "ai→/eɪ/", "vowel team")
_add("bee", "long_e_ee", "ee→/iː/", "vowel team")
_add("boat", "long_o_oa", "oa→/oʊ/", "vowel team")
_add("break", "long_a_ai", "ea→/eɪ/ or /e/", "vowel team")
_add("day", "long_a_ay", "ay→/eɪ/", "vowel team")
_add("feet", "long_e_ee", "ee→/iː/", "vowel team")
_add("leaf", "long_e_ea", "ea→/iː/", "vowel team")
_add("paint", "long_a_ai", "ai→/eɪ/", "vowel team")
_add("play", "long_a_ay", "ay→/eɪ/", "vowel team")
_add("snake", "long_a_ay", "a_e→/eɪ/", "CVCe")
_add("sneak", "long_a_ay", "ea→/iː/ or /eɪ/", "vowel team")
_add("steak", "long_a_ay", "ea→/eɪ/", "vowel team")


# ===== Week 3: Vowel Teams (compounds) =====
_add("railroad", "long_a_ai", "ai→/eɪ/", "compound: rail + road")
_add("rainfall", "long_a_ai", "ai→/eɪ/", "compound: rain + fall")
_add("staircase", "long_a_ai", "ai→/eɪ/", "compound: stair + case")
_add("mailbox", "long_a_ai", "ai→/eɪ/", "compound: mail + box")
_add("mainland", "long_a_ai", "ai→/eɪ/", "compound: main + land")
_add("sweater", "long_e_ea", "ea→/ɛ/", "also short e ea")
_add("teacher", "digraph_ch", "ch→/tʃ/", "also long_e_ea — taught as ch digraph in W5")
_add("street", "long_e_ee", "ee→/iː/", "vowel team")
_add("cheese", "long_e_ee", "ee→/iː/", "also ch digraph")
_add("cheerful", "long_e_ee", "ee→/iː/", "also ch digraph")
_add("beefsteak", "long_e_ea", "ee→/iː/", "compound: beef + steak")


# ===== Week 4: oa/ow/ou/ew =====
_add("snow", "long_o_ow", "ow→/oʊ/", "vowel team")
_add("bowl", "long_o_ow", "ow→/oʊ/", "vowel team")
_add("flower", "homophone", "ow→/aʊ/", "homophone with flour")
_add("house", "long_o_ou", "ou→/aʊ/", "vowel team")
_add("mouse", "long_o_ou", "ou→/aʊ/", "vowel team")
_add("cow", "long_o_ow", "ow→/aʊ/", "vowel team")
_add("town", "long_o_ow", "ow→/aʊ/", "vowel team")
_add("clown", "long_o_ow", "ow→/aʊ/", "vowel team")
_add("yellow", "long_o_ow", "ow→/oʊ/", "vowel team")
_add("sew", "long_e_ew", "ew→/oʊ/", "vowel team")
_add("rainbow", "long_o_ow", "ow→/aʊ/", "compound: rain + bow — also long_a_ai in W3")
_add("sailboat", "long_o_oa", "oa→/oʊ/", "compound: sail + boat")


# ===== Week 5: Digraphs =====
_add("ship", "digraph_sh", "sh→/ʃ/", "consonant digraph")
_add("chin", "digraph_ch", "ch→/tʃ/", "consonant digraph")
_add("this", "digraph_th", "th→/ð/", "consonant digraph")
_add("when", "digraph_wh", "wh→/w/", "consonant digraph")
_add("phone", "digraph_ph", "ph→/f/", "consonant digraph")
_add("neck", "digraph_ck", "ck→/k/", "consonant digraph")
_add("fish", "digraph_sh", "sh→/ʃ/", "consonant digraph")
_add("wish", "digraph_sh", "sh→/ʃ/", "consonant digraph")
_add("chat", "digraph_ch", "ch→/tʃ/", "consonant digraph")
_add("bath", "digraph_th", "th→/θ/", "consonant digraph")
_add("duck", "digraph_ck", "ck→/k/", "consonant digraph")
_add("truck", "digraph_ck", "ck→/k/", "consonant digraph")
_add("shelter", "digraph_sh", "sh→/ʃ/", "consonant digraph")
_add("smooth", "digraph_th", "th→/θ/", "consonant digraph — NOTE: NOT 'sh'")
_add("pocket", "digraph_ck", "ck→/k/", "short o + ck digraph")
_add("rocket", "digraph_ck", "ck→/k/", "short o + ck digraph")
_add("thunder", "digraph_th", "th→/θ/", "consonant digraph")
_add("whether", "digraph_wh", "wh→/w/", "consonant digraph")
_add("dolphin", "digraph_ph", "ph→/f/", "consonant digraph")
_add("physics", "digraph_ph", "ph→/f/", "consonant digraph")
_add("stretch", "digraph_ch", "ch→/tʃ/", "consonant digraph")
_add("mother", "digraph_th", "th→/ð/", "consonant digraph")


# ===== Week 6: Soft C/G =====
_add("city", "soft_c_ci", "ci→/s/", "soft c before i")
_add("face", "soft_c_ce", "ce→/s/", "soft c before e")
_add("gym", "soft_g_gy", "gy→/dʒ/", "soft g before y")
_add("gem", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("magic", "soft_c_ci", "ci→/s/", "soft c before i")
_add("dance", "soft_c_ce", "ce→/s/", "soft c before e")
_add("tiger", "soft_g_gi", "gi→/dʒ/", "soft g before i")
_add("bicycle", "soft_c_cy", "cy→/s/", "soft c before y")
_add("circle", "soft_c_ci", "ci→/s/", "soft c before i")
_add("notice", "soft_c_ci", "ci→/s/", "soft c before i")
_add("decide", "soft_c_ci", "ci→/s/", "soft c before i")
_add("ceiling", "soft_c_ce", "ce→/s/", "soft c before e")
_add("gentle", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("college", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("danger", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("change", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("giant", "soft_g_gi", "gi→/dʒ/", "soft g before i")
_add("cage", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("garage", "soft_g_ge", "ge→/dʒ/", "soft g before e (tricky: first g is hard)")
_add("finger", "soft_g_gi", "gi→/dʒ/", "soft g before i (tricky: actually hard g /ŋɡ/)")
_add("energy", "soft_g_gy", "gy→/dʒ/", "soft g before y")


# ===== Week 9: Prefixes (un-, re-, dis-) =====
_add("undo", "prefix_un", "un→/ʌn/", "prefix: undo")
_add("unlock", "prefix_un", "un→/ʌn/", "prefix: unlock")
_add("untie", "prefix_un", "un→/ʌn/", "prefix: untie")
_add("unsnap", "prefix_un", "un→/ʌn/", "prefix: unsnap")
_add("unfold", "prefix_un", "un→/ʌn/", "prefix: unfold")
_add("unzip", "prefix_un", "un→/ʌn/", "prefix: unzip")
_add("remake", "prefix_re", "re→/riː/ or /rə/", "prefix: remake")
_add("redo", "prefix_re", "re→/riː/ or /rə/", "prefix: redo")
_add("return", "prefix_re", "re→/riː/ or /rə/", "prefix: return")
_add("restart", "prefix_re", "re→/riː/ or /rə/", "prefix: restart")
_add("rename", "prefix_re", "re→/riː/ or /rə/", "prefix: rename")
_add("reload", "prefix_re", "re→/riː/ or /rə/", "prefix: reload")
_add("disagree", "prefix_dis", "dis→/dɪs/", "prefix: disagree")
_add("disappear", "prefix_dis", "dis→/dɪs/", "prefix: disappear")
_add("disconnect", "prefix_dis", "dis→/dɪs/", "prefix: disconnect")
_add("dislike", "prefix_dis", "dis→/dɪs/", "prefix: dislike")
_add("dismay", "prefix_dis", "dis→/dɪs/", "prefix: dismay")
_add("dishonest", "prefix_dis", "dis→/dɪs/", "prefix: dishonest")
_add("unhappy", "prefix_un", "un→/ʌn/", "prefix: unhappy")
_add("unpack", "prefix_un", "un→/ʌn/", "prefix: unpack")
_add("unknown", "prefix_un", "un→/ʌn/", "prefix: unknown")
_add("unsafe", "prefix_un", "un→/ʌn/", "prefix: unsafe")
_add("reopen", "prefix_re", "re→/riː/ or /rə/", "prefix: reopen")
_add("remove", "prefix_re", "re→/riː/ or /rə/", "prefix: remove")
_add("discover", "prefix_dis", "dis→/dɪs/", "prefix: discover")


# ===== Week 10: Suffixes (-er, -est, -ly, -ful, -less) =====
_add("taller", "suffix_er", "er→/ər/", "suffix: comparative -er")
_add("faster", "suffix_er", "er→/ər/", "suffix: comparative -er (NOT r-controlled)")
_add("smaller", "suffix_er", "er→/ər/", "suffix: comparative -er")
_add("bigger", "suffix_er", "er→/ər/", "suffix: comparative -er")
_add("braver", "suffix_er", "er→/ər/", "suffix: comparative -er")
_add("happier", "suffix_er", "er→/ər/", "suffix: comparative -er")
_add("bravest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
_add("strongest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
_add("tallest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
_add("fastest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
_add("smallest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
_add("biggest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
# Week 17 suffix words:
_add("helper", "suffix_er", "er→/ər/", "suffix: -er, base: help")
_add("player", "suffix_er", "er→/ər/", "suffix: -er, base: play")
_add("brighter", "suffix_er", "er→/ər/", "suffix: -er, base: bright")
_add("happiest", "suffix_est", "est→/ɪst/", "suffix: superlative -est")
_add("quickly", "suffix_ly", "ly→/li/", "suffix: adverb -ly")
_add("slowly", "suffix_ly", "ly→/li/", "suffix: adverb -ly")
_add("happily", "suffix_ly", "ly→/li/", "suffix: adverb -ly")
_add("carefully", "suffix_ly", "ly→/li/", "suffix: adverb -ly")
_add("softly", "suffix_ly", "ly→/li/", "suffix: adverb -ly")
_add("careful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("helpful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("playful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("hopeful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("useful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("careless", "suffix_less", "less→/lɪs/", "suffix: -less")
_add("helpless", "suffix_less", "less→/lɪs/", "suffix: -less")
_add("fearless", "suffix_less", "less→/lɪs/", "suffix: -less")
_add("harmless", "suffix_less", "less→/lɪs/", "suffix: -less")
_add("endless", "suffix_less", "less→/lɪs/", "suffix: -less")
_add("homeless", "suffix_less", "less→/lɪs/", "suffix: -less")


# ===== Week 11: Suffixes (-es, -ed, -ing) =====
_add("boxes", "suffix_es", "es→/əz/", "suffix: plural -es after s/z/x/ch/sh")
_add("wishes", "suffix_es", "es→/ɪz/", "suffix: 3rd person -es")
_add("brushes", "suffix_es", "es→/ɪz/", "suffix: 3rd person -es")
_add("watches", "suffix_es", "es→/ɪz/", "suffix: 3rd person -es")
_add("fixes", "suffix_es", "es→/ɪz/", "suffix: 3rd person -es")
_add("bakes", "suffix_es", "es→/z/", "suffix: 3rd person -es")
_add("walked", "suffix_ed", "ed→/t/", "suffix: past tense -ed after voiceless")
_add("jumped", "suffix_ed", "ed→/t/", "suffix: past tense -ed after voiceless")
_add("cooked", "suffix_ed", "ed→/t/", "suffix: past tense -ed after voiceless")
_add("helped", "suffix_ed", "ed→/t/", "suffix: past tense -ed after voiceless")
_add("played", "suffix_ed", "ed→/d/", "suffix: past tense -ed after voiced")
_add("called", "suffix_ed", "ed→/d/", "suffix: past tense -ed after voiced")
_add("rained", "suffix_ed", "ed→/d/", "suffix: past tense -ed after voiced")
_add("wanted", "suffix_ed", "ed→/ɪd/", "suffix: past tense -ed after t/d")
_add("needed", "suffix_ed", "ed→/ɪd/", "suffix: past tense -ed after t/d")
_add("jumping", "suffix_ing", "ing→/ɪŋ/", "suffix: present participle -ing")
_add("running", "suffix_ing", "ing→/ɪŋ/", "suffix: present participle -ing")
_add("walking", "suffix_ing", "ing→/ɪŋ/", "suffix: present participle -ing")
_add("playing", "suffix_ing", "ing→/ɪŋ/", "suffix: present participle -ing")
_add("singing", "suffix_ing", "ing→/ɪŋ/", "suffix: present participle -ing")
_add("jumps", "suffix_s", "s→/s/", "suffix: 3rd person -s after voiceless")
_add("swimming", "suffix_ing", "ing→/ɪŋ/", "suffix: present participle -ing")
_add("kicks", "suffix_s", "s→/s/", "suffix: 3rd person -s after voiceless")
_add("dances", "suffix_es", "es→/ɪz/", "suffix: 3rd person -es")
_add("painted", "suffix_ed", "ed→/t/", "suffix: past tense -ed")


# ===== Week 12: Homophones =====
_add("there", "homophone", "there/they're/their", "homophone: place vs contraction vs possessive")
_add("their", "homophone", "there/they're/their", "homophone: possessive")
_add("here", "homophone", "here/hear", "homophone: place vs sense")
_add("hear", "homophone", "here/hear", "homophone: sense")
_add("to", "homophone", "to/too/two", "homophone: preposition vs also vs number")
_add("two", "homophone", "to/too/two", "homophone: number")
_add("blue", "homophone", "blue/blew", "homophone: color vs past of blow")
_add("blew", "homophone", "blue/blew", "homophone: past of blow")
_add("write", "homophone", "write/right/rite", "homophone: compose vs correct vs ritual")
_add("right", "homophone", "write/right/rite", "homophone: correct")
_add("sea", "homophone", "sea/see", "homophone: ocean vs vision")
_add("see", "homophone", "sea/see", "homophone: vision")
_add("flour", "homophone", "flour/flower", "homophone: baking vs plant")
_add("mail", "homophone", "mail/male", "homophone: post vs gender")
_add("weather", "homophone", "weather/whether", "homophone: climate vs choice")
_add("whether", "homophone", "weather/whether", "homophone: choice")
_add("night", "homophone", "night/knight", "homophone: dark time vs warrior")
_add("knight", "homophone", "night/knight", "homophone: warrior")
_add("sun", "homophone", "sun/son", "homophone: star vs child")
_add("son", "homophone", "sun/son", "homophone: child")
_add("bear", "homophone", "bear/bare", "homophone: animal vs naked")
_add("bare", "homophone", "bear/bare", "homophone: naked")
_add("hair", "homophone", "hair/hare", "homophone: head vs rabbit")
_add("hare", "homophone", "hair/hare", "homophone: rabbit")
# ===== Week 14: Synonyms (suffix words) =====
_add("beautiful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("enormous", "suffix_ous", "ous→/əs/", "suffix: -ous")
_add("friendly", "suffix_ly", "ly→/li/", "suffix: -ly (adj form)")
_add("amazing", "suffix_ing", "ing→/ɪŋ/", "suffix: -ing")
_add("delicious", "suffix_ious", "ious→/ɪəs/", "suffix: -ious")
_add("grateful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("powerful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("wonderful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("valuable", "suffix_able", "able→/əbəl/", "suffix: -able")
_add("brilliant", "double_consonant", "ll→short_i", "double l")

# ===== Week 15: Antonyms =====
_add("afraid", "irregular", "ai→/ə/ or /eɪ/", "silent f, irregular ai")
_add("famous", "suffix_ous", "ous→/əs/", "suffix: -ous")
_add("gentle", "soft_g_ge", "ge→/dʒ/", "soft g before e")
_add("honest", "irregular", "o→/ɒ/ or /ɑ/", "silent h, irregular")
_add("harmful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("careful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("careless", "suffix_less", "less→/lɪs/", "suffix: -less")
_add("helpful", "suffix_ful", "ful→/fəl/", "suffix: -ful")
_add("unfair", "prefix_un", "un→/ʌn/", "prefix: un-")
_add("unknown", "prefix_un", "un→/ʌn/", "prefix: un-")
_add("brave", "soft_b", "b→/b/", "soft b before a")
_add("rough", "vowel_team_ough", "ough→/ʌf/", "irregular ough")




# ===== Week 7: R-Controlled =====
_add("star", "r_control_ar", "ar→/ɑr/", "r-controlled")
_add("car", "r_control_ar", "ar→/ɑr/", "r-controlled")
_add("farm", "r_control_ar", "ar→/ɑr/", "r-controlled")
_add("bird", "r_control_ir", "ir→/ɝː/", "r-controlled")
_add("nurse", "r_control_ur", "ur→/ɝː/", "r-controlled")
_add("purse", "r_control_ur", "ur→/ɝː/", "r-controlled")
_add("work", "r_control_or", "or→/ɝː/ or /ɜr/", "r-controlled")
_add("fork", "r_control_or", "or→/ɔr/", "r-controlled")
_add("purr", "r_control_ur", "ur→/ɝː/", "r-controlled")
_add("mirror", "r_control_ir", "ir→/ɝː/", "r-controlled")
_add("turtle", "r_control_ur", "ur→/ɝː/ or /ər/", "r-controlled")
_add("purple", "r_control_ur", "ur→/ɝː/", "r-controlled")
_add("market", "r_control_ar", "ar→/ɑr/", "r-controlled")
_add("corner", "r_control_or", "or→/ɔr/", "r-controlled")
_add("farmer", "r_control_ar", "ar→/ɑr/", "r-controlled")
_add("silver", "r_control_er", "er→/ɝː/", "r-controlled")
_add("better", "r_control_er", "er→/ɝː/", "r-controlled")
_add("whether", "homophone", "weather/whether", "homophone: climate vs choice")
_add("her", "r_control_er", "er→/ɝː/", "r-controlled")
_add("whether", "digraph_wh", "wh→/w/", "consonant digraph - also homophone with weather")


# ===== Week 8: Double Consonants =====
_add("butter", "double_consonant", "tt→short_u", "also short_u")
_add("little", "double_consonant", "tt→short_i", "also short_i")
_add("hopper", "double_consonant", "pp→short_o", "also short_o")
_add("muddy", "double_consonant", "dd→short_u", "also short_u")
_add("sitter", "double_consonant", "tt→short_i", "also short_i")
_add("ladder", "double_consonant", "dd→short_a", "also short_a")
_add("bigger", "double_consonant", "gg→short_i", "also short_i")
_add("hugger", "double_consonant", "gg→short_u", "also short_u")
_add("fizzle", "double_consonant", "zz→short_i", "also short_i")
_add("puddle", "double_consonant", "dd→short_u", "also short_u")
_add("summer", "double_consonant", "mm→short_u", "also short_u")
_add("tunnel", "double_consonant", "nn→short_u", "also short_u")
_add("bitter", "double_consonant", "tt→short_i", "also short_i")
_add("cotton", "double_consonant", "tt→short_o", "also short_o")


# ===== Irregular Words =====
_add("father", "digraph_th", "th→/ð/", "also irregular")
_add("believe", "ie_rule", "ie→/iː/", "i before e rule")
_add("receive", "ie_rule", "ei→/iː/", "except after c rule")
_add("said", "irregular", "ai→/ɛ/", "defies 'ai' rule")
_add("friend", "irregular", "ie→/ɛ/", "defies 'ie' rule")
_add("people", "irregular", "pe→/iː/ or /pʃ/", "irregular plural")
_add("enough", "irregular", "ough→/ʌf/", "defies 'ough' rule")
_add("children", "irregular", "ch→/tʃ/, il→/ɪ/", "irregular plural")
_add("together", "digraph_th", "th→/ð/", "also irregular")
_add("because", "irregular", "eau→/ɪkəz/", "defies vowel rules")
_add("through", "irregular", "ough→/uː/", "defies 'ough' rule")


# ===== Compound Words =====
_add("toadstool", "long_o_oa", "oa→/oʊ/", "compound: toad + stool")
_add("boatyard", "long_o_oa", "oa→/oʊ/", "compound: boat + yard")
_add("oatmeal", "long_o_oa", "oa→/oʊ/", "compound: oat + meal")
_add("snowball", "long_o_ow", "ow→/oʊ/", "compound: snow + ball")
_add("snowman", "long_o_ow", "ow→/oʊ/", "compound: snow + man")
_add("outdoor", "long_o_ou", "ou→/aʊ/", "compound: out + door")
_add("trousers", "long_o_ou", "ou→/aʊ/", "also double r")
_add("fountain", "long_o_ou", "ou→/aʊ/", "also n-ct")
_add("mountain", "long_o_ou", "ou→/aʊ/", "also n-ct")
_add("newspaper", "long_u_ew", "ew→/juː/", "compound: news + paper")
_add("feather", "short_e", "ea→/ɛ/", "short e ea pattern — also th digraph + er")


# ===== Week 16: Multiple Meaning Words =====
_add("present", "multiple_meaning", "a gift / to show or demonstrate", "W16 multiple meaning")
_add("falcon", "multiple_meaning", "a bird of prey / a fast aircraft", "W16 multiple meaning")
_add("spring", "multiple_meaning", "a season / a coiled piece of metal", "W16 multiple meaning")
_add("cricket", "multiple_meaning", "a small insect / a sport", "W16 multiple meaning")
_add("record", "multiple_meaning", "a written account / a music disc", "W16 multiple meaning")

# ===== Week 17: Word Families & Root Words =====
_add("teaching", "suffix_ing", "ing→/ɪŋ/", "suffix: -ing, base: teach")
_add("quicker", "suffix_er", "er→/ər/", "suffix: -er, base: quick")
_add("brightest", "suffix_est", "est→/ɪst/", "suffix: -est, base: bright")
_add("kindest", "suffix_est", "est→/ɪst/", "suffix: -est, base: kind")
_add("stronger", "suffix_er", "er→/ər/", "suffix: -er, base: strong")
_add("darkness", "suffix_ness", "ness→/nəs/", "suffix: -ness, base: dark")

# ===== Week 18: Context Clues =====
_add("ancient", "irregular", "a→/eɪ/", "very, very old — irregular long a, not CVCe")
_add("mysterious", "suffix_ious", "ious→/əʃəs/", "suffix: -ious, base: mystery")
_add("tiny", "suffix_y", "y→/i/", "suffix: -y, base: tin")
_add("fragile", "suffix_ile", "ile→/aɪl/", "suffix: -ile, base: frag")
_add("furious", "suffix_ious", "ious→/ɪəs/", "suffix: -ious, base: fury")
_add("nervous", "suffix_ous", "ous→/əs/", "suffix: -ous, base: nerve")
_add("peaceful", "suffix_ful", "ful→/fəl/", "suffix: -ful, base: peace")
_add("terrible", "suffix_ible", "ible→/ɪbəl/", "suffix: -ible, base: terror")
_add("abundant", "short_u", "u→/ʌ/", "multi-syllable: uh-BUN-dant")
_add("cautious", "suffix_ious", "ious→/ʃəs/", "suffix: -ious, base: caut")
_add("reluctant", "short_u", "u→/ʌ/", "multi-syllable: reh-LUK-tant")


def get_word(word: str) -> Optional[WordEntry]:
    """Look up a word in the verified database."""
    return _VERIFIED_WORDS.get(word.lower().strip())


def get_all() -> Dict[str, WordEntry]:
    """Return all verified words."""
    return dict(_VERIFIED_WORDS)


def get_review() -> List[WordEntry]:
    """Get words marked for review."""
    return [w for w in _VERIFIED_WORDS.values() if "review" in w.notes.lower()]


def count() -> int:
    """Return total verified words."""
    return len(_VERIFIED_WORDS)


# Multi-pattern words — words taught from different angles in different weeks.
# Each entry maps word -> list of acceptable patterns.
# Used by audit system to allow multiple valid patterns for the same word.
_MULTI_PATTERN_WORDS: Dict[str, List[str]] = {}


def _add_multi(word: str, patterns: List[str]):
    """Register a word that can have multiple valid patterns."""
    _MULTI_PATTERN_WORDS[word.lower().strip()] = [p.lower() for p in patterns]


def get_multi_patterns(word: str) -> Optional[List[str]]:
    """Get alternative patterns for a multi-pattern word, or None if not multi-pattern."""
    return _MULTI_PATTERN_WORDS.get(word.lower().strip())


# Rainbow: long_a_ai (W3 rain) / long_o_ow (W4 bow)
_add_multi("rainbow", ["long_a_ai", "long_o_ow"])
# Teacher: long_e_ea (W3 ea) / digraph_ch (W5 ch)
_add_multi("teacher", ["long_e_ea", "digraph_ch"])
# Feather: short_e (W7 ea) / r_control_er (W7 er)
_add_multi("feather", ["short_e", "r_control_er"])
# Kitten: short_i (W1) / double_consonant (W13)
_add_multi("kitten", ["short_i", "double_consonant"])
# Winter: short_i (W1) / r_control_er (W13)
_add_multi("winter", ["short_i", "r_control_er"])
# Doctor: short_o (W1) / r_control_or (W13)
_add_multi("doctor", ["short_o", "r_control_or"])
# Multi-meaning words from earlier weeks:
_add_multi("summer", ["double_consonant", "multiple_meaning"])
_add_multi("rocket", ["digraph_ck", "multiple_meaning"])
_add_multi("basket", ["short_a", "multiple_meaning"])
_add_multi("mirror", ["r_control_ir", "multiple_meaning"])
_add_multi("garden", ["short_a", "multiple_meaning"])
_add_multi("fountain", ["long_o_ou", "multiple_meaning"])
_add_multi("mountain", ["long_o_ou", "multiple_meaning"])