#!/usr/bin/env python3
from pathlib import Path
import json, re, shutil
base = Path('/data/video-pipeline/Channel-Loi-Co-Nhan')
project_id = '177-Giu-Mot-Ngay-Khong-Oan-Tranh-Duoc-Muoi-Nam-Hoi-Tiec'
topic = 'Giữ một ngày không oán, tránh được mười năm hối tiếc'
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, một ngày biết giữ lòng không oán, có khi tránh được mười năm hối tiếc. Lời trách móc giống mũi tên rời dây, bắn ra rồi không tự quay về được. Người giữ được một hơi thở bình tĩnh, đã giữ lại một phần phúc cho mình.','người xưa đặt mũi tên xuống trước hiên nhà trong sương sớm'),
('scene_002','Ở ven sông có người thợ mộc tên Lâm. Ông nổi tiếng làm bàn ghế chắc, nhưng tính nóng như than hồng. Chỉ cần ai chậm trả tiền hay nói sai một câu, ông liền cau mặt, lời nặng hơn búa bổ xuống gỗ.','người thợ mộc áo nâu bên bàn gỗ và búa đục'),
('scene_003','Một năm nước lũ, nhà Lâm hư mái, tiền công lại bị người buôn gạo khất hẹn. Lâm mang sổ nợ đến đòi, trong bụng đầy tức tối. Ông nghĩ, hôm nay phải nói cho người kia biết thế nào là phải trái.','người thợ mộc cầm sổ nợ đi qua bờ sông sau lũ'),
('scene_004','Đến nơi, ông thấy người buôn gạo đang ngồi trước kho ướt, mẹ già nằm bệnh bên trong, mấy bao gạo bị nước làm hỏng. Người ấy cúi đầu xin thêm mười ngày. Lâm nghe vậy càng giận, cho rằng mình bị xem thường.','kho gạo ẩm sau lũ, người buôn gạo cúi đầu bên mẹ già'),
('scene_005','Ông định mắng giữa chợ. Nhưng đúng lúc ấy, một cụ đồ đi ngang đặt tay lên vai ông, nói nhỏ, khi lòng đang bốc khói, đừng mở cửa miệng quá rộng, kẻo lửa cháy sang cả nhà mình.','cụ đồ tóc bạc ngăn người đang giận giữa chợ cổ'),
('scene_006','Lâm nuốt lời xuống. Ông chỉ nói, tôi cho ông mười ngày, nhưng xin giữ đúng một câu đã hẹn. Nói xong, ông quay về. Đường bùn khó đi, lòng cũng chưa nhẹ, nhưng ít nhất miệng ông chưa làm ai đổ máu trong tim.','người thợ mộc lặng lẽ quay về trên đường bùn'),
('scene_007','Đêm ấy, vợ Lâm hỏi sao không đòi đến cùng. Ông bực bội, nhưng nhìn con nhỏ đang ngủ cạnh mái dột, ông chợt hiểu nếu mình làm nhục người kia trước chợ, ngày sau con mình cũng học cách lấy giận làm lẽ phải.','người cha nhìn con ngủ dưới mái dột và ngọn đèn dầu'),
('scene_008','Mười ngày sau, người buôn gạo mang tiền đến đủ, còn biếu thêm một bao gạo lành. Ông nói, nếu hôm trước Lâm mắng tôi giữa chợ, tôi mất mặt, có lẽ đã bỏ xứ mà đi, nợ cũng thành gió sông.','người buôn gạo trao tiền và bao gạo trước xưởng mộc'),
('scene_009','Lâm nghe xong im lặng rất lâu. Ông nhận tiền, trả lại bao gạo, chỉ giữ một lời cảm ơn. Lần đầu tiên ông thấy, nhịn một câu không làm mình thấp đi; trái lại, nó giữ cho người khác còn đường đứng dậy.','hai người đàn ông cúi chào nhau bên cửa xưởng mộc'),
('scene_010','Từ đó, mỗi khi cơn giận dâng lên, Lâm đặt tay lên thớ gỗ trước mặt. Ông tự nhủ, gỗ cong còn uốn được bằng nước và thời gian, lòng người bị lời độc làm gãy thì khó liền lại như cũ.','bàn tay thợ mộc đặt lên thớ gỗ cong dưới ánh đèn'),
('scene_011','Trong làng có kẻ chê ông yếu mềm. Lâm chỉ cười. Ông biết cứng không phải là nói cho hả dạ, mà là giữ được đạo nghĩa khi trong lòng đang muốn hơn thua. Người thắng miệng một lúc, nhiều khi thua tình cả đời.','người thợ mộc điềm tĩnh trước lời bàn tán của dân làng'),
('scene_012','Về sau, xưởng mộc của Lâm đông khách hơn. Không chỉ vì bàn ghế bền, mà vì ai cũng tin ông biết nói điều phải bằng giọng không làm người khác nhục. Chữ tín đôi khi sinh ra từ một lần không oán.','xưởng mộc ấm sáng, khách làng đứng xem bàn ghế chắc chắn'),
('scene_013','Đời người khó tránh lúc bị chậm tiền, bị hiểu lầm, bị phụ lòng. Nhưng trước khi oán, hãy nhìn thêm một bước. Có khi sau lưng người kia là bệnh tật, lũ lụt, hoặc một nỗi khổ họ chưa kịp nói ra.','bóng người đứng trước ngã ba, phía xa là nhà nghèo sau mưa'),
('scene_014','Vậy nên, khi lời oán sắp tràn qua môi, hãy giữ lại một ngày. Một ngày không oán có thể cứu một tình nghĩa, giữ một chữ tín, và chặn mười năm hối tiếc khỏi bước vào cửa nhà mình.','cánh cửa gỗ khép nhẹ, ánh sáng ấm giữ lại trong nhà'),
]
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': 'unreleased arrow beside calm wooden doorway'}, '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')
steps = [{'step': i, 'name': name, 'status': 'completed' if i <= 2 else 'pending'} for i, name in enumerate(['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'], 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/176-Biet-Giu-Loi-Mem-Cua-Nha-Bot-Gio-Lanh'
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))
    (p/name).write_text(txt, encoding='utf-8')
print(p)
print(words)
