from typing import List, Literal, Optional, Tuple, TypedDict

Category = Literal[
    "animal",
    "color",
    "transport",
    "pokemon",
    "technology",
    "profession",
    "thing",
    "quantity",
    "size",
    "emotion",
    "condition",
]

WordEntry = Tuple[str, List[Category]]


class Vocabulary(TypedDict):
    nouns: List[WordEntry]
    adjectives: List[WordEntry]


vocabulary_kwargs = {
    "nouns": [
        ("tiger", ["animal", "color"]),
        ("elephant", ["animal", "color"]),
        ("camel", ["animal"]),
        ("giraffe", ["animal"]),
        ("elephant", ["animal"]),
        ("otter", ["animal"]),
        ("mongoose", ["animal"]),
        ("porcupine", ["animal"]),
        ("jaguar", ["animal"]),
        ("gorilla", ["animal"]),
        ("koala", ["animal"]),
        ("meerkat", ["animal"]),
        ("ocelot", ["animal"]),
        ("buffalo", ["animal"]),
        ("platypus", ["animal"]),
        ("anteater", ["animal"]),
        ("armadillo", ["animal"]),
        ("cheetah", ["animal"]),
        ("chameleon", ["animal"]),
        ("cat", ["animal"]),
        ("lion", ["animal"]),
        ("walrus", ["animal"]),
        ("quokka", ["animal"]),
        ("lynx", ["animal"]),
        ("sloth", ["animal"]),
        ("wolverine", ["animal"]),
        ("lemur", ["animal"]),
        ("carvan", ["transport"]),
        ("boat", ["transport"]),
        ("plane", ["transport"]),
        ("train", ["transport"]),
        ("bicycle", ["transport"]),
        ("motorcycle", ["transport"]),
        ("scooter", ["transport"]),
        ("skateboard", ["transport"]),
        ("car", ["transport"]),
        ("truck", ["transport"]),
        ("bus", ["transport"]),
        ("subway", ["transport"]),
        ("helicopter", ["transport"]),
        ("rocket", ["transport"]),
        ("spaceship", ["transport"]),
        ("tractor", ["transport"]),
        ("golfcart", ["transport"]),
        ("segway", ["transport"]),
        ("pikachu", ["pokemon"]),
        ("charmander", ["pokemon"]),
        ("bulbasaur", ["pokemon"]),
        ("squirtle", ["pokemon"]),
        ("snorlax", ["pokemon"]),
        ("mewtwo", ["pokemon"]),
        ("mew", ["pokemon"]),
        ("articuno", ["pokemon"]),
        ("zapdos", ["pokemon"]),
        ("moltres", ["pokemon"]),
        ("raikou", ["pokemon"]),
        ("entei", ["pokemon"]),
        ("suicune", ["pokemon"]),
        ("lugia", ["pokemon"]),
        ("celebi", ["pokemon"]),
        ("rayquaza", ["pokemon"]),
        ("jirachi", ["pokemon"]),
        ("deoxys", ["pokemon"]),
        ("uxie", ["pokemon"]),
        ("mesprit", ["pokemon"]),
        ("azelf", ["pokemon"]),
        ("dialga", ["pokemon"]),
        ("palkia", ["pokemon"]),
        ("heatran", ["pokemon"]),
        ("giratina", ["pokemon"]),
        ("cpu", ["technology"]),
        ("gpu", ["technology"]),
        ("ram", ["technology"]),
        ("rom", ["technology"]),
        ("ssd", ["technology"]),
        ("hdd", ["technology"]),
        ("usb", ["technology"]),
        ("hdmi", ["technology"]),
        ("vga", ["technology"]),
        ("dvi", ["technology"]),
        ("ethernet", ["technology"]),
        ("bluetooth", ["technology"]),
        ("floppy", ["technology"]),
        ("zip", ["technology"]),
        ("vhs", ["technology"]),
        ("cassette", ["technology"]),
        ("vinyl", ["technology"]),
        ("floppy", ["technology"]),
        ("laserdisc", ["technology"]),
        ("scientist", ["profession"]),
        ("doctor", ["profession"]),
        ("engineer", ["profession"]),
        ("programmer", ["profession"]),
        ("teacher", ["profession"]),
        ("professor", ["profession"]),
        ("student", ["profession"]),
        ("nurse", ["profession"]),
        ("artist", ["profession"]),
        ("musician", ["profession"]),
        ("actor", ["profession"]),
        ("actress", ["profession"]),
        ("singer", ["profession"]),
        ("dancer", ["profession"]),
        ("chef", ["profession"]),
        ("firefighter", ["profession"]),
        ("police", ["profession"]),
        ("officer", ["profession"]),
        ("soldier", ["profession"]),
        ("pilot", ["profession"]),
        ("astronaut", ["profession"]),
        ("lawyer", ["profession"]),
        ("judge", ["profession"]),
        ("politician", ["profession"]),
        ("president", ["profession"]),
        ("king", ["profession"]),
        ("queen", ["profession"]),
        ("prince", ["profession"]),
        ("princess", ["profession"]),
        ("emperor", ["profession"]),
        ("empress", ["profession"]),
        ("dictator", ["profession"]),
        ("tyrant", ["profession"]),
        ("pharaoh", ["profession"]),
        ("sultan", ["profession"]),
        ("shogun", ["profession"]),
        ("samurai", ["profession"]),
        ("ninja", ["profession"]),
        ("pirate", ["profession"]),
        ("viking", ["profession"]),
        ("knight", ["profession"]),
        ("wizard", ["profession"]),
        ("witch", ["profession"]),
        ("sorcerer", ["profession"]),
        ("warlock", ["profession"]),
        ("cleric", ["profession"]),
        ("monk", ["profession"]),
        ("bard", ["profession"]),
        ("druid", ["profession"]),
        ("ranger", ["profession"]),
        ("paladin", ["profession"]),
        ("barbarian", ["profession"]),
        ("fighter", ["profession"]),
        ("rogue", ["profession"]),
        ("thief", ["profession"]),
        ("assassin", ["profession"]),
        ("necromancer", ["profession"]),
        ("alchemist", ["profession"]),
        ("blacksmith", ["profession"]),
        ("merchant", ["profession"]),
        ("farmer", ["profession"]),
        ("hunter", ["profession"]),
        ("fisherman", ["profession"]),
        ("lumberjack", ["profession"]),
        ("shoe", ["thing"]),
        ("sock", ["thing"]),
        ("shirt", ["thing"]),
        ("pants", ["thing"]),
        ("shorts", ["thing"]),
        ("skirt", ["thing"]),
        ("dress", ["thing"]),
        ("suit", ["thing"]),
        ("tie", ["thing"]),
        ("bowtie", ["thing"]),
        ("scarf", ["thing"]),
        ("gloves", ["thing"]),
        ("mittens", ["thing"]),
        ("hat", ["thing"]),
        ("cap", ["thing"]),
        ("helmet", ["thing"]),
        ("glasses", ["thing"]),
        ("sunglasses", ["thing"]),
        ("watch", ["thing"]),
        ("bracelet", ["thing"]),
        ("necklace", ["thing"]),
        ("earrings", ["thing"]),
        ("ring", ["thing"]),
        ("belt", ["thing"]),
        ("wallet", ["thing"]),
        ("purse", ["thing"]),
        ("backpack", ["thing"]),
        ("bag", ["thing"]),
        ("suitcase", ["thing"]),
        ("briefcase", ["thing"]),
        ("book", ["thing"]),
        ("notebook", ["thing"]),
        ("journal", ["thing"]),
        ("diary", ["thing"]),
        ("calendar", ["thing"]),
        ("planner", ["thing"]),
        ("pen", ["thing"]),
        ("pencil", ["thing"]),
        ("marker", ["thing"]),
        ("highlighter", ["thing"]),
        ("eraser", ["thing"]),
        ("ruler", ["thing"]),
        ("scissors", ["thing"]),
        ("tape", ["thing"]),
        ("glue", ["thing"]),
        ("stapler", ["thing"]),
        ("paper", ["thing"]),
        ("envelope", ["thing"]),
        ("folder", ["thing"]),
        ("file", ["thing"]),
        ("computer", ["thing"]),
        ("laptop", ["thing"]),
        ("tablet", ["thing"]),
        ("phone", ["thing"]),
        ("smartphone", ["thing"]),
        ("smartwatch", ["thing"]),
        ("headphones", ["thing"]),
        ("earbuds", ["thing"]),
        ("speaker", ["thing"]),
        ("microphone", ["thing"]),
        ("camera", ["thing"]),
        ("television", ["thing"]),
        ("monitor", ["thing"]),
        ("keyboard", ["thing"]),
        ("mouse", ["thing"]),
        ("trackpad", ["thing"]),
    ],
    "adjectives": [
        ("blue", ["color"]),
        ("green", ["color"]),
        ("purple", ["color"]),
        ("orange", ["color"]),
        ("black", ["color"]),
        ("white", ["color"]),
        ("gray", ["color"]),
        ("brown", ["color"]),
        ("pink", ["color"]),
        ("tan", ["color"]),
        ("cyan", ["color"]),
        ("magenta", ["color"]),
        ("olive", ["color"]),
        ("maroon", ["color"]),
        ("navy", ["color"]),
        ("aquamarine", ["color"]),
        ("turquoise", ["color"]),
        ("silver", ["color"]),
        ("lime", ["color"]),
        ("teal", ["color"]),
        ("indigo", ["color"]),
        ("violet", ["color"]),
        ("red", ["color"]),
        ("yellow", ["color"]),
        ("abundant", ["quantity"]),
        ("ample", ["quantity"]),
        ("bountiful", ["quantity"]),
        ("copious", ["quantity"]),
        ("countless", ["quantity"]),
        ("endless", ["quantity"]),
        ("enough", ["quantity"]),
        ("excessive", ["quantity"]),
        ("few", ["quantity"]),
        ("infinite", ["quantity"]),
        ("many", ["quantity"]),
        ("numerous", ["quantity"]),
        ("plentiful", ["quantity"]),
        ("sufficient", ["quantity"]),
        ("surplus", ["quantity"]),
        ("unlimited", ["quantity"]),
        ("massive", ["size"]),
        ("tiny", ["size"]),
        ("small", ["size"]),
        ("medium", ["size"]),
        ("large", ["size"]),
        ("huge", ["size"]),
        ("gigantic", ["size"]),
        ("enormous", ["size"]),
        ("minuscule", ["size"]),
        ("microscopic", ["size"]),
        ("massive", ["size"]),
        ("giant", ["size"]),
        ("titanic", ["size"]),
        ("colossal", ["size"]),
        ("immense", ["size"]),
        ("monstrous", ["size"]),
        ("vast", ["size"]),
        ("tremendous", ["size"]),
        ("angry", ["emotion"]),
        ("happy", ["emotion"]),
        ("sad", ["emotion"]),
        ("excited", ["emotion"]),
        ("bored", ["emotion"]),
        ("scared", ["emotion"]),
        ("surprised", ["emotion"]),
        ("confused", ["emotion"]),
        ("disgusted", ["emotion"]),
        ("embarrassed", ["emotion"]),
        ("envious", ["emotion"]),
        ("frightened", ["emotion"]),
        ("guilty", ["emotion"]),
        ("jealous", ["emotion"]),
        ("lonely", ["emotion"]),
        ("proud", ["emotion"]),
        ("shy", ["emotion"]),
        ("tired", ["emotion"]),
        ("worried", ["emotion"]),
        ("anxious", ["emotion"]),
        ("ashamed", ["emotion"]),
        ("bored", ["emotion"]),
        ("calm", ["emotion"]),
        ("content", ["emotion"]),
        ("delighted", ["emotion"]),
        ("ecstatic", ["emotion"]),
        ("elated", ["emotion"]),
        ("euphoric", ["emotion"]),
        ("exhilarated", ["emotion"]),
        ("glad", ["emotion"]),
        ("joyful", ["emotion"]),
        ("jubilant", ["emotion"]),
        ("lively", ["emotion"]),
        ("merry", ["emotion"]),
        ("overjoyed", ["emotion"]),
        ("peaceful", ["emotion"]),
        ("pleased", ["emotion"]),
        ("radiant", ["emotion"]),
        ("satisfied", ["emotion"]),
        ("serene", ["emotion"]),
        ("thrilled", ["emotion"]),
        ("upbeat", ["emotion"]),
        ("vibrant", ["emotion"]),
        ("zestful", ["emotion"]),
        ("zesty", ["emotion"]),
        ("zippy", ["emotion"]),
        ("broken", ["condition"]),
        ("clean", ["condition"]),
        ("dirty", ["condition"]),
        ("empty", ["condition"]),
        ("full", ["condition"]),
        ("hot", ["condition"]),
        ("cold", ["condition"]),
        ("wet", ["condition"]),
        ("dry", ["condition"]),
        ("fast", ["condition"]),
        ("slow", ["condition"]),
        ("hard", ["condition"]),
        ("soft", ["condition"]),
        ("heavy", ["condition"]),
        ("light", ["condition"]),
        ("noisy", ["condition"]),
        ("quiet", ["condition"]),
        ("bright", ["condition"]),
        ("dark", ["condition"]),
        ("thick", ["condition"]),
        ("thin", ["condition"]),
        ("sharp", ["condition"]),
        ("dull", ["condition"]),
        ("smooth", ["condition"]),
        ("rough", ["condition"]),
        ("sweet", ["condition"]),
        ("sour", ["condition"]),
        ("bitter", ["condition"]),
        ("salty", ["condition"]),
        ("spicy", ["condition"]),
        ("savory", ["condition"]),
        ("tangy", ["condition"]),
        ("tart", ["condition"]),
        ("mild", ["condition"]),
        ("hot", ["condition"]),
        ("cold", ["condition"]),
        ("warm", ["condition"]),
        ("cool", ["condition"]),
        ("icy", ["condition"]),
        ("frozen", ["condition"]),
        ("boiling", ["condition"]),
        ("scalding", ["condition"]),
        ("steaming", ["condition"]),
        ("roasting", ["condition"]),
        ("toasty", ["condition"]),
        ("chilly", ["condition"]),
        ("freezing", ["condition"]),
        ("frosty", ["condition"]),
        ("frigid", ["condition"]),
        ("arctic", ["condition"]),
        ("polar", ["condition"]),
        ("tropical", ["condition"]),
        ("subtropical", ["condition"]),
        ("temperate", ["condition"]),
        ("mild", ["condition"]),
        ("moderate", ["condition"]),
        ("extreme", ["condition"]),
        ("severe", ["condition"]),
        ("intense", ["condition"]),
        ("harsh", ["condition"]),
        ("brutal", ["condition"]),
        ("cruel", ["condition"]),
        ("merciless", ["condition"]),
        ("unrelenting", ["condition"]),
        ("unforgiving", ["condition"]),
    ],
}

vocabulary = Vocabulary(**vocabulary_kwargs)


def get_words_by_category(
    part_of_speech: str, categories: Optional[List[Category]] = None
) -> List[WordEntry]:
    words = []
    for word, word_categories in vocabulary[part_of_speech]:
        if categories:
            # check if any of the categories are in word_categories
            if any(category in word_categories for category in categories):
                words.append(word)
        else:
            words.append(word)

    return words
