"""
20_report_assembly.py
报告组装模块：将全流程产出汇总为双语（中/英）HTML 报告
Report Assembly Module: assemble all pipeline outputs into a bilingual (zh/en) HTML report

用途 / Purpose:
    这是流水线的最终阶段：读取 01-19 各阶段产出的 CSV/JSON 中间文件，
    组装成 oecd38-full-report.html 的数据基础（执行摘要统计量、
    章节表格、案例叙事文本）。本脚本本身不负责 HTML 排版美化
    （网站侧的 oecd38-full-report.html 是人工/半自动编辑最终稿），
    而是生成一份结构化的 JSON 报告数据骨架（report_data_bundle.json），
    作为报告撰写的"数据底稿"，确保报告中的每个数字都可追溯到具体的
    上游脚本产出。

依赖 / Dependencies: pandas, json
"""

import json
import logging
from pathlib import Path

import pandas as pd

logging.basicConfig(level=logging.INFO, format="%(asctime)s  %(message)s")
log = logging.getLogger("20_report_assembly")

DATA_DIR = Path("./data")

SOURCE_FILES = {
    "re_scores": "panel_re_scores.csv",
    "dimension_weights": "dimension_weights.json",
    "reliability_validity": "reliability_validity_report.json",
    "domain_sub_indices": "domain_sub_indices.csv",
    "region_group_statistics": "region_group_statistics.csv",
    "crisis_response_comparison": "crisis_response_comparison.csv",
    "external_validation_report": "external_validation_report.csv",
    "case_study_narratives": "case_study_narratives.csv",
    "aggregation_method_comparison": "aggregation_method_comparison.csv",
    "figure_manifest": "figure_manifest.json",
}


def load_any(path: Path):
    if not path.exists():
        return None
    if path.suffix == ".json":
        with open(path, "r", encoding="utf-8") as f:
            return json.load(f)
    return pd.read_csv(path).to_dict(orient="records")


def compute_executive_summary(re_scores_records):
    if not re_scores_records:
        return {}
    df = pd.DataFrame(re_scores_records)
    latest_year = df["year"].max()
    first_year = df["year"].min()
    latest = df[df["year"] == latest_year]
    change = (
        df[df["year"] == latest_year].set_index("iso3")["re_score"]
        - df[df["year"] == first_year].set_index("iso3")["re_score"]
    )
    return {
        "n_countries": int(df["iso3"].nunique()),
        "n_years": int(df["year"].nunique()),
        "n_observations": int(len(df)),
        "period": f"{int(first_year)}-{int(latest_year)}",
        "latest_year_mean_re_score": round(float(latest["re_score"].mean()), 2),
        "largest_gain_country": change.idxmax() if not change.empty else None,
        "largest_gain_value": round(float(change.max()), 2) if not change.empty else None,
        "largest_decline_country": change.idxmin() if not change.empty else None,
        "largest_decline_value": round(float(change.min()), 2) if not change.empty else None,
    }


def main():
    bundle = {}
    for key, filename in SOURCE_FILES.items():
        data = load_any(DATA_DIR / filename)
        bundle[key] = data
        if data is None:
            log.warning("Missing upstream artifact: %s (skip in this environment)", filename)
        else:
            log.info("Loaded %s from data/%s", key, filename)

    bundle["executive_summary"] = compute_executive_summary(bundle.get("re_scores"))

    with open(DATA_DIR / "report_data_bundle.json", "w", encoding="utf-8") as f:
        json.dump(bundle, f, ensure_ascii=False, indent=2, default=str)

    log.info(
        "Report data bundle assembled -> data/report_data_bundle.json "
        "(source for oecd38-full-report.html executive summary & tables)"
    )
    log.info("Pipeline complete: scripts 01-20 executed in sequence.")


if __name__ == "__main__":
    main()
