"""§7 拓展 · 设计取舍 + 迁移 · slide 94-102 (9 内容页) · v0.2 真实内容版

嵌入 2 张图（G5 / A17）+ 7 张自画
"""

from pathlib import Path
from pptx.util import Inches
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR

from build_main import (
    _fill_ph, _add_textbox, _add_card,
    NAVY, CORAL, CORAL_LIGHT, BLUE_ACCENT, GREEN, GOLD,
    GRAY_300, GRAY_500, GRAY_700, WHITE,
)
from build_sec_M1 import _add_centered_image, _title


def build_slide_94_creed_vs_wiki(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 设计取舍 ① · 心法嵌进 enforcement vs 写 wiki")
    _add_textbox(s, Inches(0.55), Inches(1.6), Inches(5.8), Inches(0.5),
                 "✗ 传统：写 wiki", size_pt=22, bold=True, color=GRAY_500)
    wiki_cons = [
        "团队成员要主动去看",
        "看了不一定遵循",
        "更新滞后 → 实际做法 ≠ wiki",
        "新人 onboarding 全靠自觉",
    ]
    for i, item in enumerate(wiki_cons):
        _add_textbox(s, Inches(0.85), Inches(2.3 + i * 0.55), Inches(5.6), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(7.0), Inches(1.6), Inches(5.8), Inches(0.5),
                 "✓ AGF：嵌进 enforcement", size_pt=22, bold=True, color=CORAL)
    enforce_pros = [
        "hook 自动拦违规命令 / 密钥",
        "skill 强制路径不走不行",
        "DoD checklist 不达标 = 任务不能 done",
        "新人第一天就被机制托住",
    ]
    for i, item in enumerate(enforce_pros):
        _add_textbox(s, Inches(7.3), Inches(2.3 + i * 0.55), Inches(5.6), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(0.55), Inches(5.5), Inches(12.2), Inches(0.5),
                 "学术参考：AI Scrum Master 自动化研究（Springer 2024）",
                 size_pt=14, color=NAVY, align=PP_ALIGN.CENTER, bold=True)
    _add_textbox(s, Inches(0.55), Inches(6.1), Inches(12.2), Inches(0.9),
                 "→ link.springer.com/chapter/10.1007/978-3-031-72781-8_12\n→ AGF PO+SM 合并不是孤例",
                 size_pt=12, color=GRAY_500, align=PP_ALIGN.CENTER)
    return s


def build_slide_95_14_vs_1(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 设计取舍 ② · 14 同事职责契约 vs 单 agent 全能")
    _add_textbox(s, Inches(0.55), Inches(1.6), Inches(5.8), Inches(0.5),
                 "✗ 单 agent 全能", size_pt=22, bold=True, color=GRAY_500)
    cons = [
        "context 太长 token 超预算",
        "无角色边界 → 既裁判又球员",
        "无失败回路 → bug 滚到上线才发现",
        "无 push back 机制",
        "无 audit 轨迹",
    ]
    for i, item in enumerate(cons):
        _add_textbox(s, Inches(0.85), Inches(2.3 + i * 0.55), Inches(5.6), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(7.0), Inches(1.6), Inches(5.8), Inches(0.5),
                 "✓ 14 同事职责契约", size_pt=22, bold=True, color=CORAL)
    pros = [
        "每 agent 短 context 高质量",
        "角色边界明确（review/QA 不动源码）",
        "6 阶段门 + 失败回路捕 bug 早",
        "dev push back 带数据反驳 reviewer",
        "progress/ + docs/reviews/ + docs/qa/ 全 audit 轨迹",
    ]
    for i, item in enumerate(pros):
        _add_textbox(s, Inches(7.3), Inches(2.3 + i * 0.55), Inches(5.6), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(0.55), Inches(6.0), Inches(12.2), Inches(0.5),
                 "代价：14 agent 启动管理复杂（用 /agf-team-start 抽象）",
                 size_pt=14, color=NAVY, align=PP_ALIGN.CENTER)
    return s


def build_slide_96_dev_sit_vs_qa(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 设计取舍 ③ · dev 自跑 SIT vs 独立 QA stage")
    _add_textbox(s, Inches(0.55), Inches(1.6), Inches(5.8), Inches(0.5),
                 "✗ 独立 QA stage", size_pt=22, bold=True, color=GRAY_500)
    cons = [
        "dev 写完丢 QA → 心态'反正 QA 会测'",
        "QA 测出 bug 回 dev → 排期失控",
        "上下文 dev → QA 翻译损失大",
        "QA 工时 = 额外阶段，工期延长 30%",
    ]
    for i, item in enumerate(cons):
        _add_textbox(s, Inches(0.85), Inches(2.3 + i * 0.55), Inches(5.6), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(7.0), Inches(1.6), Inches(5.8), Inches(0.5),
                 "✓ dev 自跑 SIT + reviewer audit", size_pt=22, bold=True, color=CORAL)
    pros = [
        "dev 必须 own 集成质量（不能甩锅）",
        "reviewer 在 review 时 audit SIT 证据",
        "上下文连续（dev 自己测）",
        "qa-engineer 仅做 E2E + UAT（高价值人工）",
    ]
    for i, item in enumerate(pros):
        _add_textbox(s, Inches(7.3), Inches(2.3 + i * 0.55), Inches(5.6), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(0.55), Inches(5.7), Inches(12.2), Inches(0.5),
                 "关键：dev 自跑 ≠ 没人审 · reviewer 双 verdict 含 SIT Audit 维度",
                 size_pt=14, color=NAVY, align=PP_ALIGN.CENTER, bold=True)
    _add_textbox(s, Inches(0.55), Inches(6.3), Inches(12.2), Inches(0.5),
                 "spec v2.0 大改动：原本独立 QA SIT stage → 取消并入 dev",
                 size_pt=12, color=GRAY_500, align=PP_ALIGN.CENTER)
    return s


def build_slide_97_anti_patterns(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 反模式对照表 · 7 条")
    _add_centered_image(s, "G5-anti-patterns.png")
    return s


def build_slide_98_keep_3(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 迁移到自己栈 · 保留 3 件事")
    items = [
        ("①  4 层 hook 防御",     "硬阻断危险命令 + 密钥泄漏 + prompt injection + commit 前再扫", CORAL),
        ("②  DoD 9 项 checklist",  "PBI 5 + Sprint 4 · 不达标任务不能 done", GOLD),
        ("③  AC 摘录派单",        "PRD AC 必进派单消息 · 6 段 schema · hook 校验缺段", NAVY),
    ]
    for i, (head, body, color) in enumerate(items):
        y = Inches(1.8 + i * 1.6)
        _add_card(s, Inches(0.55), y, Inches(12.2), Inches(1.4),
                  fill=CORAL_LIGHT if color == CORAL else WHITE,
                  border=color, accent=color)
        _add_textbox(s, Inches(0.85), y + Inches(0.2), Inches(5.5), Inches(0.7),
                     head, size_pt=24, bold=True, color=color)
        _add_textbox(s, Inches(0.85), y + Inches(0.9), Inches(11.5), Inches(0.45),
                     body, size_pt=14, color=GRAY_700)
    _add_textbox(s, Inches(0.55), Inches(6.7), Inches(12.2), Inches(0.4),
                 "这 3 件无关具体技术栈 · 任何项目都能直接抄走",
                 size_pt=14, color=NAVY, align=PP_ALIGN.CENTER, bold=True)
    return s


def build_slide_99_replace_3(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 迁移到自己栈 · 可替换 3 件事")
    items = [
        ("①  后端栈",     "FastAPI + PG → 换 Django / Express / Spring 等任意",     "技术栈选型 ≠ 团队协作"),
        ("②  LLM 厂商",   "豆包 → 换 OpenAI / Claude / 国产任何家",                "skill agf-wiring-multi-llm-sdk 已抽象"),
        ("③  同事数量裁剪", "14 同事 → 小项目可砍到 7（去掉 miniapp 3 + post-launch 1 + ml-engineer + content-writer + uiux-designer）", "保留：PL / TL / FE / BE / AI / reviewer / qa"),
    ]
    replace_colors = [NAVY, GREEN, BLUE_ACCENT]  # 3 卡片 = NAVY / GREEN / BLUE 轮换
    for i, (head, body, why) in enumerate(items):
        y = Inches(1.7 + i * 1.65)
        c = replace_colors[i]
        _add_card(s, Inches(0.55), y, Inches(12.2), Inches(1.5),
                  fill=WHITE, border=c, accent=c)
        _add_textbox(s, Inches(0.85), y + Inches(0.15), Inches(4.5), Inches(0.6),
                     head, size_pt=22, bold=True, color=c)
        _add_textbox(s, Inches(0.85), y + Inches(0.75), Inches(11.5), Inches(0.4),
                     body, size_pt=13, color=GRAY_700)
        _add_textbox(s, Inches(0.85), y + Inches(1.15), Inches(11.5), Inches(0.3),
                     f"{why}", size_pt=11, color=GRAY_500)
    return s


def build_slide_100_llm_fallback(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 国产 LLM fallback 机制 · 4 厂商 cost 对照")
    _add_textbox(s, Inches(0.55), Inches(1.5), Inches(12.2), Inches(0.5),
                 "💰 4 厂商定价（2026-05，$/M token · input/output）：",
                 size_pt=16, bold=True, color=NAVY)
    vendors = [
        ("DeepSeek V4-Pro",        "$0.14 / $0.28",  "纯文本 SOTA · 最便宜"),
        ("Doubao-Seed-2.0-Pro",    "$0.47 / $2.37",  "原生多模态 · 全栈友好 ⭐"),
        ("Qwen3.6-Max",             "$0.50 / $2.00",  "阿里生态 · VL 强"),
        ("MiniMax M2.7",            "$0.50 / $2.50",  "长上下文 · 角色扮演"),
    ]
    for i, (name, price, note) in enumerate(vendors):
        y = Inches(2.2 + i * 0.7)
        color = CORAL if "⭐" in note else GRAY_500
        _add_card(s, Inches(0.55), y, Inches(12.2), Inches(0.6),
                  fill=WHITE, border=color, accent=color)
        _add_textbox(s, Inches(0.85), y + Inches(0.1), Inches(4.0), Inches(0.4),
                     name, size_pt=15, bold=True, color=NAVY)
        _add_textbox(s, Inches(5.0), y + Inches(0.1), Inches(3.0), Inches(0.4),
                     price, size_pt=14, color=GRAY_700)
        _add_textbox(s, Inches(8.2), y + Inches(0.1), Inches(4.5), Inches(0.4),
                     note, size_pt=13, color=NAVY if "⭐" in note else GRAY_700)
    # cost guardrail
    _add_textbox(s, Inches(0.55), Inches(5.4), Inches(12.2), Inches(0.5),
                 "cost guardrail（agf-wiring-multi-llm-sdk 强制点 ④）：",
                 size_pt=16, bold=True, color=CORAL)
    _add_textbox(s, Inches(0.85), Inches(5.95), Inches(12.0), Inches(0.4),
                 "▎ 调用前估算 cost · 超 AC 预算自动 fail + 通知 PL",
                 size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(0.85), Inches(6.4), Inches(12.0), Inches(0.4),
                 "▎ Pro → Lite → Mini 同厂商 fallback · 跨厂商演练单独写故障注入",
                 size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(0.85), Inches(6.85), Inches(12.0), Inches(0.4),
                 "▎ 国产比国际 15-30× 便宜 · DeepSeek cache 命中 $0.014/M（再 10× 折扣）",
                 size_pt=13, color=GRAY_700)
    return s


def build_slide_101_miniapp_variants(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · 多模态 / 微信小程序变体")
    _add_textbox(s, Inches(0.55), Inches(1.6), Inches(12.2), Inches(0.6),
                 "🔀 AGF 的 14 同事支持两种变体（按需启用）：",
                 size_pt=18, bold=True, color=NAVY, align=PP_ALIGN.CENTER)
    # 多模态
    _add_card(s, Inches(0.55), Inches(2.6), Inches(6.0), Inches(3.8),
              fill=WHITE, border=CORAL, accent=CORAL)
    _add_textbox(s, Inches(0.85), Inches(2.75), Inches(5.5), Inches(0.5),
                 "🎨 多模态变体", size_pt=22, bold=True, color=CORAL)
    multi_items = [
        "ml-engineer 主导",
        "Vision + LLM + 文生图 / 文生视频",
        "评测三指标（准确率 / 相关性 / 风格符合度）",
        "适合：产品图生成 / AI 助理 / 内容创作",
        "本主线（旅游明信片）就是这种",
    ]
    for i, item in enumerate(multi_items):
        _add_textbox(s, Inches(1.05), Inches(3.35 + i * 0.55), Inches(5.3), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    # 小程序
    _add_card(s, Inches(6.75), Inches(2.6), Inches(6.0), Inches(3.8),
              fill=WHITE, border=GOLD, accent=GOLD)
    _add_textbox(s, Inches(7.05), Inches(2.75), Inches(5.5), Inches(0.5),
                 "微信小程序变体", size_pt=22, bold=True, color=GOLD)
    miniapp_items = [
        "miniapp-dev 主导（替代 frontend-dev）",
        "miniapp-code-reviewer 独立 review",
        "miniapp-qa-engineer 真机抽测",
        "适合：C 端工具型小程序 / 企业内部工具",
        "Web 变体的 'MiniApp Mode' 启动",
    ]
    for i, item in enumerate(miniapp_items):
        _add_textbox(s, Inches(7.25), Inches(3.35 + i * 0.55), Inches(5.3), Inches(0.45),
                     f"▎ {item}", size_pt=13, color=GRAY_700)
    _add_textbox(s, Inches(0.55), Inches(6.6), Inches(12.2), Inches(0.4),
                 "两种变体共用 4 层 hook + DoD + skill 路径（无需重做）",
                 size_pt=13, color=NAVY, align=PP_ALIGN.CENTER, bold=True)
    return s


def build_slide_102_github_actions(prs):
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · Issue 自动化 + GitHub Actions · claude-code.yml")
    # PNG 1506×812 (ratio 1.85) · 按 height 5.8 居中
    _add_centered_image(s, "A17-github-actions.png", top_inch=1.4, height_inch=5.8)
    return s


def build_slide_103_ai_native_vs_agf(prs):
    """v1.4 新增：AI-Native 业界研究 vs AGF · 10 项对照 + 关键数据墙
    业界对标 · 让学员明白 AGF 设计与"AI-Native 转型"行业研究思路重合
    """
    s = prs.slides.add_slide(prs.slide_layouts[3])
    _title(s, "§8 · AI-Native 转型 10 项 · AGF 命中度对照（2025 业界研究综述）")

    # ===== 上方：4 个业界研究关键数据墙（chip 风格）=====
    metrics = [
        ("70%", "公司部署 AI 但完全没改角色", CORAL),
        ("5-15% vs 5-7×", "普通公司 vs 头部企业 产能差距", GOLD),
        ("51% · 60×", "金融案例：merge ↑51% · agent 调用 ↑60×（重组织后）", NAVY),
        ("3-5 年", "诚实转型 timeline（非 12 个月营销话术）", GREEN),
    ]
    chip_w = 3.0
    for i, (num, label, c) in enumerate(metrics):
        x = Inches(0.55 + i * (chip_w + 0.07))
        _add_card(s, x, Inches(1.4), Inches(chip_w), Inches(1.05),
                  fill=c, border=c)
        _add_textbox(s, x, Inches(1.45), Inches(chip_w), Inches(0.45),
                     num, size_pt=22, bold=True, color=WHITE,
                     align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
        _add_textbox(s, x + Inches(0.1), Inches(1.93), Inches(chip_w - 0.2), Inches(0.5),
                     label, size_pt=10, color=WHITE,
                     align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)

    # ===== 下方：10 行对照表 =====
    _add_textbox(s, Inches(0.55), Inches(2.65), Inches(12.2), Inches(0.4),
                 "AGF 10 项命中度对照（强命中 / 不同取舍 / 缺失补 v1.4）",
                 size_pt=13, bold=True, color=NAVY, align=PP_ALIGN.CENTER)

    # 表头
    headers = [("AI-Native 价值点", 0.55, 5.5, NAVY),
               ("AGF 命中度",      6.15, 1.6, NAVY),
               ("取舍 / 备注",    7.85, 4.9, NAVY)]
    for (h, x, w, c) in headers:
        _add_card(s, Inches(x), Inches(3.1), Inches(w), Inches(0.45),
                  fill=c, border=c)
        _add_textbox(s, Inches(x), Inches(3.13), Inches(w), Inches(0.4),
                     h, size_pt=12, bold=True, color=WHITE,
                     align=PP_ALIGN.CENTER)

    # 10 行数据
    rows = [
        ("重定义角色（70% 公司不改）",       "强命中", "14 角色定义 · .claude/agents/*.md",        GREEN),
        ("Spec-driven 派单",                   "强命中", "PRD §4 AC + 6 段派单 schema",              GREEN),
        ("Review bottleneck 先修",             "强命中", "双 verdict + SIT Audit + 自动 quality gate", GREEN),
        ("Agent orchestration",                "命中",   "product-lead SendMessage 编排 14 同事",   GREEN),
        ("Living systems · model drift",       "命中",   "evals/ 季度漂移检测",                       GREEN),
        ("Data-centric · 数据 > 代码",         "命中",   "F1 多模态雷达 + AC 量化",                   GREEN),
        ("3-5 人小 pod",                       "不同",    "14 同事 + worktree 异步 ≈ 小 pod + 专业化",  GOLD),
        ("PM 直接 prototype code",            "不命中", "AGF PRD 仍 markdown · 文字 spec 更可审",  CORAL),
        ("QA merge into pod",                  "不命中", "qa-engineer 独立 · 避免裁判+球员",          CORAL),
        ("3 层度量框架（output/economic/resilience）", "缺", "v1.4 §1/§4 takeaway 已补行业数据点引用", CORAL),
    ]
    for i, (mk, agf, note, c) in enumerate(rows):
        y = Inches(3.6 + i * 0.34)
        # 列 1
        _add_textbox(s, Inches(0.65), y, Inches(5.4), Inches(0.32),
                     mk, size_pt=10, color=GRAY_700,
                     anchor=MSO_ANCHOR.MIDDLE)
        # 列 2 (命中度 chip)
        _add_card(s, Inches(6.25), y + Inches(0.02), Inches(1.45), Inches(0.28),
                  fill=c, border=c)
        _add_textbox(s, Inches(6.25), y, Inches(1.45), Inches(0.32),
                     agf, size_pt=10, bold=True, color=WHITE,
                     align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
        # 列 3
        _add_textbox(s, Inches(7.95), y, Inches(4.8), Inches(0.32),
                     note, size_pt=10, color=GRAY_700,
                     anchor=MSO_ANCHOR.MIDDLE)
        # 行底分隔线
        if i < len(rows) - 1:
            from pptx.enum.shapes import MSO_SHAPE as _MS
            sep = s.shapes.add_shape(_MS.RECTANGLE,
                                      Inches(0.55), y + Inches(0.32),
                                      Inches(12.2), Inches(0.005))
            sep.fill.solid(); sep.fill.fore_color.rgb = GRAY_300
            sep.line.fill.background()

    # 底部：source + 结论
    _add_textbox(s, Inches(0.55), Inches(7.05), Inches(12.2), Inches(0.35),
                 "结论：AGF 设计独立但与「AI-Native 转型」业界研究思路高度重合 · 6 强命中 + 1 命中 + 2 不同取舍 + 1 缺已补",
                 size_pt=12, bold=True, color=CORAL, align=PP_ALIGN.CENTER)
    _add_textbox(s, Inches(0.55), Inches(7.4), Inches(12.2), Inches(0.3),
                 "来源：2025 业界 AI-Native 转型研究综述（多源公开报告 / 顶级咨询 / 学术分析整合）",
                 size_pt=9, color=GRAY_500, align=PP_ALIGN.CENTER)
    return s


def build(prs):
    """构建 §8 10 张内容 slide (v1.4: 原 9 张 + 新增 AI-Native 业界对标 1 张)"""
    build_slide_94_creed_vs_wiki(prs)
    build_slide_95_14_vs_1(prs)
    build_slide_96_dev_sit_vs_qa(prs)
    build_slide_97_anti_patterns(prs)
    build_slide_98_keep_3(prs)
    build_slide_99_replace_3(prs)
    build_slide_100_llm_fallback(prs)
    build_slide_101_miniapp_variants(prs)
    build_slide_102_github_actions(prs)
    build_slide_103_ai_native_vs_agf(prs)   # v1.4 新增 · AI-Native 业界对标
