#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
part5 情景模型复算脚本（苹果 Agent 风险研究 · 第5组）
读取 model_assumptions.csv，用同一套参数复算报告 headline 数字。
运行: python3 model.py
输出: 品类×地区佣金池、绕过率路径、地区乘子、佣金损失、TAC、利润侵蚀比、敏感性。
"""

import csv
from pathlib import Path

HERE = Path(__file__).resolve().parent

def load_params():
    p = {}
    with open(HERE / "model_assumptions.csv", encoding="utf-8-sig") as f:
        for row in csv.DictReader(f):
            p[row["parameter"]] = row
    return p

P = load_params()

def v(name, scen):
    return float(P[name][scen])

CATS = ["game", "sub", "other"]
CAT_CN = {"game": "游戏", "sub": "订阅", "other": "其他"}
REGS = ["us", "row", "cn", "eu"]
REG_CN = {"us": "美国", "row": "其他地区", "cn": "中国", "eu": "欧盟"}

# ---- 品类×地区佣金池（独立性假设） ----
CAT_POOL = {c: v(f"pool_cat_{c}", "base") for c in CATS}
REG_POOL = {r: v(f"pool_reg_{r}", "base") for r in REGS}
TOT_CAT = sum(CAT_POOL.values())
POOL = {(c, r): REG_POOL[r] * CAT_POOL[c] / TOT_CAT for c in CATS for r in REGS}

def compute(h, scen, ov=None):
    """核心模型。h: 年数(3/5); scen: conservative/base/aggressive; ov: 参数覆盖(敏感性用)。"""
    ov = ov or {}
    def gv(name):
        return ov[name] if name in ov else v(name, scen)

    def bypass(c):  # 线性收敛到5年目标
        now = gv(f"bypass_now_{c}")
        tgt = gv(f"bypass_target_{c}_5y")
        return now + (tgt - now) * (h / 5.0)

    def m(r):  # 地区侵蚀乘子
        if r == "us":
            if "m_us" in ov:
                return ov["m_us"]
            if scen != "conservative":
                return gv("m_us_zero_rule")
            # 保守分支：最高法推翻 0 佣金令，时间加权
            t0, tr = gv("horizon_start"), gv("reversal_date")
            m0, m1 = gv("m_us_zero_rule"), gv("m_us_post_reversal")
            return ((tr - t0) * m0 + (t0 + h - tr) * m1) / h
        return gv({"eu": "m_eu", "cn": "m_cn"}.get(r, "m_row"))

    comm = sum(POOL[(c, r)] * bypass(c) * m(r) for c in CATS for r in REGS)
    tac = gv("tac_loss")
    off = gv(f"miniprogram_offset_{h}y")
    return {"comm": comm, "tac": tac, "offset": off, "net": comm + tac - off,
            "bypass": {c: bypass(c) for c in CATS},
            "m": {r: m(r) for r in REGS}}

def ratios(net):
    gp, op = v("services_gp", "base"), v("op_profit", "base")
    lo, hi = v("services_op_lo", "base"), v("services_op_hi", "base")
    return {"services_gp": net / gp, "op": net / op,
            "services_op_lo": net / lo, "services_op_hi": net / hi}

def show(title, d):
    r = ratios(d["net"])
    print(f"{title}: 佣金 {d['comm']:.2f} + TAC {d['tac']:.2f} - 小程序对冲 {d['offset']:.2f} "
          f"= 净毛利损失 {d['net']:.2f} $B | "
          f"Services毛利 {r['services_gp']*100:.1f}% | 公司经营利润 {r['op']*100:.1f}% | "
          f"Services经营利润(估) {r['services_op_hi']*100:.1f}–{r['services_op_lo']*100:.1f}%")

if __name__ == "__main__":
    print("=== 品类×地区佣金池 ($B, 独立性假设) ===")
    for r in REGS:
        row = "  ".join(f"{CAT_CN[c]} {POOL[(c,r)]:.2f}" for c in CATS)
        print(f"  {REG_CN[r]}({REG_POOL[r]:.1f}): {row}")

    print("\n=== 保守情景美国乘子(时间加权) ===")
    for h in (3, 5):
        print(f"  {h}年: m_us = {compute(h, 'conservative')['m']['us']:.3f}")

    print("\n=== 绕过率路径 ===")
    for scen, cn in [("conservative", "保守"), ("base", "基准"), ("aggressive", "激进")]:
        for h in (3, 5):
            b = compute(h, scen)["bypass"]
            print(f"  {cn} {h}年: " + "  ".join(f"{CAT_CN[c]} {b[c]*100:.1f}%" for c in CATS))

    print("\n=== Headline: 净毛利损失 (目标年份年化 run-rate, $B) ===")
    for scen, cn in [("conservative", "保守"), ("base", "基准"), ("aggressive", "激进")]:
        for h in (3, 5):
            show(f"  {cn} {h}年", compute(h, scen))

    print("\n=== 构成拆解: 基准5年佣金损失按品类/地区 ($B) ===")
    d = compute(5, "base", {})
    # 重算分项
    ov = {}
    def gv2(name): return v(name, "base")
    for c in CATS:
        now, tgt = gv2(f"bypass_now_{c}"), gv2(f"bypass_target_{c}_5y")
        b = now + (tgt - now) * 1.0
        parts = {r: POOL[(c, r)] * b * ({"us": 1.0, "eu": 0.42, "cn": 0.0, "row": 0.70}[r]) for r in REGS}
        print(f"  {CAT_CN[c]}(b={b*100:.0f}%): 合计 {sum(parts.values()):.2f} = " +
              " + ".join(f"{REG_CN[r]}{parts[r]:.2f}" for r in REGS))

    print("\n=== 敏感性: 以基准5年(净 13.46$B)为锚, 单因素变动 ===")
    base5 = compute(5, "base")["net"]
    m_us_cons5 = compute(5, "conservative")["m"]["us"]
    sens = [
        (f"美国0%被推翻(m_us 1.0→{m_us_cons5:.2f})", {"m_us": m_us_cons5}),
        ("游戏天花板 55%→45%", {"bypass_target_game_5y": 0.45}),
        ("游戏天花板 55%→65%", {"bypass_target_game_5y": 0.65}),
        ("TAC传导系数 1.0→0.7", {"tac_loss": 2.1}),
        ("TAC传导系数 1.0→1.3", {"tac_loss": 3.9}),
        ("订阅天花板 70%→60%", {"bypass_target_sub_5y": 0.60}),
        ("订阅天花板 70%→80%", {"bypass_target_sub_5y": 0.80}),
    ]
    for name, over in sens:
        net = compute(5, "base", over)["net"]
        print(f"  {name}: 净 {net:.2f}$B  (Δ {net-base5:+.2f}$B, {net/base5-1:+.1%})")
