"""
08_re_aggregation.py
RE 指数聚合模块：RE = V·C / (1+F) 乘除法比率聚合
RE Index Aggregation Module: multiplicative-ratio aggregation RE = V*C/(1+F)

用途 / Purpose:
    1. 使用 07 输出的维度权重，对每个维度内的标准化指标做加权平均，
       得到 V_score / C_score / F_score（均落于 [0,1] 区间）；
    2. 按照 RE = V * C / (1 + F) 的乘除法比率公式计算原始复合分数
       （V、C 越高越好，F 越高摩擦越大，因此作为分母的抑制项）；
    3. 对原始 RE 分数在全样本（38 国 x 24 年 = 912 观测）范围内做
       Min-Max 缩放至 [0, 100]，得到最终展示用的 re_score。

依赖 / Dependencies: pandas, numpy
"""

import json
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("08_aggregation")

DATA_DIR = Path("./data")


def weighted_dimension_score(df: pd.DataFrame, weights: dict) -> pd.Series:
    cols = list(weights.keys())
    w = np.array([weights[c] for c in cols])
    values = df[cols].to_numpy(dtype=float)
    return pd.Series(values.dot(w), index=df.index)


def main():
    panel = pd.read_csv(DATA_DIR / "panel_normalized_minmax.csv")
    with open(DATA_DIR / "dimension_weights.json", "r", encoding="utf-8") as f:
        weight_spec = json.load(f)

    weights = weight_spec["weights"]

    v_score = weighted_dimension_score(panel, weights["V"])
    c_score = weighted_dimension_score(panel, weights["C"])
    f_score = weighted_dimension_score(panel, weights["F"])

    log.info("Computed V/C/F dimension scores for %d observations", len(panel))

    re_raw = (v_score * c_score) / (1 + f_score)

    # Min-Max rescale RE raw score to [0, 100] across the full panel
    re_min, re_max = re_raw.min(), re_raw.max()
    re_score = 100 * (re_raw - re_min) / (re_max - re_min)

    log.info(
        "RE raw score range: [%.4f, %.4f] -> rescaled to [0, 100]",
        re_min, re_max,
    )

    result = panel[["iso3", "year"]].copy()
    result["v_score"] = v_score.round(4)
    result["c_score"] = c_score.round(4)
    result["f_score"] = f_score.round(4)
    result["re_raw"] = re_raw.round(6)
    result["re_score"] = re_score.round(2)

    result.to_csv(DATA_DIR / "panel_re_scores.csv", index=False)
    log.info(
        "RE aggregation complete -> data/panel_re_scores.csv (mean re_score=%.2f)",
        result["re_score"].mean(),
    )


if __name__ == "__main__":
    main()
