# -*- coding: utf-8 -*-
"""
실거래가 대비 공시가격(현실화율) 세그먼트·시계열 분석
=====================================================
입력 : 결과/분석_실거래가_공시가격_결합.csv  (gongsi.py 산출)
출력 : 결과/분석_현실화율_요약.xlsx  (여러 시트)
       결과/차트/*.png  (연도별 추이·면적·가격대)

현실화율 = 공시가격 / 실거래가(매매가)  (한국 공시가격 현실화율 정의)
"""
from __future__ import annotations

import sys
from pathlib import Path

import numpy as np
import pandas as pd

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

try:
    sys.stdout.reconfigure(encoding="utf-8")
except Exception:
    pass

# 한글 폰트 (Windows)
for _f in ["Malgun Gothic", "맑은 고딕", "AppleGothic", "NanumGothic"]:
    try:
        plt.rcParams["font.family"] = _f
        break
    except Exception:
        continue
plt.rcParams["axes.unicode_minus"] = False

RESULT_DIR = Path(__file__).with_name("결과")
CHART_DIR = RESULT_DIR / "차트"

REGION = {"11680": "강남구", "11650": "서초구", "11710": "송파구"}
TYPE_SHORT = {"아파트_매매": "아파트", "연립다세대_매매": "연립다세대"}


def load() -> pd.DataFrame:
    df = pd.read_csv(RESULT_DIR / "분석_실거래가_공시가격_결합.csv", encoding="utf-8-sig")
    df["현실화율"] = pd.to_numeric(df["현실화율"], errors="coerce")
    df["거래금액_원"] = pd.to_numeric(df["거래금액_원"], errors="coerce")
    df["공시가격_원"] = pd.to_numeric(df["공시가격_원"], errors="coerce")
    df["거래연도"] = pd.to_numeric(df["거래연도"], errors="coerce").astype("Int64")
    df["유형"] = df["자료구분"].map(TYPE_SHORT).fillna(df["자료구분"])
    df["지역"] = df["sggCd"].astype(str).map(REGION).fillna(df["sggCd"].astype(str))
    return df


def clean(df: pd.DataFrame) -> pd.DataFrame:
    """유효 현실화율만: 공시가격 매칭됨 + 0.1~1.5 범위(이상치 제거)."""
    m = df["현실화율"].notna() & (df["현실화율"] > 0.1) & (df["현실화율"] < 1.5)
    valid = df[m].copy()
    print(f"전체 {len(df)}행 | 공시가격 매칭 {df['현실화율'].notna().sum()} | "
          f"유효(이상치제거) {len(valid)}")
    return valid


def _pivot(df, index, col="유형", val="현실화율", aggfunc="median"):
    return pd.pivot_table(df, index=index, columns=col, values=val, aggfunc=aggfunc)


def summarize(df: pd.DataFrame) -> dict:
    tables = {}
    # 1) 연도 x 유형 (중앙값 + 건수)
    tables["연도x유형_중앙"] = _pivot(df, "거래연도").round(3)
    tables["연도x유형_건수"] = pd.pivot_table(df, index="거래연도", columns="유형",
                                          values="현실화율", aggfunc="count")
    # 2) 연도 x 지역 (아파트)
    apt = df[df["유형"] == "아파트"]
    tables["연도x지역_아파트_중앙"] = _pivot(apt, "거래연도", col="지역").round(3)
    # 3) 면적구간 x 유형
    order = ["~40㎡", "40-60㎡", "60-85㎡", "85-135㎡", "135㎡~"]
    t3 = _pivot(df, "면적구간").reindex(order).round(3)
    tables["면적구간x유형_중앙"] = t3
    # 4) 가격대(5분위) x 유형 : 유형별로 거래금액 5분위
    def price_band(g):
        g = g.copy()
        g["가격대"] = pd.qcut(g["거래금액_원"], 5,
                            labels=["1분위(저가)", "2분위", "3분위", "4분위", "5분위(고가)"])
        return g
    banded = df.groupby("유형", group_keys=False).apply(price_band)
    tables["가격대x유형_중앙"] = pd.pivot_table(
        banded, index="가격대", columns="유형", values="현실화율", aggfunc="median").round(3)
    # 5) 전체 요약
    tables["요약"] = df.groupby("유형")["현실화율"].agg(
        건수="count", 평균="mean", 중앙="median", 표준편차="std").round(3)
    return tables


def charts(df: pd.DataFrame) -> None:
    CHART_DIR.mkdir(parents=True, exist_ok=True)

    # 1) 연도별 현실화율 추이 (유형별)
    fig, ax = plt.subplots(figsize=(8, 5))
    for name, g in df.groupby("유형"):
        s = g.groupby("거래연도")["현실화율"].median()
        ax.plot(s.index.astype(int), s.values, marker="o", label=name)
    ax.set_title("연도별 공시가격 현실화율 추이 (중앙값)")
    ax.set_xlabel("거래연도"); ax.set_ylabel("현실화율 (공시가격/실거래가)")
    ax.legend(); ax.grid(alpha=0.3)
    fig.tight_layout(); fig.savefig(CHART_DIR / "1_연도별_유형별.png", dpi=120); plt.close(fig)

    # 2) 연도별 현실화율 (아파트, 지역별)
    apt = df[df["유형"] == "아파트"]
    fig, ax = plt.subplots(figsize=(8, 5))
    for name, g in apt.groupby("지역"):
        s = g.groupby("거래연도")["현실화율"].median()
        ax.plot(s.index.astype(int), s.values, marker="o", label=name)
    ax.set_title("연도별 현실화율 추이 (아파트, 지역별)")
    ax.set_xlabel("거래연도"); ax.set_ylabel("현실화율"); ax.legend(); ax.grid(alpha=0.3)
    fig.tight_layout(); fig.savefig(CHART_DIR / "2_연도별_지역별_아파트.png", dpi=120); plt.close(fig)

    # 3) 면적구간별 현실화율 (유형별, 막대)
    order = ["~40㎡", "40-60㎡", "60-85㎡", "85-135㎡", "135㎡~"]
    piv = _pivot(df, "면적구간").reindex(order)
    fig, ax = plt.subplots(figsize=(9, 5))
    piv.plot(kind="bar", ax=ax)
    ax.set_title("면적구간별 현실화율 (중앙값)")
    ax.set_xlabel("전용면적 구간"); ax.set_ylabel("현실화율")
    ax.grid(axis="y", alpha=0.3); plt.xticks(rotation=0)
    fig.tight_layout(); fig.savefig(CHART_DIR / "3_면적구간별.png", dpi=120); plt.close(fig)

    # 4) 가격대별 현실화율 (아파트, 고가주택 저평가 확인)
    apt2 = apt.copy()
    apt2["가격대"] = pd.qcut(apt2["거래금액_원"], 5,
                          labels=["1(저가)", "2", "3", "4", "5(고가)"])
    s = apt2.groupby("가격대")["현실화율"].median()
    fig, ax = plt.subplots(figsize=(8, 5))
    ax.bar(s.index.astype(str), s.values, color="#4C78A8")
    ax.set_title("가격대(5분위)별 현실화율 (아파트, 중앙값)")
    ax.set_xlabel("거래금액 분위"); ax.set_ylabel("현실화율"); ax.grid(axis="y", alpha=0.3)
    fig.tight_layout(); fig.savefig(CHART_DIR / "4_가격대별_아파트.png", dpi=120); plt.close(fig)
    print(f"차트 4종 저장: {CHART_DIR}")


def main() -> None:
    df = clean(load())
    tables = summarize(df)
    out = RESULT_DIR / "분석_현실화율_요약.xlsx"
    with pd.ExcelWriter(out) as xw:
        for name, t in tables.items():
            t.to_excel(xw, sheet_name=name[:31])
    print(f"요약 저장: {out} ({len(tables)}시트)")
    for name, t in tables.items():
        print(f"\n[{name}]\n{t.to_string()}")
    charts(df)


if __name__ == "__main__":
    main()
