#!/usr/bin/env python3
from pathlib import Path
import json, re, math

PROJECT = Path('/data/video-pipeline/Youtube-Video-Maker/Project/03072026-001-Han-Tin')
SRC = PROJECT / 'script/source_story.txt'

def clean_text(t: str) -> str:
    t = t.replace('\r\n', '\n').replace('\r', '\n')
    t = re.sub(r'\n{3,}', '\n\n', t.strip())
    return t

def split_sentences(p: str):
    return [s.strip() for s in re.split(r'(?<=[.!?。]|[?])\s+', p.strip()) if s.strip()]

def section_title(raw: str) -> str:
    title = re.sub(r'^\d+\.\s*', '', raw.strip())
    return title[:1] + title[1:].lower()

def visual_for(text: str, section: str, typ='visual_beat') -> str:
    low = text.lower()
    if typ == 'heading':
        return f'Title card for section: {section}'
    if 'bối thủy' in low or 'lưng' in low and 'sông' in low:
        return 'Hàn Tín bày trận lưng tựa sông, quân sĩ liều chết chiến đấu, cờ Hán dâng lên trong sương nước.'
    if 'hạng vũ' in low and ('cai hạ' in low or 'ô giang' in low):
        return 'Bi kịch Cai Hạ và Ô Giang: Hạng Vũ giữa vòng vây, ánh lửa tàn, tiếng Sở ca xa xăm.'
    if 'tiêu hà' in low and ('trăng' in low or 'đuổi' in low):
        return 'Tiêu Hà cưỡi ngựa đuổi theo Hàn Tín dưới ánh trăng lạnh ngoài doanh trại Hán.'
    if 'chui qua háng' in low or 'chợ' in low:
        return 'Hàn Tín trẻ tuổi nghèo khó giữa chợ Hoài Âm, đeo kiếm, cúi mình chịu nhục trước đám đông.'
    if 'lữ hậu' in low or 'trường lạc' in low:
        return 'Cung Trường Lạc u tối, âm mưu triều đình khép lại số phận Hàn Tín.'
    if 'long thư' in low or 'sông duy' in low:
        return 'Sông Duy vỡ dòng, quân Sở bị chia cắt, Hàn Tín phản công trong mưa nước và cờ xí.'
    if 'ngụy' in low or 'trần thương' in low or 'quan trung' in low:
        return 'Bản đồ chiến dịch, quân Hán vượt đường hiểm, nghi binh và phục kích làm xoay chuyển thế trận.'
    return 'Cảnh lịch sử Trung Hoa thời Hán Sở, nhân vật và quân đội trong bố cục kể chuyện bằng mực nâu trên giấy cổ.'

def build_scenes(cleaned: str):
    body = re.sub(r'^Tiêu đề truyện:.*?^Nội dung:\s*', '', cleaned, flags=re.S|re.M).strip()
    chunks = re.split(r'(?m)^(\d+\.\s+[^\n]+)$', body)
    scenes=[]; sid=1; current='Mở đầu'
    for chunk in chunks:
        if not chunk.strip():
            continue
        if re.match(r'^\d+\.\s+', chunk.strip()):
            current = section_title(chunk)
            scenes.append({'scene_id':f'scene_{sid:03d}','type':'heading','section':current,'text':current,'visual_beat':visual_for('', current, 'heading'),'estimated_seconds':4,'rule':'heading_must_be_own_scene'})
            sid+=1
            continue
        paras=[p.strip() for p in chunk.split('\n\n') if p.strip()]
        for p in paras:
            sents=split_sentences(p)
            if not sents: continue
            group=[]; wc=0
            for s in sents:
                group.append(s); wc += len(s.split())
                if wc >= 42 or len(group)>=3:
                    text=' '.join(group)
                    scenes.append({'scene_id':f'scene_{sid:03d}','type':'visual_beat','section':current,'text':text,'visual_beat':visual_for(text,current),'estimated_seconds':max(14,min(22,round(len(text.split())/3.0))),'rule':'grouped_visual_beat_14_22_seconds'})
                    sid+=1; group=[]; wc=0
            if group:
                text=' '.join(group)
                if scenes and scenes[-1]['type']=='visual_beat' and len(text.split()) < 18 and scenes[-1]['section']==current:
                    scenes[-1]['text'] += ' ' + text
                    scenes[-1]['estimated_seconds']=min(22, scenes[-1]['estimated_seconds']+5)
                    scenes[-1]['visual_beat']=visual_for(scenes[-1]['text'],current)
                else:
                    scenes.append({'scene_id':f'scene_{sid:03d}','type':'visual_beat','section':current,'text':text,'visual_beat':visual_for(text,current),'estimated_seconds':max(12,min(22,round(len(text.split())/3.0))),'rule':'grouped_visual_beat_14_22_seconds'})
                    sid+=1
    return scenes

characters = [
 {'name':'Hàn Tín trẻ tuổi','role':'Main character early life, poor swordsman in Hoài Âm','estimated_age':'20-28','appearance':'thin young Han Chinese man, sharp thoughtful eyes, tied black hair, restrained posture, humble but intense','costume':'plain worn late Qin/early Han cloth robe, simple belt, old sword on back','temperament':'patient, wounded pride, frightening self-control','historical_cultural_context':'late Qin collapse, Huaiyin marketplace, lower-class wandering swordsman','visual_keywords':['young Han Xin','Hoai Am market','worn sword','humiliation'],'negative_notes':'no fantasy armor, no modern street, no Qing queue'},
 {'name':'Hàn Tín đại tướng','role':'Main character as Han grand general and strategist','estimated_age':'30-38','appearance':'lean commanding Han Chinese general, angular face, calm calculating gaze, black hair under commander headgear','costume':'early Western Han lamellar armor, dark robe layers, command seal, sword, muted red/black banners','temperament':'brilliant, controlled, strategic, proud','historical_cultural_context':'Chu-Han contention, Qin-Han transition military culture','visual_keywords':['Han Xin general','Han army','strategy map','early Han armor'],'negative_notes':'no Three Kingdoms armor, no Tang/Song/Ming/Qing clothing'},
 {'name':'Lưu Bang','role':'Han king and future emperor who uses talented men','estimated_age':'45-55','appearance':'middle-aged Han Chinese ruler, practical face, short beard, shrewd eyes','costume':'early Han noble robe and battlefield cloak, modest imperial bearing before full empire','temperament':'charismatic, pragmatic, suspicious after victory','historical_cultural_context':'King of Han during Chu-Han War, founder of Han dynasty','visual_keywords':['Liu Bang','Han king','pragmatic ruler'],'negative_notes':'no dragon emperor excess before founding, no later dynasty crown'},
 {'name':'Tiêu Hà','role':'Chancellor and talent scout who recommends Hàn Tín','estimated_age':'45-60','appearance':'scholarly older Han official, long beard, intelligent tired eyes','costume':'early Han official robes, simple cap, travel cloak for moonlit chase','temperament':'steady, discerning, loyal to statecraft','historical_cultural_context':'Han administrative elite, logistics and governance','visual_keywords':['Xiao He','moon chase','Han official'],'negative_notes':'no modern scholar clothing'},
 {'name':'Hạng Vũ','role':'Western Chu hegemon king and tragic rival','estimated_age':'28-32','appearance':'powerful heroic Chu warrior, broad shoulders, intense eyes, commanding presence','costume':'Chu aristocratic armor, heavy cloak, halberd or sword, dark war banners','temperament':'fierce, proud, heroic, impetuous','historical_cultural_context':'Chu aristocracy and Chu-Han War','visual_keywords':['Xiang Yu','Chu warrior','Cai Xia','Wu River'],'negative_notes':'no fantasy barbarian design, no Roman armor'},
 {'name':'Lữ hậu','role':'Empress who executes Hàn Tín in political purge','estimated_age':'35-45','appearance':'stern Han court woman, composed face, cold political gaze','costume':'early Han palace robes, restrained noble hair ornaments, dark red and black palette','temperament':'ruthless, calculating, controlled','historical_cultural_context':'early Han imperial court, Changle Palace','visual_keywords':['Empress Lu','Han palace','court intrigue'],'negative_notes':'no Tang palace costume, no Qing hair ornaments'},
 {'name':'Khoái Triệt','role':'Strategist who advises Hàn Tín to divide the realm','estimated_age':'40-55','appearance':'thin sharp-eyed counselor, quiet intense expression','costume':'plain strategist robe, bamboo slips, travel-worn cloak','temperament':'coldly rational, farsighted','historical_cultural_context':'wandering Chu-Han era persuader and strategist','visual_keywords':['Kuai Che','strategist','three-way realm'],'negative_notes':'no fantasy wizard look'},
 {'name':'Binh sĩ Hán','role':'Recurring Han army soldiers and banners','estimated_age':'varied adults','appearance':'East Asian soldiers, disciplined but weary, simple helmets and lamellar pieces','costume':'early Han infantry armor, spears, crossbows, red-black Han banners','temperament':'tense, resilient, loyal under pressure','historical_cultural_context':'Qin-Han transition army','visual_keywords':['Han soldiers','red black banners','ancient Chinese infantry'],'negative_notes':'no modern guns, no plate armor'},
 {'name':'Quân Sở','role':'Recurring Chu forces under Hạng Vũ and Long Thư','estimated_age':'varied adults','appearance':'hardened East Asian warriors, proud fierce expressions','costume':'Chu-style armor, dark blue/black banners, spears and halberds','temperament':'bold, proud, shaken near defeat','historical_cultural_context':'Western Chu army during Chu-Han contention','visual_keywords':['Chu army','Xiang Yu banners','ancient battlefield'],'negative_notes':'no fantasy monster army'}
]

def main():
    cleaned=clean_text(SRC.read_text(encoding='utf-8'))
    (PROJECT/'script/cleaned_story.txt').write_text(cleaned,encoding='utf-8')
    scenes=build_scenes(cleaned)
    (PROJECT/'script/scenes.json').write_text(json.dumps({'project_id':PROJECT.name,'target_beat_seconds':'14-22','split_rule':'Headings standalone; narration grouped into visual beats of about 14-22 seconds.','total_scenes':len(scenes),'scenes':scenes},ensure_ascii=False,indent=2),encoding='utf-8')
    (PROJECT/'script/scenes_validation.json').write_text(json.dumps({'project_id':PROJECT.name,'total_scenes':len(scenes),'metadata_removed_from_scenes':True,'headings_standalone':True,'each_scene_has_visual_beat':all('visual_beat' in s for s in scenes),'status':'passed'},ensure_ascii=False,indent=2),encoding='utf-8')
    bible={'project_id':PROJECT.name,'visual_style_global':'16:9 horizontal historical storytelling image, ink-wash window centered on warm antique paper, muted brown-black/charcoal watercolor, early Qin-Han / Chu-Han historical grounding, no modern/fantasy drift.','consistency_rules':['Use Hàn Tín trẻ tuổi only for poverty/market humiliation scenes.','Use Hàn Tín đại tướng for military campaigns and court after rise.','Use period-correct late Qin/early Western Han clothing, armor, banners, architecture.'],'characters':characters}
    (PROJECT/'script/character_bible.json').write_text(json.dumps(bible,ensure_ascii=False,indent=2),encoding='utf-8')
    dense=[]
    for sc in scenes:
        prompt=('16:9 horizontal historical storytelling image, ink-wash narrative window on warm antique paper, painted content only 65-70% of frame with clean parchment negative space. '
                f"Scene: {sc['visual_beat']} Narration beat: {sc['text']} Historical grounding: Chu-Han contention, late Qin to early Western Han China, accurate clothing, armor, banners, architecture. Negative: no modern objects, no fantasy armor, no 3D game art, no full-frame glossy poster, no text labels or watermark.")
        dense.append({**sc,'summary':sc['visual_beat'],'narration':sc['text'],'visual_prompt':prompt})
    (PROJECT/'script/dense_scene_plan.json').write_text(json.dumps({'project_id':PROJECT.name,'approved_for_next_step':True,'total_scenes':len(dense),'scenes':dense},ensure_ascii=False,indent=2),encoding='utf-8')
    print(json.dumps({'project':str(PROJECT),'total_scenes':len(scenes)},ensure_ascii=False))
if __name__=='__main__': main()
