"""Build draft parts and timing studies from preserved artbook SVGs. Stdlib only."""
from pathlib import Path
import copy,json,xml.etree.ElementTree as ET
NS='http://www.w3.org/2000/svg'; ET.register_namespace('',NS)
ROOT=Path(__file__).resolve().parents[3]
OUT=Path(__file__).resolve().parent
EDITION=OUT.parent
q=lambda n:'{'+NS+'}'+n

def find(root,cls):
    return next((e for e in root.iter() if cls in e.get('class','').split()),None)
def detach(root,cls):
    e=find(root,cls)
    if e is not None:
        for p in root.iter():
            if e in list(p):p.remove(e);break
    return e

def root_for(src):
    r=ET.Element(q('svg'),{'viewBox':'0 0 240 240','width':'240','height':'240','role':'img'})
    r.append(copy.deepcopy(src.find(q('defs'))))
    return r

css='''.guide-body{transform-origin:120px 223px;animation:breathe 5s ease-in-out infinite}.guide-head{transform-origin:120px 130px}.guide-arm-left{transform-origin:82px 142px}.guide-arm-right{transform-origin:155px 142px}.guide-eyes{transform-box:fill-box;transform-origin:center;animation:blink 6.4s infinite}.state-thinking .guide-head{animation:think 3.6s ease-in-out infinite}.state-thinking .guide-arm-right{transform:rotate(-24deg)}.state-working .guide-arm-left{animation:point 2.8s ease-in-out infinite}.state-writing .guide-arm-left{animation:write 2.4s ease-in-out infinite}.state-writing .guide-head{transform:rotate(4deg)}.state-celebrate .guide-arm-right{animation:cheer 1.8s ease-in-out 1}.state-rest .guide-head{transform:rotate(5deg)}.state-rest .guide-eyes{animation:none;transform:scaleY(.12)}.state-rest .guide-body{animation-duration:6s}@keyframes breathe{50%{transform:scaleY(1.008)}}@keyframes blink{0%,44%,48%,100%{transform:scaleY(1)}46%{transform:scaleY(.08)}}@keyframes think{40%,70%{transform:rotate(-7deg)}}@keyframes point{30%,60%{transform:rotate(7deg)}}@keyframes write{15%,40%,65%{transform:rotate(3deg)}25%,50%,75%{transform:rotate(-2deg)}}@keyframes cheer{25%,60%{transform:rotate(-65deg)}40%,75%{transform:rotate(-45deg)}}@media(prefers-reduced-motion:reduce){svg *{animation:none!important}}'''

for name in ['summit','ridge','terra']:
    src=ET.parse(ROOT/'characters'/name/'idle.svg').getroot()
    folder=OUT/name;folder.mkdir(exist_ok=True)
    body=find(src,'guide-body')
    base=copy.deepcopy(body)
    parts={}
    for cls,key in [('guide-head','head'),('guide-arm-left','arm-character-right'),('guide-arm-right','arm-character-left'),('guide-legs','legs')]:
        parts[key]=detach(base,cls)
    parts['torso']=base
    head=parts['head']
    for cls,key in [('guide-eyes','eyes'),('guide-mouth','mouth'),('guide-goggles','goggles')]:
        part=detach(head,cls)
        if part is not None:parts[key]=part
    arm=parts['arm-character-right']
    gear=detach(arm,'guide-gear')
    if gear is not None:parts['gear']=gear
    # Restore stroke style inherited from body for independent parts.
    for key,part in parts.items():
        r=root_for(src);r.set('aria-label',name+' draft '+key)
        title=ET.SubElement(r,q('title'));title.text=name+' — draft vector part: '+key
        wrapper=ET.SubElement(r,q('g'),{k:v for k,v in body.attrib.items() if k!='class'})
        wrapper.append(copy.deepcopy(part))
        ET.ElementTree(r).write(folder/(key+'.svg'),encoding='unicode')
    rig={ 'status':'draft-vector-timing-kit', 'source':f'../../../../characters/{name}/idle.svg', 'canvas':[240,240], 'coordinateSystem':'SVG pixels; x right, y down', 'leftRight':'character side; front view reverses screen side', 'pivots':{'torso':[120,208],'head':[120,130],'arm-character-right':[82,142],'arm-character-left':[155,142],'legs':[120,194],'eyes':[120,94],'mouth':[120,118],'goggles':[120,84],'gear':[57,163]}, 'layerOrder':['legs','torso','gear','arm-character-right','arm-character-left','head','goggles','eyes','mouth'], 'limits':['Arms include hands; legs are paired.','Head includes clothing and headwear.','No hidden surfaces or 3D geometry.','Ridge rope is still part of torso.','Do not use these as approved soft 3D assets.']}
    (folder/'joints.json').write_text(json.dumps(rig,indent=2)+'\n')
    motions=EDITION/'motion'/name;motions.mkdir(exist_ok=True)
    for state in ['idle','thinking','working','writing','celebrate','rest']:
        r=copy.deepcopy(src); r.set('class','guide state-'+state);r.set('data-guide-state',state)
        r.find(q('style')).text=css
        for cls in ['guide-shadow','guide-sparkles']:detach(r,cls)
        if state in ['working','writing','celebrate']:detach(r,'guide-gear')
        if state in ['working','writing']:
            b=find(r,'guide-body');prop=ET.Element(q('g'),{'id':'map' if state=='working' else 'journal','stroke':'#394A43','stroke-width':'2'})
            ET.SubElement(prop,q('rect'),{'x':'72','y':'164','width':'71','height':'28','rx':'3','fill':'#EFE4CC'})
            ET.SubElement(prop,q('path'),{'d':'M108 166V190 M82 173H100 M115 178H134','fill':'none','stroke':'#9F987F'})
            b.insert(list(b).index(find(r,'guide-arm-left')),prop)
            ar=find(r,'guide-arm-left')
            ET.SubElement(ar,q('path'),{'d':'M61 159L92 179','stroke':'#D5A35D','stroke-width':'4'})
        ET.ElementTree(r).write(motions/(state+'.svg'),encoding='unicode')
print('Built three draft parts kits and 18 motion SVGs.')
