# -*- coding: utf-8 -*-
r"""브리프 01 — 경기 31개 시군 여성 생산연령인구(15~64세) 2015 → 2025

    py prep.py            (run.py 가 analysis/ 를 cwd로 잡고 실행한다)

하는 일
  ① KOSIS OpenAPI 에서 원자료를 받아 raw.csv 로 남긴다 (재현성)
  ② 31개 시군 정렬 막대그래프 chart.png 를 그린다

★ 숫자는 전부 여기서 계산한다. 본문에 손으로 옮겨 적지 않는다.
  1호에서 틀린 3건은 전부 본문에 손으로 쓴 숫자였다 (doc_wiki L011 부수교훈).
  이 스크립트가 찍는 [대장] 블록의 값을 수치대장.csv 에 그대로 옮긴다.

자료
  통계청 KOSIS · 주민등록인구현황
  「행정구역(읍면동)별/5세별 주민등록인구(2011년~)」 orgId=101 tblId=DT_1B04005N
  itmId T4=여자인구수 · objL2 20~65 = 15~19세 … 60~64세 · prdSe=Y (각 연 12월 기준)
"""
import csv, json, os, sys, urllib.parse, urllib.request
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
# ⛔ 그림 저장은 정본(`chartkit.save`)을 지난다 〔2026-09-21〕 — 그래야
#   ⑴ 폰용 그림이 같이 나가고(`analysis/폰/`) ⑵ 「폰에서 읽히나」 관문이 돈다.
#   `plt.savefig` 를 직접 부르면 그 둘이 통째로 꺼진다.
# ⚠ 이 호는 KOSIS 를 «직접» urllib 으로 부르느라 저장소 루트를 sys.path 에 안 넣는다
#   (다른 호는 `kosis.py` 를 읽으려고 이미 넣어 둔다). 그래서 여기서 넣는다.
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
import chartkit as ck

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

plt.rcParams["font.family"] = ["Malgun Gothic", "sans-serif"]   # '맑은 고딕'은 미등록명 → 경고만 쏟아진다
plt.rcParams["axes.unicode_minus"] = False

API = "https://kosis.kr/openapi/Param/statisticsParameterData.do"
ORG, TBL = "101", "DT_1B04005N"
ITM = "T4"                                   # 여자인구수
AGE = ["20", "25", "30", "35", "40", "45", "50", "55", "60", "65"]   # 15~64세
Y0, Y1 = "2015", "2025"

# 경기도(41) + 31개 시군. 일반구(41111 등)·북부출장소·폐지된 여주군은 제외한다.
GG = "41"
SGG = ["41110", "41130", "41150", "41170", "41190", "41210", "41220", "41250",
       "41270", "41280", "41290", "41310", "41360", "41370", "41390", "41410",
       "41430", "41450", "41460", "41480", "41500", "41550", "41570", "41590",
       "41610", "41630", "41650", "41670", "41800", "41820", "41830"]
HL = "안산시"                                  # 강조할 시군


def key():
    """KOSIS_KEY — **환경변수를 먼저** 보고, 없으면 저장소 루트 `.env` 를 읽는다.

    ⚠ 2026-08-20 수정. 원래는 `.env` 파일만 봤다. 그런데 **GitHub Actions 에는
      `.env` 가 없다**(.gitignore 로 막힌 파일이라 체크아웃에 안 딸려온다).
      즉 예약 발행이 B01 을 재발행하려 하면 `run.py` → `prep.py` 가
      「✖ .env 없음」으로 죽어 **관문에 닿기도 전에 실패**한다.
      B02~B07 은 `import kosis` 로 환경변수를 먼저 보므로 이 호만 그랬다.
      〔2026-08-20 내부 리뷰가 잡은 것 — `publish.yml` 머리말은 이미
        「재발행 때 prep.py 가 KOSIS_KEY 로 원자료를 받는다」고 적고 있었다〕
    """
    env = (os.environ.get("KOSIS_KEY") or "").strip()
    if env:
        return env
    for p in (Path("../../.env"), Path(".env")):
        if p.exists():
            for line in p.read_text(encoding="utf-8").splitlines():
                if line.startswith("KOSIS_KEY="):
                    값 = line.split("=", 1)[1].strip()
                    if 값:                      # 빈 값이면 «없는 것»으로 친다
                        return 값
    sys.exit("✖ KOSIS_KEY 를 찾지 못했습니다 — 저장소 루트 .env 에 넣거나 "
             "환경변수 KOSIS_KEY 로 주세요 (GitHub Actions 는 Secrets → KOSIS_KEY)")


def fetch(k, year):
    q = urllib.parse.urlencode({
        "method": "getList", "apiKey": k, "format": "json", "jsonVD": "Y",
        "orgId": ORG, "tblId": TBL, "prdSe": "Y",
        "startPrdDe": year, "endPrdDe": year,
        "objL1": "+".join([GG] + SGG), "objL2": "+".join(AGE), "itmId": ITM,
    })
    body = urllib.request.urlopen(API + "?" + q, timeout=90).read().decode("utf-8")
    d = json.loads(body)
    if isinstance(d, dict):                          # {"err":..} 도 200으로 온다
        sys.exit(f"✖ KOSIS 오류 응답: {d}")
    out = {}
    for x in d:
        out[x["C1_NM"]] = out.get(x["C1_NM"], 0) + int(x["DT"])
    want = len(SGG) + 1
    if len(out) != want:                             # 조용한 실패 방지
        sys.exit(f"✖ {year}년 지역 {len(out)}개 — {want}개여야 합니다")
    return out


k = key()
a, b = fetch(k, Y0), fetch(k, Y1)
print(f"[수집] {Y0} {len(a)}개 · {Y1} {len(b)}개 지역")

rows = []
for nm in sorted(a):
    if nm == "경기도":
        continue
    rows.append({"시군": nm, f"여성생산연령_{Y0}": a[nm], f"여성생산연령_{Y1}": b[nm],
                 "변화율": round((b[nm] / a[nm] - 1) * 100, 2),
                 "증감": b[nm] - a[nm]})
rows.sort(key=lambda r: r["변화율"])

with open("raw.csv", "w", encoding="utf-8-sig", newline="") as f:
    w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
    w.writeheader()
    w.writerows(rows)

gg = round((b["경기도"] / a["경기도"] - 1) * 100, 2)
minus = [r for r in rows if r["변화율"] < 0]
hl = [r for r in rows if r["시군"] == HL][0]

# ── 차트 ── 31개 시군 정렬 막대 · 안산 강조 · 경기 평균 기준선
fig, ax = plt.subplots(figsize=(7.4, 8.6))
names = [r["시군"] for r in rows]
vals = [r["변화율"] for r in rows]
colors = ["#c8482a" if v < 0 else "#3d5a80" for v in vals]
for i, r in enumerate(rows):
    if r["시군"] == HL:
        colors[i] = "#ef5b3b"
bars = ax.barh(names, vals, color=colors, height=.72)
ax.axvline(0, color="#15171c", lw=1)
ax.axvline(gg, color="#6b7280", lw=1.1, ls="--")
ax.text(gg, len(rows) - .2, f" 경기 평균 {gg:+.1f}%", color="#6b7280", fontsize=9, va="bottom")
for i, (n, v) in enumerate(zip(names, vals)):
    ax.text(v + (1.4 if v >= 0 else -1.4), i, f"{v:+.1f}%", va="center",
            ha="left" if v >= 0 else "right", fontsize=8.4,
            color="#ef5b3b" if n == HL else "#4a5560",
            fontweight="bold" if n == HL else "normal")
for lab in ax.get_yticklabels():
    if lab.get_text() == HL:
        lab.set_color("#ef5b3b"); lab.set_fontweight("bold")
ax.set_xlim(min(vals) - 14, max(vals) + 16)
ax.set_xlabel(f"{Y0} → {Y1} 변화율 (%)", fontsize=10)
ax.tick_params(axis="y", labelsize=9.5, length=0)
ax.tick_params(axis="x", labelsize=9)
for s in ("top", "right", "left"):
    ax.spines[s].set_visible(False)
ax.spines["bottom"].set_color("#cfd4de")
ax.grid(axis="x", color="#eef0f4", lw=.8)
ax.set_axisbelow(True)
fig.tight_layout()
ck.save(fig, "chart.png", dpi=130)

print(f"[저장] raw.csv {len(rows)}행 · chart.png")
print("\n[대장] 수치대장.csv 에 옮길 값 ─────────────────")
print(f"  경기도 여성 생산연령 {Y0}  {a['경기도']:,}")
print(f"  경기도 여성 생산연령 {Y1}  {b['경기도']:,}")
print(f"  경기도 변화율               {gg:+.2f}%")
print(f"  감소한 시군 수              {len(minus)}개 / {len(rows)}개")
print(f"  {HL} {Y0}               {hl[f'여성생산연령_{Y0}']:,}")
print(f"  {HL} {Y1}               {hl[f'여성생산연령_{Y1}']:,}")
print(f"  {HL} 변화율               {hl['변화율']:+.2f}%  ({hl['증감']:,}명)")
print(f"  최대 감소                   {rows[0]['시군']} {rows[0]['변화율']:+.2f}%")
print(f"  최대 증가                   {rows[-1]['시군']} {rows[-1]['변화율']:+.2f}%")
