#!/usr/bin/env python3
import json,re,sys,hashlib
from pathlib import Path
p=Path(sys.argv[1]);d=json.loads(p.read_text());errs=[]
P='gacmai_20260717_184527';TITLE='Mùa Nở Không Có Tên';POV='Nguyễn Lam Chi';CAST=['Nguyễn Lam Chi','Trần Vĩnh Phúc','Lê Thu Nguyệt','Phạm Hữu Tường','Đỗ Khánh An','Vũ Minh Triết']
if d.get('project_id')!=P:errs.append('project_id')
if d.get('title')!=TITLE:errs.append('title')
if d.get('pov',POV)!=POV:errs.append('pov')
if d.get('named_characters',d.get('cast'))!=CAST:errs.append('cast')
parts=d.get('parts',[])
if [x.get('part') for x in parts]!=list(range(1,13)):errs.append('part_ids')
texts=[]
for part in parts:
 ps=part.get('paragraphs',[])
 if len(ps)!=12:errs.append(f"P{part.get('part')}_count")
 for x in ps:
  t=x if isinstance(x,str) else x.get('text') or x.get('narration') or ''
  texts.append(t.strip())
if len(texts)!=144 or any(not x for x in texts):errs.append('paragraphs')
words=sum(len(re.findall(r'\b\w+\b',x,re.UNICODE)) for x in texts)
if not 14000<=words<=15000:errs.append(f'word_count:{words}')
blob='\n'.join(texts)
for pat in [r'\bE0[1-9]\b',r'\bA0[1-6]\b',r'cannot.support',r'placeholder',r'Aftercare',r'không teaser',r'P\d+D\d+',r'paragraph beat']:
 if re.search(pat,blob,re.I):errs.append('meta:'+pat)
UP='A-ZĐÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÈÉẺẼẸÊỀẾỂỄỆÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸỴ'
LO='a-zđàáảãạăằắẳẵặâầấẩẫậèéẻẽẹêềếểễệìíỉĩịòóỏõọôồốổỗộơờớởỡợùúủũụưừứửữựỳýỷỹỵ'
found=set(re.findall(rf'\b[{UP}][{LO}]+\s+[{UP}][{LO}]+\s+[{UP}][{LO}]+\b',blob))
allowed_prefix=('Hội Đồng','Ngân Hàng','Cơ Quan','Mùa Nở')
extra=sorted(x for x in found if x not in CAST and not x.startswith(allowed_prefix))
if extra:errs.append('extra_names:'+','.join(extra[:20]))
if len(set(texts))!=144:errs.append('exact_paragraph_duplicates')
if d.get('outline_sha256') is None:errs.append('missing_outline_sha')
sources=d.get('sources',[])
if len(sources)!=3 or [x.get('part_range') for x in sources]!=[[1,4],[5,8],[9,12]] or any(not x.get('sha256') for x in sources):errs.append('source_provenance')
out={'status':'passed' if not errs else 'failed','story_sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'parts':len(parts),'paragraphs':len(texts),'words':words,'cast':CAST,'errors':errs};print(json.dumps(out,ensure_ascii=False));raise SystemExit(1 if errs else 0)
