#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""make_cards.py — 自绘片头字卡（叠加到 S01）与片尾字幕卡（S60），避免 H3 渲染中文出错。

输出：
  05-分镜脚本/字卡/标题.png                透明底「九九八十一」书法感标题
  05-分镜脚本/字卡/片尾.png                片尾字幕卡底图（含原唱/翻唱/作词/作曲）
  06-H3片段/S01/S01_final.mp4             S01 原片段 + 标题淡入淡出（合片时优先用 _final）
  06-H3片段/S60.mp4                       片尾字幕卡 + 缓慢推镜（合片时优先于 stills/S60.mp4）
"""
import os, subprocess, sys
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
os.chdir(ROOT)
CARD = ROOT / "05-分镜脚本/字卡"
CARD.mkdir(parents=True, exist_ok=True)
BOLD = "/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc"
SERIF = "/usr/share/fonts/opentype/source-han-cjk/SourceHanSerif.ttc"
if not Path(SERIF).exists():
    SERIF = BOLD
W, H = 1920, 1080


def font(path, size):
    try:
        return ImageFont.truetype(path, size)
    except Exception:
        return ImageFont.truetype(BOLD, size)


def title_card():
    """透明底标题：竖排感不强求，用大号衬线字 + 朱红印章。"""
    img = Image.new("RGBA", (W, H), (0, 0, 0, 0))
    d = ImageDraw.Draw(img)
    f = font(SERIF, 190)
    text = "九九八十一"
    # 居中，逐字微调字距
    total = sum(d.textlength(ch, font=f) for ch in text) + 26 * (len(text) - 1)
    x = (W - total) / 2
    y = 300
    for ch in text:
        # 描边 + 墨色填充，模拟书法
        for dx, dy in [(-6, 0), (6, 0), (0, -6), (0, 6), (-4, -4), (4, 4), (-4, 4), (4, -4)]:
            d.text((x + dx, y + dy), ch, font=f, fill=(255, 255, 255, 210))
        d.text((x, y), ch, font=f, fill=(28, 26, 24, 255))
        x += d.textlength(ch, font=f) + 26
    # 朱红小印
    fs = font(SERIF, 40)
    d.rounded_rectangle([W / 2 - 74, y + 250, W / 2 + 74, y + 330], radius=10,
                        fill=(178, 42, 36, 235))
    d.text((W / 2 - 56, y + 264), "群像 MV", font=fs, fill=(255, 248, 240, 255))
    img.save(CARD / "标题.png")
    print("已写", CARD / "标题.png")


def end_card(bg="05-分镜脚本/关键帧/可爱版/S59.png"):
    base = Image.open(bg).convert("RGB").resize((W, H))
    # 轻微提亮 + 叠一层暖白，保证文字可读
    overlay = Image.new("RGB", (W, H), (255, 252, 245))
    base = Image.blend(base, overlay, 0.55)
    d = ImageDraw.Draw(base, "RGBA")
    # 中间一块半透明宣纸底，保证文字干净可读
    d.rounded_rectangle([W / 2 - 420, 130, W / 2 + 420, 950], radius=26,
                        fill=(255, 253, 248, 205), outline=(180, 170, 158, 180), width=3)
    f1 = font(SERIF, 112)
    f2 = font(BOLD, 48)
    t = "九九八十一"
    w = d.textlength(t, font=f1)
    d.text(((W - w) / 2, 200), t, font=f1, fill=(30, 28, 26),
           stroke_width=4, stroke_fill=(255, 255, 255))
    lines = ["", "原唱　　乐正绫 / 洛天依", "翻唱　　咻咻满", "作词　　邪叫教主",
             "作曲　　乌龟Sui", "编曲　　司鼓君", "", "可爱版 MV · AI 分镜与生成",
             "2026-09-25"]
    y = 390
    for ln in lines:
        if ln:
            w = d.textlength(ln, font=f2)
            d.text(((W - w) / 2, y), ln, font=f2, fill=(52, 48, 44),
                   stroke_width=3, stroke_fill=(255, 255, 255))
        y += 68
    base.save(CARD / "片尾.png")
    print("已写", CARD / "片尾.png")


def build_s01(title_png, dur=5.875):
    """把标题叠到 S01：1.2s 淡入、3.6s 起淡出。"""
    src = "06-H3片段/S01/S01.mp4"
    out = "06-H3片段/S01/S01_final.mp4"
    if not Path(src).exists():
        print("!! 缺少", src, "（等 S01 出片后再跑本步）"); return
    vf = (f"[1:v]format=rgba,fade=in:st=0.3:d=1.0:alpha=1,"
          f"fade=out:st=3.2:d=0.9:alpha=1[t];[0:v][t]overlay=0:0,format=yuv420p")
    r = subprocess.run(["ffmpeg", "-v", "error", "-y", "-i", src, "-loop", "1", "-i", str(title_png),
                        "-filter_complex", vf, "-t", f"{dur}", "-r", "24",
                        "-c:v", "libx264", "-crf", "17", "-preset", "medium", "-an", out],
                       capture_output=True, text=True)
    print(("[ok] " if r.returncode == 0 else "[FAIL] ") + out + ("" if r.returncode == 0 else r.stderr[-300:]))


def build_s60(png, dur=7.0):
    out = "06-H3片段/S60.mp4"
    f = int(dur * 24)
    vf = (f"scale=3840:-2,zoompan=z='min(1.0+0.06*on/{f},1.06)':x='iw/2-(iw/zoom/2)':"
          f"y='ih/2-(ih/zoom/2)':d={f}:s=1920x1080:fps=24,format=yuv420p")
    r = subprocess.run(["ffmpeg", "-v", "error", "-y", "-loop", "1", "-i", str(png), "-t", f"{dur}",
                        "-vf", vf, "-c:v", "libx264", "-crf", "17", "-preset", "medium", "-an", out],
                       capture_output=True, text=True)
    print(("[ok] " if r.returncode == 0 else "[FAIL] ") + out + ("" if r.returncode == 0 else r.stderr[-300:]))


if __name__ == "__main__":
    title_card()
    end_card()
    # 注：S01 由 H3 自带的书法标题已足够好，不再叠加自绘标题（曾出现双重标题）
    build_s60(CARD / "片尾.png")
