#!/usr/bin/env python3
from __future__ import annotations

import hashlib
import json
from pathlib import Path

ROOT = Path("/data/video-pipeline/HaTramAudio/project/013-Ngay-Buu-Cuc-Cu-Sang-Den")
PROJECT_ID = "013-Ngay-Buu-Cuc-Cu-Sang-Den"
RUN_ID = "run-20260720T110344Z-f6c08be9"
OWNER = "zoro"
TITLE = "Ngày Bưu Cục Cũ Sáng Đèn"
WORK = ROOT / "work" / "artwork" / RUN_ID


def sha(path: Path) -> str:
    h = hashlib.sha256()
    with path.open("rb") as f:
        for block in iter(lambda: f.read(8 * 1024 * 1024), b""):
            h.update(block)
    return h.hexdigest()


def guard() -> None:
    d = json.loads((ROOT / ".ownership-lock.json").read_text(encoding="utf-8"))
    for k, v in {"project_id": PROJECT_ID, "run_id": RUN_ID, "owner": OWNER, "status": "active"}.items():
        if d.get(k) != v:
            raise RuntimeError(f"ownership mismatch: {k}")


def write(path: Path, text: str) -> None:
    guard()
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(text, encoding="utf-8")


def main() -> None:
    guard()
    authority = {
        "story/story-canon.txt": ROOT / "story/story-canon.txt",
        "script/story-brief.json": ROOT / "script/story-brief.json",
        "script/identity-registry.json": ROOT / "script/identity-registry.json",
        "script/reveal-ledger.json": ROOT / "script/reveal-ledger.json",
        "script/outline.json": ROOT / "script/outline.json",
        "script/promotion-report.json": ROOT / "script/promotion-report.json",
    }
    if not all(path.is_file() for path in authority.values()):
        raise RuntimeError("artwork authority incomplete")
    promotion = json.loads(authority["script/promotion-report.json"].read_text(encoding="utf-8"))
    if not promotion.get("verified") or promotion.get("status") not in {"passed", "completed", "completed_content_only"}:
        raise RuntimeError("promotion not verified")
    canon_hash = sha(authority["story/story-canon.txt"])
    if canon_hash != (promotion.get("canon_sha256") or promotion.get("source_canon_sha256")):
        raise RuntimeError("canon hash mismatch")
    brief = json.loads(authority["script/story-brief.json"].read_text(encoding="utf-8"))
    identity = json.loads(authority["script/identity-registry.json"].read_text(encoding="utf-8"))
    reveal = json.loads(authority["script/reveal-ledger.json"].read_text(encoding="utf-8"))
    identity_context = json.dumps(identity, ensure_ascii=False)
    # Only visual identity crosses the provider boundary; reveal content remains hash-bound but undisclosed.
    shared = f"""IDENTITY REGISTRY NỘI BỘ (chỉ dùng để giữ nhất quán nhân vật, không render thành chữ):\n{identity_context}\n\nTên chính thức: \"{TITLE}\". Thể loại: ngôn tình đô thị trưởng thành, cứu hộ đời thường, chữa lành và drama. Bối cảnh biểu tượng: bưu cục gạch cũ ở huyện miền núi Vân Khê sáng đèn giữa thị trấn mất điện và mưa lớn; bên trong có điện thoại hữu tuyến, bộ đàm, bản đồ tuyến phát thư, túi thư và phiếu giấy buộc chỉ đỏ. Nhân vật là người châu Á hư cấu trưởng thành, nhất quán với Identity Registry. Giới hạn tiết lộ tuyệt đối: chỉ thể hiện bưu cục sáng đèn, Trình Vãn Ý, Lục Trầm Chu, túi thư, phiếu giấy buộc chỉ đỏ và mưa lớn; không tiết lộ người làm giả, sai phạm cây cầu, sổ giao ca, trách nhiệm của Trình Vãn Ý hoặc kết cục quan hệ.\n\nPhong cách poster phim điện ảnh cao cấp, digital illustration bán hiện thực, tối giản, một focal point rõ, low-key lighting, tương phản mạnh có kiểm soát, ánh tungsten hổ phách đối lập xanh mưa lạnh, chiều sâu foreground-midground-background, không collage, không card, không slide, không mockup. Không mô phỏng người thật.\n\nVệ sinh đạo cụ: mọi phiếu, phong bì, tem, dấu, biển, đồng hồ, sổ, bản đồ, màn hình và nhãn trong cảnh phải trơn hoặc không có ký tự đọc được. Chỉ đỏ được phép xuất hiện như motif hình ảnh nhưng không có chữ. Không logo, watermark, chữ ký, số, chữ môi trường hay pseudo-text ngoài các khối chữ bắt buộc. Provider tạo hoàn chỉnh cả hình và typography; không chừa chỗ để hậu kỳ chữ.\n"""
    poster = shared + f"""\nTạo key art poster ngang tỷ lệ 16:9, master 1920x1080 dùng làm intro/thumbnail. Trọng tâm là Trình Vãn Ý, nữ kỹ sư liên lạc khẩn cấp 30 tuổi, tóc đen ngang vai, áo mưa vàng đất và túi dụng cụ xám, đứng trong bưu cục cũ đang sáng đèn. Lục Trầm Chu, bưu tá đường núi 33 tuổi trong áo mưa xanh sẫm, đứng ở lớp sau cạnh xe máy bám bùn và túi thư. Một phiếu giấy buộc chỉ đỏ cùng chiếc điện thoại hữu tuyến tạo điểm nhấn, mưa lớn và thị trấn mất điện ở hậu cảnh; căng thẳng cứu hộ và tình cảm trưởng thành nhưng không lộ twist. Provider tự quyết font, vị trí, kích thước, xuống dòng, khoảng cách và phân cấp typography.\n\nRENDER CHÍNH XÁC BA KHỐI CHỮ TIẾNG VIỆT SAU TRỰC TIẾP TRONG ẢNH, KHÔNG THÊM CHỮ KHÁC:\n\"Hạ Trâm Audio\"\n\"{TITLE}\"\n\"Truyện được phát độc quyền tại Hạ Trâm Audio, nghiêm cấm sao chép dưới mọi hình thức\"\n\nGiữ nguyên từng chữ, dấu tiếng Việt và dấu phẩy; chữ không bị cắt hoặc che, dễ đọc và không phá bố cục.\n"""
    right = shared + f"""\nTạo key art poster phim điện ảnh dọc tỷ lệ chính xác 656:1080, master 1080x1778, dùng nguyên ảnh làm panel phải. Trình Vãn Ý trong áo mưa vàng đất là focal point; Lục Trầm Chu áo mưa xanh sẫm lùi phía sau với túi thư và xe máy bám bùn. Bưu cục cũ sáng đèn giữa mưa tối, điện thoại hữu tuyến và phiếu giấy buộc chỉ đỏ tạo chiều sâu. Bố cục dọc tối giản, không crop nhân vật hoặc đạo cụ quan trọng. Provider tự quyết toàn bộ typography.\n\nRENDER CHÍNH XÁC BA KHỐI CHỮ TIẾNG VIỆT SAU TRỰC TIẾP TRONG ẢNH, KHÔNG THÊM CHỮ KHÁC:\n\"Hạ Trâm Audio\"\n\"{TITLE}\"\n\"Truyện được phát độc quyền tại Hạ Trâm Audio, nghiêm cấm sao chép dưới mọi hình thức\"\n\nGiữ nguyên từng chữ, dấu tiếng Việt và dấu phẩy; chữ không bị cắt hoặc che, dễ đọc và không phá bố cục.\n"""
    left = shared + f"""\nTạo branding panel điện ảnh dọc tỷ lệ chính xác 656:1080, master 1080x1778, dành cho cạnh trái layout Hạ Trâm Audio. Cùng color grade với poster \"{TITLE}\": bưu cục cũ trừu tượng trong mưa, ánh tungsten trên ô thư gỗ, điện thoại hữu tuyến và motif chỉ đỏ không chữ; không nhân vật, không tên truyện, không dòng độc quyền. Cạnh phải có transition texture nhẹ, không aperture, không khung màn hình và không giả lập layout ba panel. Provider tự quyết toàn bộ typography.\n\nRENDER CHÍNH XÁC HAI KHỐI CHỮ TIẾNG VIỆT SAU TRỰC TIẾP TRONG ẢNH, KHÔNG THÊM CHỮ KHÁC:\n\"Hạ Trâm Audio\"\n\"Like • Chia sẻ • Đăng ký\"\n\nGiữ nguyên chính tả và dấu tiếng Việt; chữ không bị cắt hoặc che, dễ đọc và không phá bố cục.\n"""
    WORK.mkdir(parents=True, exist_ok=True)
    outputs = {"intro_poster": poster, "right_panel": right, "left_panel": left}
    items = {}
    for key, prompt in outputs.items():
        path = WORK / f"{key}.prompt.txt"
        write(path, prompt)
        items[key] = {"prompt_path": str(path), "prompt_sha256": sha(path)}
    manifest = {
        "schema_version": 1,
        "project_id": PROJECT_ID,
        "run_id": RUN_ID,
        "status": "locked",
        "verified": True,
        "source_canon_sha256": canon_hash,
        "authority_sha256": {key: sha(path) for key, path in authority.items()},
        "canonical_title": TITLE,
        "provider_skill": "tao-anh",
        "provider_model": "cx/gpt-5.5-image",
        "provider_only_typography": True,
        "text_postprocessing_allowed": False,
        "items": items,
    }
    guard()
    (ROOT / "script/image-prompts.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"status": "locked", "source_canon_sha256": canon_hash, "items": items}, ensure_ascii=False))


if __name__ == "__main__":
    main()
