from __future__ import annotations

import csv
import json
from collections import Counter
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import font_manager


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

FONT = ROOT.parents[1] / "public" / "fonts" / "NotoSansTC-Regular.ttf"
if FONT.exists():
    font_manager.fontManager.addfont(str(FONT))
    plt.rcParams["font.family"] = "Noto Sans TC"
plt.rcParams["axes.unicode_minus"] = False
plt.rcParams["figure.dpi"] = 180

COLORS = {
    "brown": "#6f3519",
    "tan": "#c78654",
    "cream": "#f4e8dc",
    "green": "#55735c",
    "gold": "#b88a3b",
    "ink": "#2d211b",
    "muted": "#7d7068",
}


def read_csv(name: str) -> list[dict[str, str]]:
    with (ROOT / name).open("r", encoding="utf-8-sig", newline="") as handle:
        return list(csv.DictReader(handle))


def write_csv(name: str, rows: list[dict], fieldnames: list[str]) -> None:
    with (OUTPUTS / name).open("w", encoding="utf-8-sig", newline="") as handle:
        writer = csv.DictWriter(handle, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)


documents = read_csv("evidence-documents.csv")
modes = read_csv("mode-framework.csv")
gates = read_csv("stage-gates.csv")
scenario_variables = read_csv("scenario-variable-template.csv")

theme_fields = [
    ("demand_risk", "需求／取消"),
    ("production_risk", "生產／天候"),
    ("price_risk", "價格／收入"),
    ("quality_risk", "品質／食安"),
    ("power_risk", "權力不對稱"),
    ("data_rights", "資料權利"),
    ("labor_risk", "勞動負荷"),
    ("contract_governance", "契約治理"),
    ("insurance_risk_transfer", "保險／移轉"),
    ("traceability", "追溯／驗證"),
    ("exit_dispute", "退出／爭議"),
]

theme_summary: list[dict] = []
for field, label in theme_fields:
    official_count = sum(
        int(row[field]) for row in documents if row["official"] == "1"
    )
    academic_count = sum(
        int(row[field]) for row in documents if row["peer_reviewed"] == "1"
    )
    theme_summary.append(
        {
            "theme": label,
            "official_documents": official_count,
            "academic_documents": academic_count,
            "total_documents": official_count + academic_count,
        }
    )
write_csv(
    "evidence-theme-summary.csv",
    theme_summary,
    ["theme", "official_documents", "academic_documents", "total_documents"],
)

corpus_counter = Counter((row["source_group"], row["source_kind"]) for row in documents)
corpus_summary = [
    {"source_group": group, "source_kind": kind, "documents": count}
    for (group, kind), count in sorted(corpus_counter.items())
]
write_csv(
    "corpus-summary.csv",
    corpus_summary,
    ["source_group", "source_kind", "documents"],
)

mode_summary = [
    {
        "mode_id": row["mode_id"],
        "mode": row["mode"],
        "control_level": int(row["control_level"]),
        "fixed_capital": int(row["fixed_capital"]),
        "working_capital": int(row["working_capital"]),
        "production_exposure": int(row["production_exposure"]),
        "inventory_exposure": int(row["inventory_exposure"]),
        "quality_control": int(row["quality_control"]),
        "reversibility": int(row["reversibility"]),
        "farmer_power_risk": int(row["farmer_power_risk"]),
        "legal_complexity": int(row["legal_complexity"]),
        "score_status": row["score_status"],
    }
    for row in modes
]
write_csv(
    "mode-score-summary.csv",
    mode_summary,
    list(mode_summary[0]),
)

source_log = [
    {
        "source_id": row["document_id"],
        "source_group": row["source_group"],
        "title": row["title"],
        "year": row["year"],
        "url": row["url"],
        "retrieved_at": row["retrieved_at"],
        "public_distribution": "書目、網址與研究者編碼；不散布第三方全文",
        "rights_status": row["license_or_terms"],
    }
    for row in documents
]
with (ROOT / "source-log.csv").open(
    "w", encoding="utf-8-sig", newline=""
) as handle:
    writer = csv.DictWriter(handle, fieldnames=list(source_log[0]))
    writer.writeheader()
    writer.writerows(source_log)

# Figure 1: corpus composition
fig, ax = plt.subplots(figsize=(9.2, 5.4))
groups = ["臺灣官方", "國際學術"]
kinds = sorted({row["source_kind"] for row in documents})
bottom = np.zeros(len(groups))
palette = plt.cm.YlGn(np.linspace(0.35, 0.85, len(kinds)))
for color, kind in zip(palette, kinds):
    values = [
        sum(1 for row in documents if row["source_group"] == group and row["source_kind"] == kind)
        for group in groups
    ]
    if any(values):
        ax.bar(groups, values, bottom=bottom, label=kind, color=color, edgecolor="white")
        bottom += np.array(values)
ax.set_ylabel("文件數")
ax.set_title("圖1　研究證據庫組成（目的性選取，非母體抽樣）")
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.12), ncol=3, frameon=False)
ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
fig.savefig(FIGURES / "figure-1-corpus-composition.png", bbox_inches="tight")
plt.close(fig)

# Figure 2: theme coverage
fig, ax = plt.subplots(figsize=(10.5, 6.8))
labels = [row["theme"] for row in theme_summary]
official_values = [row["official_documents"] for row in theme_summary]
academic_values = [row["academic_documents"] for row in theme_summary]
y = np.arange(len(labels))
ax.barh(y, official_values, color=COLORS["green"], label="臺灣官方")
ax.barh(y, academic_values, left=official_values, color=COLORS["gold"], label="國際學術")
ax.set_yticks(y, labels)
ax.invert_yaxis()
ax.set_xlabel("提及該主題的文件數（0/1編碼）")
ax.set_title("圖2　文件對風險與治理主題的可觀察覆蓋")
ax.legend(frameon=False)
ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
fig.savefig(FIGURES / "figure-2-theme-coverage.png", bbox_inches="tight")
plt.close(fig)

# Figure 3: normative mode matrix
matrix_fields = [
    ("production_exposure", "生產曝險"),
    ("inventory_exposure", "庫存曝險"),
    ("working_capital", "週轉資金"),
    ("farmer_power_risk", "農民權力風險"),
    ("legal_complexity", "法遵複雜度"),
    ("quality_control", "品質控制"),
]
matrix = np.array(
    [[int(row[field]) for field, _ in matrix_fields] for row in modes],
    dtype=float,
)
fig, ax = plt.subplots(figsize=(10.5, 5.4))
im = ax.imshow(matrix, cmap="YlOrBr", vmin=1, vmax=4, aspect="auto")
ax.set_xticks(range(len(matrix_fields)), [label for _, label in matrix_fields])
ax.set_yticks(range(len(modes)), [row["mode"] for row in modes])
for i in range(matrix.shape[0]):
    for j in range(matrix.shape[1]):
        ax.text(j, i, str(int(matrix[i, j])), ha="center", va="center", color=COLORS["ink"])
ax.set_title("圖3　四種模式的規範性序位矩陣（1低、4高；非企業實測）")
fig.colorbar(im, ax=ax, fraction=0.035, pad=0.03)
fig.tight_layout()
fig.savefig(FIGURES / "figure-3-mode-matrix.png", bbox_inches="tight")
plt.close(fig)

# Figure 4: control-capital-reversibility trade-off
fig, ax = plt.subplots(figsize=(9.0, 6.2))
for row in modes:
    x = int(row["fixed_capital"])
    yv = int(row["control_level"])
    size = int(row["reversibility"]) * 320
    ax.scatter(x, yv, s=size, alpha=0.68, color=COLORS["tan"], edgecolor=COLORS["brown"])
    ax.annotate(row["mode"], (x, yv), xytext=(8, 5), textcoords="offset points")
ax.set_xlim(0.5, 4.5)
ax.set_ylim(0.5, 4.5)
ax.set_xticks(range(1, 5))
ax.set_yticks(range(1, 5))
ax.set_xlabel("固定資本需求（規範性序位）")
ax.set_ylabel("供應鏈控制（規範性序位）")
ax.set_title("圖4　控制、固定資本與可逆性的取捨\n氣泡越大表示較可逆；序位不是獲利或風險機率")
ax.grid(alpha=0.2)
ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
fig.savefig(FIGURES / "figure-4-control-capital-tradeoff.png", bbox_inches="tight")
plt.close(fig)

# Figure 5: stage-gate path
fig, ax = plt.subplots(figsize=(12.2, 4.8))
ax.axis("off")
nodes = [
    (0.02, "純行銷平台", "先量得留存、CM2與供應履約"),
    (0.27, "有限契作", "設定承購上限、價格與驗收"),
    (0.52, "共同生產", "累積完整期作、批次與農戶淨收益"),
    (0.77, "完全自營", "保守及歉收情境均優於外包"),
]
for x, title, subtitle in nodes:
    ax.add_patch(
        plt.Rectangle((x, 0.36), 0.19, 0.35, facecolor=COLORS["cream"], edgecolor=COLORS["brown"], lw=1.2)
    )
    ax.text(x + 0.095, 0.58, title, ha="center", va="center", weight="bold", fontsize=12)
    ax.text(x + 0.095, 0.45, subtitle, ha="center", va="center", fontsize=8.8, wrap=True)
for index in range(3):
    start = nodes[index][0] + 0.19
    end = nodes[index + 1][0]
    ax.annotate("", xy=(end, 0.535), xytext=(start, 0.535), arrowprops=dict(arrowstyle="->", lw=1.5, color=COLORS["green"]))
    ax.text((start + end) / 2, 0.63, f"G{index + 1}", ha="center", color=COLORS["green"], weight="bold")
ax.text(0.5, 0.14, "任一門檻未通過：縮小承諾、維持委外，或退回較輕資產模式", ha="center", color=COLORS["brown"], fontsize=10.5)
ax.set_title("圖5　選擇權式垂直整合：可升級，也必須能退回", pad=10, fontsize=14)
fig.tight_layout()
fig.savefig(FIGURES / "figure-5-stage-gates.png", bbox_inches="tight")
plt.close(fig)

# Figure 6: evidence-to-claim boundary
fig, ax = plt.subplots(figsize=(10.5, 6.4))
ax.axis("off")
levels = [
    (0.10, "公開法規與政策文件", "可判斷角色、義務與制度上的可能路徑", COLORS["green"]),
    (0.31, "學術文獻與規範性比較", "可建立風險機制、模式取捨與可檢驗命題", COLORS["gold"]),
    (0.52, "企業匿名營運與完整期作資料", "才可估計單位經濟、現金缺口與企業財務可行性", COLORS["tan"]),
    (0.73, "前瞻試點、比較組或分階段導入", "才有條件估計轉型對農民與公司的因果效果", COLORS["brown"]),
]
for yv, title, text_value, color in levels:
    width = 0.82 - (yv - 0.10) * 0.35
    x = (1 - width) / 2
    ax.add_patch(plt.Rectangle((x, yv), width, 0.14, facecolor=color, alpha=0.88, edgecolor="white"))
    ax.text(0.5, yv + 0.095, title, ha="center", va="center", color="white", weight="bold", fontsize=11)
    ax.text(0.5, yv + 0.04, text_value, ha="center", va="center", color="white", fontsize=8.8)
ax.text(0.5, 0.94, "證據越強，能支持的主張才可越接近企業實際效果", ha="center", weight="bold", fontsize=13)
ax.text(0.5, 0.02, "本研究完成前兩層；後兩層仍需真實資料與前瞻研究，不以假設補值。", ha="center", color=COLORS["brown"], fontsize=10.5)
fig.tight_layout()
fig.savefig(FIGURES / "figure-6-evidence-claim-boundary.png", bbox_inches="tight")
plt.close(fig)

results = {
    "research_number": "SHWRP-2026-027",
    "analysis_date": "2026-07-27",
    "document_count": len(documents),
    "official_document_count": sum(row["official"] == "1" for row in documents),
    "peer_reviewed_document_count": sum(row["peer_reviewed"] == "1" for row in documents),
    "risk_and_governance_theme_count": len(theme_fields),
    "mode_count": len(modes),
    "stage_gate_count": len(gates),
    "scenario_variable_count": len(scenario_variables),
    "figure_count": 6,
    "second_independent_human_coder": False,
    "farmer_interviews_conducted": False,
    "actual_firm_financial_data_observed": False,
    "normative_mode_scores_are_empirical_measurements": False,
    "financial_feasibility_conclusion": (
        "Current public evidence supports legal and organizational feasibility for staged "
        "coordination, especially limited contracting and a reversible co-production pilot. "
        "It does not establish that full self-production is financially feasible for a specific firm."
    ),
    "public_data_scope": (
        "Bibliographic metadata, source URLs, researcher coding, normative ordinal framework, "
        "empty real-data templates, derived summaries, code, and original figures only."
    ),
}
(ROOT / "analysis-results.json").write_text(
    json.dumps(results, ensure_ascii=False, indent=2),
    encoding="utf-8",
)
print(json.dumps(results, ensure_ascii=False, indent=2))
