"""
17_crisis_response_comparison.py
危机响应对比模块：2008年全球金融危机 vs COVID-19 冲击下的 RE 走势对比
Crisis Response Comparison Module: 2008 GFC vs COVID-19 shock RE trajectories

用途 / Purpose:
    提取两次系统性冲击窗口期（2008 GFC: 2007-2010；COVID-19: 2019-2022）
    前后的 RE 分数及 V/C/F 子分数变化，计算"冲击幅度"（危机年 vs 危机前一年
    的降幅）与"恢复速度"（冲击后 N 年恢复到危机前水平所需时长），
    用于识别哪些国家的资源重配置机制在危机中表现出更强的韧性。

依赖 / Dependencies: pandas, numpy
"""

import logging
from pathlib import Path

import numpy as np
import pandas as pd

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

DATA_DIR = Path("./data")

CRISIS_WINDOWS = {
    "gfc_2008": {"pre": 2007, "shock": 2009, "recovery_check": [2010, 2011, 2012]},
    "covid_2020": {"pre": 2019, "shock": 2020, "recovery_check": [2021, 2022, 2023]},
}


def compute_shock_magnitude(panel: pd.DataFrame, pre_year: int, shock_year: int) -> pd.Series:
    pre = panel[panel["year"] == pre_year].set_index("iso3")["re_score"]
    shock = panel[panel["year"] == shock_year].set_index("iso3")["re_score"]
    return (shock - pre).rename("shock_magnitude")


def compute_recovery_year(panel: pd.DataFrame, iso3: str, pre_value: float, shock_year: int, check_years: list):
    for y in check_years:
        row = panel[(panel["iso3"] == iso3) & (panel["year"] == y)]
        if not row.empty and row["re_score"].iloc[0] >= pre_value:
            return y
    return None  # 尚未恢复到危机前水平


def main():
    panel = pd.read_csv(DATA_DIR / "panel_re_scores.csv")

    all_results = []
    for crisis_name, spec in CRISIS_WINDOWS.items():
        pre_year, shock_year = spec["pre"], spec["shock"]
        shock_mag = compute_shock_magnitude(panel, pre_year, shock_year)

        pre_values = panel[panel["year"] == pre_year].set_index("iso3")["re_score"]

        recovery_rows = []
        for iso3 in panel["iso3"].unique():
            pre_val = pre_values.get(iso3)
            if pre_val is None:
                continue
            recovery_year = compute_recovery_year(panel, iso3, pre_val, shock_year, spec["recovery_check"])
            recovery_rows.append({
                "crisis": crisis_name,
                "iso3": iso3,
                "pre_crisis_score": round(float(pre_val), 2),
                "shock_magnitude": round(float(shock_mag.get(iso3, np.nan)), 2),
                "recovery_year": recovery_year,
                "years_to_recover": (recovery_year - shock_year) if recovery_year else None,
            })
        all_results.extend(recovery_rows)
        log.info(
            "%s: mean shock magnitude=%.2f, recovered-by-window countries=%d/%d",
            crisis_name, shock_mag.mean(),
            sum(1 for r in recovery_rows if r["recovery_year"] is not None),
            len(recovery_rows),
        )

    out = pd.DataFrame(all_results)
    out.to_csv(DATA_DIR / "crisis_response_comparison.csv", index=False)
    log.info("Crisis response comparison saved -> data/crisis_response_comparison.csv")


if __name__ == "__main__":
    main()
