"""Transparent scenario analysis for SHWRP-2026-022.

All monetary values and scores are author-defined assumptions for sensitivity
analysis. They are not observations, forecasts, market averages, or records of
any identifiable platform or supplier.
"""
from __future__ import annotations

import json
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs"
FIG = OUT / "figures"
OUT.mkdir(exist_ok=True)
FIG.mkdir(exist_ok=True)

FONT = ROOT.parents[1] / "public" / "fonts" / "NotoSansTC-Regular.ttf"
from matplotlib import font_manager
font_manager.fontManager.addfont(str(FONT))
plt.rcParams["font.family"] = font_manager.FontProperties(fname=str(FONT)).get_name()
plt.rcParams["axes.unicode_minus"] = False

sc = pd.read_csv(ROOT / "scenario-assumptions.csv")
sc["revenue_per_order"] = sc.basket_twd * sc.commission_rate
sc["payment_fee_per_order"] = sc.basket_twd * sc.payment_fee_rate
sc["reward_cost_per_order"] = sc.basket_twd * sc.reward_rate
sc["order_contribution"] = (sc.revenue_per_order - sc.payment_fee_per_order - sc.pickup_subsidy_per_order - sc.support_cost_per_order - sc.reward_cost_per_order)
sc["member_contribution"] = sc.membership_fee_twd + sc.orders_per_member_month * sc.order_contribution - sc.member_service_cost_month
sc["break_even_members"] = np.where(sc.member_contribution > 0, np.ceil(sc.fixed_cost_month / sc.member_contribution), np.nan)
sc.to_csv(OUT / "platform-scenario-results.csv", index=False, encoding="utf-8-sig")

sup = pd.read_csv(ROOT / "supplier-cost-scenarios.csv")
sup["settlement_twd"] = sup.consumer_price_twd - sup.platform_commission_twd
sup["supplier_contribution_twd"] = sup.settlement_twd - sup[["production_cost_twd", "packaging_twd", "picking_twd", "no_show_return_reserve_twd", "compliance_allocation_twd"]].sum(axis=1)
sup.to_csv(OUT / "supplier-contribution-results.csv", index=False, encoding="utf-8-sig")

risk = pd.read_csv(ROOT / "risk-matrix.csv")
risk["score"] = risk.probability * risk.impact
risk.to_csv(OUT / "risk-priority-results.csv", index=False, encoding="utf-8-sig")

# Sensitivity grid for the coordinated-preorder structure.
fees = np.arange(79, 221, 10)
orders = np.round(np.arange(0.25, 1.01, 0.05), 2)
rows = []
base = sc.loc[sc.scenario == "協調預購"].iloc[0]
for fee in fees:
    for q in orders:
        contribution = fee + q * base.order_contribution - base.member_service_cost_month
        rows.append({"membership_fee_twd": fee, "orders_per_member_month": q, "member_contribution_twd": contribution, "break_even_members": np.ceil(base.fixed_cost_month / contribution) if contribution > 0 else np.nan})
sens = pd.DataFrame(rows)
sens.to_csv(OUT / "sensitivity-grid.csv", index=False, encoding="utf-8-sig")

colors = ["#8e4b2a", "#2f6b4f", "#b4553f"]

fig, ax = plt.subplots(figsize=(10, 5.5))
components = pd.DataFrame({
    "抽成收入": sc.revenue_per_order.to_numpy(),
    "支付費": -sc.payment_fee_per_order.to_numpy(),
    "取貨補貼": -sc.pickup_subsidy_per_order.to_numpy(),
    "客服": -sc.support_cost_per_order.to_numpy(),
    "回饋": -sc.reward_cost_per_order.to_numpy(),
}, index=sc.scenario.to_numpy())
x = np.arange(len(sc))
width = 0.15
for idx, (col, color) in enumerate(zip(components.columns, ["#2f6b4f", "#c98263", "#ddad84", "#9d826b", "#b4553f"])):
    ax.bar(x + (idx - 2) * width, components[col], width=width, label=col, color=color)
ax.axhline(0, color="#30241e", lw=1)
ax.set_xticks(x, sc.scenario)
ax.set_ylabel("每筆訂單平台貢獻（情境假設，元）")
ax.set_title("圖1　訂單層級收入與變動成本結構")
ax.legend(ncol=5, fontsize=8, loc="lower center")
fig.tight_layout(); fig.savefig(FIG / "figure-1-order-unit-economics.png", dpi=210); plt.close(fig)

fig, ax = plt.subplots(figsize=(9, 5.2))
bars = ax.bar(sc.scenario, sc.break_even_members, color=colors)
ax.bar_label(bars, fmt="%.0f")
ax.set_ylabel("每月損益兩平所需付費會員數")
ax.set_title("圖2　三種透明情境的會員損益兩平門檻")
ax.text(.5, -.18, "僅為模型輸出，不是市場預測", transform=ax.transAxes, ha="center", color="#6d625a")
fig.tight_layout(); fig.savefig(FIG / "figure-2-break-even-members.png", dpi=210); plt.close(fig)

pivot = sens.pivot(index="orders_per_member_month", columns="membership_fee_twd", values="break_even_members")
fig, ax = plt.subplots(figsize=(11, 5.8))
im = ax.imshow(pivot, aspect="auto", origin="lower", cmap="YlGnBu_r")
ax.set_xticks(range(len(pivot.columns)), pivot.columns, rotation=45)
ax.set_yticks(range(0, len(pivot.index), 2), [f"{x:.2f}" for x in pivot.index[::2]])
ax.set_xlabel("月會員費（情境假設，元）"); ax.set_ylabel("每會員月訂單數")
ax.set_title("圖3　會員費與使用頻率對損益兩平會員數的敏感度")
fig.colorbar(im, ax=ax, label="損益兩平會員數")
fig.tight_layout(); fig.savefig(FIG / "figure-3-membership-sensitivity.png", dpi=210); plt.close(fig)

fig, ax = plt.subplots(figsize=(9, 5.2))
bars = ax.bar(sup.scenario, sup.supplier_contribution_twd, color=["#b4553f", "#2f6b4f"])
ax.bar_label(bars, fmt="%.0f")
ax.set_ylabel("供應商每筆貢獻（情境假設，元）")
ax.set_title("圖4　批次協調是否能把履約節省留給供應商")
fig.tight_layout(); fig.savefig(FIG / "figure-4-supplier-contribution.png", dpi=210); plt.close(fig)

fig, ax = plt.subplots(figsize=(9, 6.2))
palette = {"平台":"#8e4b2a", "供應商":"#477a65", "共同":"#c29055"}
for _, row in risk.iterrows():
    ax.scatter(row.probability, row.impact, s=row.score*38, color=palette[row.primary_owner], alpha=.78, edgecolor="white")
    ax.text(row.probability+.05, row.impact+.04, row.risk, fontsize=8)
ax.set(xlim=(0.7,5.5), ylim=(0.7,5.5), xticks=range(1,6), yticks=range(1,6), xlabel="發生可能性（分析者評分）", ylabel="影響程度（分析者評分）", title="圖5　供應商合作風險優先矩陣")
ax.grid(alpha=.22)
fig.tight_layout(); fig.savefig(FIG / "figure-5-risk-matrix.png", dpi=210); plt.close(fig)

allocation = pd.DataFrame([[2,1,1],[2,1,1],[1,2,1],[1,1,2],[2,2,1],[1,2,1]], index=["會員招募與客服","商品資料與宣稱","供應與批號","付款結算","取貨與未領","退款與召回"], columns=["平台","供應商","共同"])
fig, ax = plt.subplots(figsize=(8.8, 5.4))
im = ax.imshow(allocation, cmap=matplotlib.colors.ListedColormap(["#f2e9df", "#477a65"]), vmin=1, vmax=2, aspect="auto")
ax.set_xticks(range(3), allocation.columns); ax.set_yticks(range(len(allocation)), allocation.index)
for i in range(len(allocation)):
    for j in range(3): ax.text(j, i, "主責" if allocation.iloc[i,j]==2 else "協作", ha="center", va="center", color="white" if allocation.iloc[i,j]==2 else "#4b3a31")
ax.set_title("圖6　合作契約的責任配置範本")
fig.tight_layout(); fig.savefig(FIG / "figure-6-governance-allocation.png", dpi=210); plt.close(fig)

result = {
    "study_type": "anonymous scenario analysis",
    "platform_scenarios": sc[["scenario","order_contribution","member_contribution","break_even_members"]].round(2).to_dict("records"),
    "supplier_contribution": sup[["scenario","supplier_contribution_twd"]].to_dict("records"),
    "supplier_coordination_gain_twd": float(sup.supplier_contribution_twd.iloc[1] - sup.supplier_contribution_twd.iloc[0]),
    "risk_count": int(len(risk)),
    "high_risk_count": int((risk.score >= 16).sum()),
    "assumption_notice": "All values are researcher-defined assumptions; not observed company data or forecasts."
}
(ROOT / "analysis-results.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
