"""
전이행렬 데이터 전수 감사 엑셀 생성

단계:
1. 3사 원본 CSV (WR 포함 before, WR 제거 after)
2. 3사 평균 (AVG)
3. TTC (장기 평균)
4. Zt 추정 결과 + 부도율(PD) 비교
"""

import sys, io
import numpy as np
import pandas as pd
from pathlib import Path

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.path.insert(0, str(Path(__file__).parent.parent))

from data.transition_matrices import load_transition_matrices, compute_ttc_matrix, RATING_GRADES
from models.credit_cycle import estimate_zt_series, compute_thresholds, model_transition_matrix

DATA_DIR = Path(__file__).parent / "real"
GRADES = RATING_GRADES  # ['AAA','AA','A','BBB','BB','B','CCC','D']
AGENCIES = ["KR", "NICE", "SCI"]


def load_raw_csv(agency, year):
    """개별 에이전시 CSV 로딩"""
    f = DATA_DIR / f"{agency}_{year}.csv"
    if f.exists():
        return pd.read_csv(f, index_col=0)
    return None


def main():
    output = Path(__file__).parent.parent / "results" / "transition_matrix_audit.xlsx"
    
    # 연도 범위 확인
    tm_all = load_transition_matrices("real")
    years = sorted(tm_all.keys())
    print(f"연도: {years[0]}~{years[-1]} ({len(years)}개)")
    
    with pd.ExcelWriter(output, engine="openpyxl") as writer:
        
        # ============================================================
        # Sheet 1: 연도별 3사 + AVG 부도율(PD) 비교
        # ============================================================
        pd_rows = []
        for year in years:
            row = {"Year": year}
            for agency in AGENCIES:
                df = load_raw_csv(agency, year)
                if df is not None and "D" in df.columns:
                    for grade in ["AAA", "AA", "A", "BBB", "BB", "B", "CCC"]:
                        if grade in df.index:
                            row[f"{agency}_{grade}_PD"] = round(df.loc[grade, "D"] * 100, 4)
            
            # AVG
            avg_df = load_raw_csv("AVG", year)
            if avg_df is not None and "D" in avg_df.columns:
                for grade in ["AAA", "AA", "A", "BBB", "BB", "B", "CCC"]:
                    if grade in avg_df.index:
                        row[f"AVG_{grade}_PD"] = round(avg_df.loc[grade, "D"] * 100, 4)
            
            pd_rows.append(row)
        
        pd_df = pd.DataFrame(pd_rows)
        pd_df.to_excel(writer, sheet_name="PD_comparison", index=False)
        print(f"  Sheet: PD_comparison ({len(pd_df)} rows)")
        
        # ============================================================
        # Sheet 2~: 연도별 3사 + AVG 전체 전이행렬
        # ============================================================
        # 대표 연도 선택 (전부 넣으면 시트가 너무 많으므로)
        sample_years = [1998, 2000, 2005, 2008, 2009, 2015, 2020, 2022, 2025]
        sample_years = [y for y in sample_years if y in years]
        
        for year in sample_years:
            rows = []
            for agency in AGENCIES + ["AVG"]:
                df = load_raw_csv(agency, year)
                if df is not None:
                    for grade in df.index:
                        row = {"Agency": agency, "From": grade}
                        for col in df.columns:
                            row[col] = round(df.loc[grade, col] * 100, 4)
                        rows.append(row)
                    # 빈 행 구분
                    rows.append({})
            
            sheet_df = pd.DataFrame(rows)
            sheet_name = f"TM_{year}"
            sheet_df.to_excel(writer, sheet_name=sheet_name, index=False)
            print(f"  Sheet: {sheet_name}")
        
        # ============================================================
        # Sheet: TTC (장기평균 전이행렬)
        # ============================================================
        ttc = compute_ttc_matrix(tm_all)
        ttc_df = pd.DataFrame(ttc * 100, index=GRADES, columns=GRADES)
        ttc_df = ttc_df.round(4)
        ttc_df.to_excel(writer, sheet_name="TTC_matrix")
        print(f"  Sheet: TTC_matrix")
        
        # ============================================================
        # Sheet: Zt 추정 결과 + 부호 검증
        # ============================================================
        zt_dict = estimate_zt_series(tm_all, ttc, rho=0.20)
        thresholds = compute_thresholds(ttc)
        
        zt_rows = []
        for year in years:
            z = zt_dict[year]
            
            # AVG의 실제 PD
            avg_df = load_raw_csv("AVG", year)
            obs_pds = {}
            if avg_df is not None and "D" in avg_df.columns:
                for grade in ["BBB", "BB", "B", "CCC"]:
                    if grade in avg_df.index:
                        obs_pds[grade] = avg_df.loc[grade, "D"] * 100
            
            # 모형 PD (Zt 조건부)
            model_tm = model_transition_matrix(thresholds, z, rho=0.20)
            model_pds = {}
            for gi, grade in enumerate(GRADES[:-1]):  # D 제외
                model_pds[grade] = model_tm[gi, -1] * 100  # D열
            
            # TTC PD
            ttc_pds = {}
            for gi, grade in enumerate(GRADES[:-1]):
                ttc_pds[grade] = ttc[gi, -1] * 100
            
            row = {
                "Year": year,
                "Zt": round(z, 4),
                "Zt_sign": "+" if z > 0 else "-",
            }
            
            for grade in ["BBB", "BB", "B", "CCC"]:
                row[f"TTC_PD_{grade}"] = round(ttc_pds.get(grade, 0), 4)
                row[f"Obs_PD_{grade}"] = round(obs_pds.get(grade, 0), 4)
                row[f"Model_PD_{grade}"] = round(model_pds.get(grade, 0), 4)
            
            # Obs vs TTC 비교 — Zt+면 PD가 TTC보다 높아야 하나 낮아야 하나?
            bbb_obs = obs_pds.get("BBB", 0)
            bbb_ttc = ttc_pds.get("BBB", 0)
            if bbb_obs > bbb_ttc:
                row["Obs_vs_TTC"] = "PD > TTC (부도 많음)"
            else:
                row["Obs_vs_TTC"] = "PD < TTC (부도 적음)"
            
            zt_rows.append(row)
        
        zt_df = pd.DataFrame(zt_rows)
        zt_df.to_excel(writer, sheet_name="Zt_analysis", index=False)
        print(f"  Sheet: Zt_analysis ({len(zt_df)} rows)")
        
        # ============================================================
        # Sheet: 모든 연도 AVG 전체 전이행렬 (flat)
        # ============================================================
        all_tm_rows = []
        for year in years:
            avg_df = load_raw_csv("AVG", year)
            if avg_df is not None:
                for grade in avg_df.index:
                    row = {"Year": year, "From": grade}
                    for col in avg_df.columns:
                        row[f"To_{col}"] = round(avg_df.loc[grade, col] * 100, 4)
                    all_tm_rows.append(row)
        
        all_tm_df = pd.DataFrame(all_tm_rows)
        all_tm_df.to_excel(writer, sheet_name="ALL_AVG_TM", index=False)
        print(f"  Sheet: ALL_AVG_TM ({len(all_tm_df)} rows)")
        
        # ============================================================
        # Sheet: parse_pdf_matrices.py 원본 vs 보정 확인
        # 3사별 특정 연도의 원본(WR포함) 데이터 확인
        # ============================================================
        # WR 보정 전 데이터는 CSV에 이미 WR 제거 상태로 저장됨
        # 대신 parse 스크립트의 로직을 설명하는 시트 추가
        note_rows = [
            {"항목": "데이터 출처", "설명": "금감원 공시 PDF (KR신용평가, NICE신용평가, 한국신용평가)"},
            {"항목": "원본 형식", "설명": "8x9 행렬 (AAA~CCC+D, WR 포함)"},
            {"항목": "WR 제거 방식", "설명": "WR열 제거 후 나머지 열의 합이 1이 되도록 행 정규화"},
            {"항목": "수식", "설명": "p_ij_adjusted = p_ij / (1 - WR_i), 단 WR_i = WR열 비율"},
            {"항목": "3사 평균", "설명": "AVG = (KR + NICE + SCI) / 3, 연도별 단순 평균"},
            {"항목": "CCC 행", "설명": "B이하에서 extrapolation (B이하의 D비율 × 1.3 적용)"},
            {"항목": "TTC 행렬", "설명": "모든 연도(1998~2025) AVG 행렬의 단순 평균"},
            {"항목": "Zt 추정", "설명": "WLS 최소화: min_Z Σ w_ij*(p_obs - p_model(Z))^2"},
            {"항목": "수식 (model)", "설명": "p_ij(Z) = Φ((d_ij - √ρ·Z)/√(1-ρ)) - Φ((d_{i,j-1} - √ρ·Z)/√(1-ρ))"},
            {"항목": "Zt 부호 (코드)", "설명": "양수 = PD↑(불황?), 음수 = PD↓(호황?)"},
            {"항목": "Zt 부호 (논문)", "설명": "양수 = 호황(PD↓), 음수 = 불황(PD↑) — 부호 반전 확인 필요!"},
        ]
        pd.DataFrame(note_rows).to_excel(writer, sheet_name="NOTES", index=False)
        print(f"  Sheet: NOTES")
    
    print(f"\n  완료: {output}")


if __name__ == "__main__":
    main()
