"""Generate reviewed-draft semantic specifications for every speech concept."""

from __future__ import annotations

import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1] / "content" / "speech"
PLAN = json.loads((ROOT / "plan" / "content-plan.json").read_text(encoding="utf-8"))
CONCEPTS = {c["key"]: c for c in PLAN["concepts"]}

MEANING = {
"apple":"An edible apple fruit: the round or slightly lobed firm fruit of an apple tree, whole or recognizably cut.",
"banana":"An edible banana fruit: elongated and curved, with peel or recognizably peeled flesh.",
"orange_fruit":"An edible orange citrus fruit, whole or recognizably segmented; this excludes the colour and juice alone.",
"water":"Plain water as a drink or visible substance, independent of container, source or temperature.",
"milk":"Drinkable animal or plant milk presented as milk; the concept is the liquid, not its package.",
"juice":"A drink made from fruit or vegetables, shown as liquid with sufficient contextual evidence to distinguish it from water or milk.",
"ball":"A portable rounded object intended for rolling, throwing, catching or kicking.",
"doll":"A toy representation of a person or baby intended for pretend play.",
"car_toy":"A small toy representation of a car intended for play, not a rideable or full-size vehicle.",
"cup":"An open-topped drinking vessel sized to be held, with or without a handle.",
"spoon":"A handheld utensil with a shallow bowl and handle used for scooping, stirring or eating.",
"shoe":"Footwear worn on a foot, excluding socks and other clothing.",
"shirt":"An upper-body garment with a neck opening and sleeves or arm openings.",
"book":"A bound or digitally represented sequence of pages intended for reading or viewing; teaching media should normally show a physical book.",
"mother":"The learner's mother or a primary caregiver who occupies that family role; identity is relationship-based, not appearance-based.",
"father":"The learner's father or a primary caregiver who occupies that family role; identity is relationship-based, not appearance-based.",
"child":"A young person, represented across ages, bodies, cultures and communication profiles without inferring a specific family role.",
"therapist":"A qualified or supervised helping professional participating in a therapeutic session; role must be established by context rather than clothing alone.",
"eat":"Taking food into the mouth and consuming it, including culturally varied foods and safe adaptive methods.",
"drink":"Taking a liquid into the mouth from a suitable vessel or approved support.",
"sleep":"A state of natural sleep, distinguished from resting, pretending, unconsciousness or illness.",
"play":"Voluntary enjoyable engagement with toys, games, movement, imagination or social partners.",
"give":"Intentionally transferring or offering an item to another person so the other person can receive it.",
"wash":"Cleaning a body part or object using water or another appropriate cleaning method.",
"cut":"Dividing material with an appropriate cutting tool or safe adapted method.",
"open":"Changing something from closed to accessible, uncovered or allowing passage.",
"close":"Changing something from open to shut, covered or blocking passage.",
"want":"Communicating desire or preference for an item, action, person or continuation; it does not imply entitlement or consent from others.",
"more":"An additional amount or continuation relative to an established amount or event.",
"help":"Requesting or providing assistance toward a task or need while respecting autonomy.",
"finished":"Communicating that an item, activity, turn or routine has ended or that the communicator wants it to end.",
"yes":"An affirmative response indicating agreement, confirmation or acceptance in the current context.",
"no":"A negative response indicating disagreement, rejection, refusal or absence in the current context.",
"stop":"A directive or request for an action, interaction or movement to cease immediately.",
"hello":"A culturally appropriate act that opens or acknowledges a social interaction.",
"goodbye":"A culturally appropriate act that closes or marks departure from a social interaction.",
"dog":"A domestic dog across breeds, sizes, ages and safe real or representational examples.",
"cat":"A domestic cat across breeds, sizes, ages and safe real or representational examples.",
"hand":"The body part at the end of the arm, including palm, back, fingers and thumb; include natural limb differences and prostheses as appropriate.",
"foot":"The body part at the end of the leg used for standing or movement; include natural limb differences and prostheses as appropriate.",
"mouth":"The external and visible oral region including lips and oral opening, without requiring invasive internal views.",
"eye":"The organ and visible eye region used for vision, represented without assuming eye contact or typical vision.",
"big":"Relatively larger in a stated comparison set or context; not an absolute property.",
"small":"Relatively smaller in a stated comparison set or context; not an absolute property.",
"red":"The red colour attribute applied to otherwise varied objects; colour must be the only controlled difference in teaching contrasts.",
"green":"The green colour attribute applied to otherwise varied objects; colour must be the only controlled difference in teaching contrasts.",
"blue":"The blue colour attribute applied to otherwise varied objects; colour must be the only controlled difference in teaching contrasts.",
"in":"A spatial relation in which the target is inside or enclosed by a reference container or boundary.",
"on":"A spatial relation in which the target is supported by and in contact with the upper or functional surface of a reference object.",
"under":"A spatial relation in which the target is lower than and vertically aligned with a reference object, usually beneath it.",
"one":"A quantity set containing exactly one target item.",
"all":"Every member of the defined relevant set, with none of that set omitted.",
"none":"Zero members of the defined relevant set; absence must be shown without hiding or ambiguity.",
"home":"A place where a person lives or experiences home, independent of building type, ownership or family structure.",
"school":"A place or organized setting for learning, including varied accessible school environments.",
"clinic":"A healthcare or therapy setting identified by its function and activity, not uniforms or medical symbols alone.",
"happy":"A positive emotional state commonly indicated by congruent facial, body and contextual cues; expression varies across people.",
"sad":"An unpleasant emotional state associated with loss or disappointment, indicated by congruent facial, body and contextual cues without requiring tears.",
"snack_time":"A familiar routine involving preparation, eating or drinking a small amount between main meals, followed by an appropriate finish or cleanup.",
"hand_washing":"The ordered hygiene routine of wetting hands, applying soap, rubbing all hand surfaces, rinsing and drying safely."
}

CONFUSIONS = {
"apple":["orange_fruit","ball"],"banana":["apple","orange_fruit"],"orange_fruit":["apple","juice"],
"water":["milk","juice"],"milk":["water","juice"],"juice":["water","milk","orange_fruit"],
"ball":["orange_fruit","doll","car_toy"],"doll":["child","car_toy"],"car_toy":["ball","doll"],
"cup":["glass or bowl not represented as an approved concept","spoon"],"spoon":["cup","fork or ladle"],
"shoe":["foot","shirt"],"shirt":["shoe","jacket or dress"],"book":["tablet or notebook","closed box"],
"mother":["father","therapist"],"father":["mother","therapist"],"child":["mother","father","therapist"],"therapist":["mother","father","teacher or doctor"],
"eat":["drink","play"],"drink":["eat","wash"],"sleep":["resting or pretending","unconsciousness"],"play":["work task","eat","sleep"],
"give":["take","show or hold"],"wash":["drink","wipe without cleaning"],"cut":["tear or break","pretend tool use"],"open":["close","already open"],"close":["open","already closed"],
"want":["like or have","request already fulfilled"],"more":["one","all","same amount"],"help":["doing it without consent","attention only"],"finished":["pause","stop before completion"],
"yes":["no","repetition without agreement"],"no":["yes","none"],"stop":["finished","no","pause"],"hello":["goodbye","unrelated wave"],"goodbye":["hello","unrelated wave"],
"dog":["cat","toy dog or wolf"],"cat":["dog","toy cat or wild feline"],
"hand":["foot","arm"],"foot":["hand","leg","shoe"],"mouth":["eye","nose"],"eye":["mouth","eyeglasses"],
"big":["small","nearer camera"],"small":["big","farther camera"],"red":["green","blue","orange"],"green":["red","blue"],"blue":["red","green"],
"in":["on","under","behind"],"on":["in","under","above without contact"],"under":["in","on","behind"],
"one":["more","all","none"],"all":["one","more","none","subset"],"none":["one","all","hidden items"],
"home":["school","clinic","hotel"],"school":["home","clinic","library"],"clinic":["home","school","office"],
"happy":["sad","excited","neutral"],"sad":["happy","tired","angry"],"snack_time":["main meal","food preparation only","play time"],"hand_washing":["rinsing only","washing an object","hand drying only"]
}

OPPOSITES = {"big":"small","small":"big","open":"close","close":"open","yes":"no","no":"yes","hello":"goodbye","goodbye":"hello","happy":"sad","sad":"happy","all":"none","none":"all"}
SAFETY = {
"eat":"Use developmentally safe food sizes and positions; never depict choking or forced feeding.","drink":"Use safe vessels and positioning; do not depict unsafe liquids or forced drinking.",
"cut":"Use age-appropriate tools, stable surfaces and supervision; never depict blades directed toward a person.","wash":"Avoid scalding water, chemicals, wet-floor hazards and coercive hygiene.",
"hand_washing":"Show safe water temperature, stable access, soap, rinse and dry; avoid wet floors and coercion.",
"dog":"Use calm supervised animals; avoid bites, fear or unsafe approach behavior.","cat":"Use calm supervised animals; avoid scratches, fear or unsafe handling.",
"mouth":"Avoid invasive close-ups, pain, dental procedures and forced imitation.","eye":"Do not require eye contact; include visual disability respectfully and avoid injury imagery.",
"mother":"Use the learner's chosen caregiver labels; never infer gender, biology or family role from appearance.","father":"Use the learner's chosen caregiver labels; never infer gender, biology or family role from appearance.",
"child":"Represent disability, culture and body variation respectfully; no identifiable learner media without consent.","therapist":"Avoid white-coat stereotyping, restraint, forced compliance or identifiable clinical records.",
"want":"Honor refusal and consent; wanting does not authorize taking or contact.","help":"Ask permission before physical assistance whenever possible; preserve independent attempts.",
"no":"Treat every accessible refusal as meaningful and do not train automatic compliance.","stop":"Treat stop as an immediately honored safety communication across all response modes.",
"happy":"Do not demand smiles or infer wellbeing from eye contact; use multiple congruent cues.","sad":"Do not require tears or depict crisis; use gentle everyday contexts and multiple cues.",
"snack_time":"Use allergy-aware, culturally appropriate, developmentally safe foods; avoid food as coercive reward.",
}

TYPE_INCLUSIONS = {
"object":["real examples with natural variation","recognizable photographs or approved representations","different viewpoints and everyday contexts"],
"person":["role-consistent examples across cultures and bodies","familiar and unfamiliar people when the relationship or role is established","accessible communication and mobility differences"],
"action":["a visible actor and observable target action","different actors, objects and settings that preserve the action","a clear start or result when needed to disambiguate motion"],
"social_word":["the communicative intent plus a partner or consequence","gesture, sign, AAC, vocalization or speech forms","culturally and contextually appropriate variants"],
"quantity":["a clearly bounded comparison or reference set","different object types and spatial arrangements","examples where quantity is not cued by colour or position"],
"body_part":["the part on self, another person, model or illustration","natural anatomical variation and appropriate assistive devices","multiple viewpoints without distress"],
"attribute":["controlled comparisons where only the target attribute changes","varied objects and contexts","examples independent of camera distance or lighting"],
"preposition":["a visible target and reference object","controlled spatial contrasts","multiple viewpoints that preserve the relation"],
"location":["interior, exterior and activity cues that jointly establish place","culturally and physically varied examples","accessible versions of the setting"],
"emotion":["congruent facial, posture and contextual cues","subtle and stronger everyday expressions","variation across age, culture and disability"],
"routine":["recognizable beginning, middle and end states","safe variants across people and places","sequence examples and functional participation"]
}

def concept_path(c): return ROOT / "concepts" / Path(*c["category"].split(".")) / c["key"]

def relation_records(c):
    out=[{"type":"member_of_group","target_key":g} for g in c["groups"]]
    if c["key"] in OPPOSITES: out.append({"type":"semantic_contrast","target_key":OPPOSITES[c["key"]]})
    for x in CONFUSIONS[c["key"]]:
        if x in CONCEPTS: out.append({"type":"commonly_confused_with","target_key":x})
    return out

def distractors(c):
    conf=CONFUSIONS[c["key"]]
    known=[x for x in conf if x in CONCEPTS]
    clear=[x for x,v in CONCEPTS.items() if x!=c["key"] and v["type"]!=c["type"] and x not in known][:3]
    return {
      "level_1_clear_contrast":{"candidates":clear,"rule":"Use visually and semantically unrelated choices; match size, crop, background and salience."},
      "level_2_near_contrast":{"candidates":conf,"rule":"Introduce same-category or functionally similar choices only after clear-contrast success."},
      "level_3_advanced":{"rule":"Use novel exemplars, richer contexts and balanced positions; remove colour, scale, actor, container and background shortcuts."},
      "prohibited_cues":["target always in the same position","target uniquely larger or brighter","written label reveals answer","only target has audio or animation","distractor is unsafe, frightening or culturally demeaning"]
    }

def exclusions(c):
    base=[f"an ambiguous or substantially hidden example of {c['name'].lower()}","a written word, icon or logo without a meaningful exemplar","a scene where position, colour, size or background reveals the answer"]
    return CONFUSIONS[c["key"]]+base

updated=0
for c in PLAN["concepts"]:
    record={
      "schema_version":1,"concept_key":c["key"],"concept_type":c["type"],"category":c["category"],
      "semantic_intent":"language_independent_concept_definition","meaning":MEANING[c["key"]],
      "counts_as":TYPE_INCLUSIONS[c["type"]],"does_not_count_as":exclusions(c),
      "relations":relation_records(c),"distractor_rules":distractors(c),
      "ambiguity_controls":["teach meaning before labels","vary irrelevant visual features","require at least two exemplars before mastery","score prompts separately from correctness","probe with an unseen exemplar"],
      "safety_and_cultural_notes":[SAFETY.get(c["key"],"Use safe everyday contexts, respectful representation and culturally familiar alternatives; avoid stereotypes and coercion."),"Localize from semantic intent rather than translating the English label literally.","Clinical and native-language/cultural review are required before approval."],
      "review":{"status":"draft_needs_slp_and_cultural_review","required_reviewers":["speech_language_professional","accessibility_reviewer","native_language_or_cultural_reviewer"]}
    }
    p=concept_path(c)/"semantic-definition.json"; text=json.dumps(record,ensure_ascii=False,indent=2)+"\n"
    if not p.exists() or p.read_text(encoding="utf-8")!=text: p.write_text(text,encoding="utf-8"); updated+=1
print(f"Semantic definitions ready: {len(PLAN['concepts'])} concepts; {updated} files updated")
