#!/usr/bin/env python3
from pathlib import Path
import json, re
base=Path('/data/video-pipeline/Channel-Loi-Co-Nhan')
project_id='179-Giu-Mot-Loi-Hua-Voi-Nguoi-Nho-Phuc-Lon-Moi-Ben'
topic='Giữ một lời hứa với người nhỏ, phúc lớn mới bền'
title=topic+' | Lời cổ nhân dạy'
p=base/'project'/project_id
p.mkdir(parents=True, exist_ok=True)
for d in ['script','images/scenes','audio/voice_segments','subtitles','output/thumbnails','output/intro','logs','render_onepass']:
    (p/d).mkdir(parents=True, exist_ok=True)
scenes=[('scene_001', 'Cổ nhân dạy, giữ một lời hứa với người nhỏ, phúc lớn mới bền. Lời hứa không vì nói với người thấp mà nhẹ đi. Một chiếc cầu nhỏ nếu gãy trước khe suối, thì ngày gặp sông lớn, ai còn dám đặt chân lên cầu ấy nữa.', 'chiếc cầu gỗ nhỏ qua khe suối, người xưa đứng suy nghĩ'), ('scene_002', 'Ở một huyện cổ có người thầy thuốc tên Từ. Ông chữa bệnh giỏi, nhà khá giả, được quan lại kính trọng. Nhưng điều khiến dân nghèo quý ông không phải là hòm thuốc đầy, mà là lời nói ra hiếm khi để rơi xuống đất.', 'thầy thuốc áo nâu bên hòm thuốc cổ và người dân nghèo'), ('scene_003', 'Một buổi chiều, có đứa bé chăn trâu đến xin thuốc cho mẹ. Nhà nó nghèo, trong tay chỉ có mấy đồng lẻ. Thầy Từ đang bận đi xem bệnh cho nhà quan, liền hẹn, tối nay ta về sẽ ghé qua nhà con.', 'đứa bé chăn trâu cầm đồng lẻ trước cửa hiệu thuốc'), ('scene_004', 'Đứa bé mừng rỡ chạy về. Đêm xuống, mưa lớn bất ngờ. Người nhà quan giữ thầy Từ lại, nói đường trơn, bệnh người nghèo mai hãy tính. Trên bàn còn có túi bạc hậu tạ, sáng lấp lánh dưới ánh đèn.', 'túi bạc trên bàn, mưa đêm ngoài cửa nhà quan'), ('scene_005', 'Thầy Từ nhìn mưa rồi nhớ đôi mắt đứa bé. Ông biết, bệnh của người lớn có thể đợi một canh, nhưng niềm tin của trẻ nhỏ nếu bị phụ, có khi lạnh cả đời. Ông khoác áo tơi, xách hòm thuốc bước ra.', 'thầy thuốc khoác áo tơi xách hòm thuốc đi trong mưa'), ('scene_006', 'Đường bùn ngập mắt cá, gió thổi tắt đèn lồng. Người hầu khuyên quay lại. Thầy Từ chỉ nói, đã hứa thì chân phải đi thay miệng. Nếu lời hứa chỉ sáng trong nhà giàu, nó không còn là chữ tín.', 'thầy thuốc chống gậy đi qua đường bùn và đèn lồng tắt'), ('scene_007', 'Khi ông đến, căn nhà tranh gần như tối om. Đứa bé vẫn ngồi ngoài cửa chờ, áo ướt mà tay còn ôm bó rơm giữ lửa. Thấy thầy Từ, nó bật khóc, không phải vì sợ, mà vì biết mình không bị quên.', 'đứa bé áo ướt ôm bó rơm bên cửa nhà tranh'), ('scene_008', 'Thầy Từ bắt mạch cho người mẹ, sắc thuốc, dặn cách giữ ấm. Trước khi về, ông đặt lại mấy đồng lẻ vào tay đứa bé. Ông nói, tiền này để mua cháo, còn lời hứa tối nay, ta đã nhận từ lúc gật đầu.', 'thầy thuốc bắt mạch người mẹ nghèo dưới đèn dầu'), ('scene_009', 'Vài ngày sau, chuyện ấy lan khắp huyện. Nhà quan trách ông không biết trọng sang khinh hèn. Thầy Từ đáp, bệnh trong thân người nghèo hay giàu đều đau như nhau; chữ tín trong lòng trẻ nhỏ hay người lớn cũng nặng như nhau.', 'thầy thuốc điềm tĩnh trước sân quan huyện cổ'), ('scene_010', 'Năm sau, dịch bệnh nổi lên. Chính đứa bé chăn trâu ngày trước dẫn dân làng tìm đến thầy Từ, vì nó tin ông sẽ không bỏ ai giữa đường. Nhờ dân nghe lời, thuốc phát kịp, nhiều nhà thoát nạn.', 'đứa bé dẫn dân làng đến hiệu thuốc trong mùa dịch cổ'), ('scene_011', 'Thầy Từ lúc ấy mới hiểu, một lời hứa nhỏ không mất đi. Nó nằm lại trong lòng người, lớn lên thành đường đi cho ngày nguy khó. Người coi thường lời hứa nhỏ, đến khi cần lòng tin lớn thì tìm không ra.', 'hạt giống nhỏ nảy mầm thành lối đi sáng trên đất vàng'), ('scene_012', 'Có người hỏi ông, vì sao không tiếc túi bạc nhà quan. Ông cười nói, bạc dùng rồi hết, còn chữ tín giữ được thì nuôi mình cả đời. Người nghèo có thể không trả bằng tiền, nhưng trời đất trả bằng phúc khí lâu bền.', 'thầy thuốc cười hiền bên hòm thuốc và túi bạc khép lại'), ('scene_013', 'Ở đời, ta thường nghĩ lời hứa với người yếu thế có thể lùi lại. Nhưng chính lúc không ai ép buộc, chữ tín mới hiện rõ. Giữ được lời với người không thể trách phạt mình, ấy mới là giữ lòng ngay thật.', 'người xưa đặt tay lên ngực trước người nghèo và trẻ nhỏ'), ('scene_014', 'Vậy nên, đã hứa với ai, dù là trẻ nhỏ, người nghèo, hay kẻ không có quyền thế, cũng đừng xem nhẹ. Một lời giữ được trong việc nhỏ sẽ dựng nên uy tín trong việc lớn; phúc bền bắt đầu từ chỗ không phụ lòng người yếu.', 'chiếc cầu gỗ vững qua suối, ánh sáng ấm cuối ngày')]
style='Vertical 9:16, cổ phong giấy vàng, aged parchment, ink-wash cinematic historical Vietnamese moral story scene, muted ochre brown sepia charcoal, dignified calm mood, one clear symbolic scene: '; neg=' Negative prompt: no modern objects, no modern clothing, no cars, no motorbikes, no phones, no electric lights, no plastic, no Western faces, no wrong culture, no fantasy, no sci-fi, no neon, no glossy 3D, no anime, no cartoon, no model sheet, no watermark, no logo, no text.'
objs=[{'scene_id':sid,'narration':nar,'image_prompt':style+vis+'.'+neg,'visual_prompt':vis} for sid,nar,vis in scenes]
(p/'script/scenes.json').write_text(json.dumps({'title':title,'metadata':{'project_id':project_id,'topic_sentence':topic,'thumbnail_symbol':'small wooden bridge and medicine chest in rain'},'scenes':objs}, ensure_ascii=False, indent=2), encoding='utf-8')
words=sum(len(re.findall(r'[\wÀ-ỹ]+', nar, re.UNICODE)) for _,nar,_ in scenes)
(p/'script/scenes_validation.json').write_text(json.dumps({'passed':620<=words<=660,'scene_count':14,'word_count':words}, ensure_ascii=False, indent=2), encoding='utf-8')
names=['Choose fresh moral topic, name project, and create project folder','Write script and split scene plan','Image preflight, 9:16 scene images, and single vertical thumbnail','Scene-level TTS','Build master narration timeline and probe durations','ASR master narration word timestamps','Map original narration to ASR word timing','Clamp subtitle safe gaps and validate no overlap','Prepare one-pass 9:16 render','Render full 9:16 main story once','Validate and QA main story video','Create one-frame thumbnail intro','Final package intro + main + BGM audio-safe','Final QA, write output/info.json, then approve output']
steps=[{'step':i,'name':name,'status':'completed' if i<=2 else 'pending'} for i,name in enumerate(names,1)]
(p/'checklist_14_steps.json').write_text(json.dumps({'project_id':project_id,'project_name':project_id[4:].replace('-',' '),'topic_sentence':topic,'title':title,'target_words':'620-660','target_scenes':14,'channel':'Loi Co Nhan','workflow_version':'v3-current-short-ai-script','current_step':3,'steps':steps}, ensure_ascii=False, indent=2), encoding='utf-8')
(p/'checklist_14_steps.md').write_text(f'# Checklist 14 Steps\n\nProject ID: {project_id}  \nTopic: {topic}  \nTitle: {title}  \nTarget: 620-660 words, 14 scenes\n\n- Step 01: Completed\n- Step 02: Completed (14 scenes, {words} words)\n'+'\n'.join([f'- Step {i:02}: Pending' for i in range(3,15)])+'\n', encoding='utf-8')
src=base/'project/178-Dung-Lay-Luc-Gian-Lam-Thuoc-Do-Long-Nguoi'
for name in ['scripts_step03_04_assets_tts.py','scripts_compose_master_worker.py','scripts_run_asr_and_build_subtitles.py','scripts_worker_rebuild_strict.py','scripts_worker_rebuild_yt.py','scripts_generate_intro_audio.py']:
    txt=(src/name).read_text(encoding='utf-8').replace(str(src), str(p)).replace("Path('/data/video-pipeline/Channel-Loi-Co-Nhan/project/161-Giu-Mot-Loi-Dong-Vien-Con-Cai-Vung-Qua-Ngay-Kho')", f"Path('{p}')")
    (p/name).write_text(txt, encoding='utf-8')
print(p); print(words)
