import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE','config.settings'); django.setup()
from apps.editor.models import Project, TranscriptWord
p=Project.objects.get(id=26)
ed=p.editor_draft if isinstance(p.editor_draft,dict) else {}
for s in ed.get('sequences',[]):
    if s.get('id')!='seq-mokn6aji-thematic-4-5-ksho': continue
    sid=s['id']
    print('visualSplitPoints:', s.get('visualSplitPoints'))
    print('customSplitPoints:', s.get('customSplitPoints'))
    print('customStartPoints:', s.get('customStartPoints'))
    print('customEndPoints:', s.get('customEndPoints'))
    print('breakAfterWordIds:', s.get('breakAfterWordIds'))
    print('collapsedGapWordIds:', s.get('collapsedGapWordIds'))
    print('movedBlockIds:', s.get('movedBlockIds'))
    print('hookMovedToStart:', s.get('hookMovedToStart'))
    print('hookLoopTailEnabled:', s.get('hookLoopTailEnabled'), s.get('hook_loop_tail_enabled'))
    print('hookFrontEnabled:', s.get('hookFrontEnabled'))
    print()
    print('visualBlockOrderIds:')
    for b in s.get('visualBlockOrderIds') or []:
        print(' ', b)
    wids=s.get('wordIds') or []
    inactive=set(s.get('inactiveWordIds') or [])
    visual_split=set(int(e.get('afterWordId',0)) for e in (s.get('visualSplitPoints') or []))
    custom_split=set(int(e.get('afterWordId',0)) for e in (s.get('customSplitPoints') or []))
    breaks=set(s.get('breakAfterWordIds') or [])
    collapsed=set(int(x) for x in (s.get('collapsedGapWordIds') or []))
    words=TranscriptWord.objects.in_bulk(wids)
    blocks=[]
    cur=None
    prev=None
    for wid in wids:
        if wid in inactive:
            if cur:
                blocks.append(cur); cur=None
            prev=words.get(wid) or prev
            continue
        w=words.get(wid)
        if w is None: continue
        gap=(w.start_ms-prev.end_ms) if prev else 0
        prev_id=prev.id if prev else None
        has_visual=prev_id in visual_split
        has_custom=prev_id in custom_split
        has_break=prev_id in breaks
        is_collapsed_prev=(prev_id in collapsed) if prev_id else False
        big_gap = gap > 3500 if prev else False
        if cur is None:
            cur={'first':wid,'last':wid,'sin':w.start_ms,'sout':w.end_ms,'reason':'first'}
        elif has_visual or has_custom or has_break or is_collapsed_prev or big_gap:
            blocks.append(cur)
            reason='visual' if has_visual else ('custom' if has_custom else ('break' if has_break else ('collapsed' if is_collapsed_prev else 'gap')))
            cur={'first':wid,'last':wid,'sin':w.start_ms,'sout':w.end_ms,'reason':reason}
        else:
            cur['last']=wid; cur['sout']=w.end_ms
        prev=w
    if cur: blocks.append(cur)
    print()
    order = s.get('visualBlockOrderIds') or []
    derived_ids = [f"block-{sid}:{b['first']}" for b in blocks]
    print(f'derivedBlocks count: {len(blocks)}')
    for i,b in enumerate(blocks):
        bid=f"block-{sid}:{b['first']}"
        in_order = bid in order
        marker=''
        if 109267<=b['first']<=109284 or i<3 or i>=len(blocks)-3:
            print(f'  blk[{i}] {bid} last={b["last"]} sin={b["sin"]} sout={b["sout"]} in_order={in_order} reason={b["reason"]}')
    print()
    print('visualBlockOrderIds NOT in derivedBlocks (stale):')
    for b in order:
        if b not in derived_ids:
            print(' STALE:', b)
    print('derivedBlocks NOT in visualBlockOrderIds (orphan):')
    for b in derived_ids:
        if b not in order:
            print(' ORPHAN:', b)
    break
