from __future__ import annotations
from typing import Dict, List
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
import re
from app.web.deps import templates, sb

router = APIRouter()

MOEF_KPS_DEPT_ORDER = [
    "부총리실",
    "제1차관", "제2차관",
    "공공정책국", "공공혁신심의관",
    "공공정책총괄과", "공공제도기획과", "재무경영과",
    "평가분석과", "인재경영과", "공공윤리정책과",
    "공공혁신기획과", "경영관리과",
]
MOEF_KPS_DEPT_WHITELIST = MOEF_KPS_DEPT_ORDER + ["부총리", "장관실"]
MOEF_KPS_EXPECTED_POS: Dict[str, str] = {
    "부총리실": "부총리",
    "제1차관": "차관",
    "제2차관": "차관",
    "공공정책국": "국장",
    "공공혁신심의관": "심의관",
    "공공정책총괄과": "과장",
    "공공제도기획과": "과장",
    "재무경영과": "과장",
    "평가분석과": "과장",
    "인재경영과": "과장",
    "공공윤리정책과": "과장",
    "공공혁신기획과": "과장",
    "경영관리과": "과장",
}
MOEF_KPS_PHONE_ROLE_LAST4 = [
    ("제1차관", "2028", "담당"),
    ("제2차관", "2022", "담당"),
    ("재무경영과", "5631", "담당"),
]

def _last4(phone: str | None) -> str | None:
    if not phone: return None
    m = re.search(r"(\d{4})\s*$", str(phone))
    return m.group(1) if m else None

def _canon_dep(dep: str, pos: str) -> str:
    d = (dep or "").strip(); p = (pos or "").strip()
    if d == "부총리":
        return "부총리실"
    if d == "장관실" and p == "비서실장":
        return "부총리실"
    return d

def _pick_best(rows: List[Dict]) -> Dict:
    rows = rows or []
    rows.sort(key=lambda x: (
        0 if (x.get("name") or "").strip() else 1,
        0 if (x.get("phone") or "").strip() else 1,
        (x.get("name") or "")
    ))
    return rows[0] if rows else {}

@router.get("/gov/moef/kps", response_class=HTMLResponse)
async def gov_moef_kps(request: Request):
    try:
        res = (
            sb.table("moef_kps")
              .select("id,department,position,name,phone,task")
              .in_("department", MOEF_KPS_DEPT_WHITELIST)
              .limit(50000)
              .execute()
        )
        raw: List[Dict] = res.data or []
    except Exception:
        raw = []

    by_dep: Dict[str, List[Dict]] = {}
    by_dep_pos: Dict[tuple, List[Dict]] = {}
    by_dep_l4: Dict[tuple, List[Dict]] = {}

    for r in raw:
        raw_dep = (r.get("department") or "").strip()
        pos = (r.get("position") or "").strip()
        dep = _canon_dep(raw_dep, pos)
        l4  = _last4((r.get("phone") or "").strip())
        r["_dep"] = dep
        by_dep.setdefault(dep, []).append(r)
        if pos:
            by_dep_pos.setdefault((dep, pos), []).append(r)
        if l4:
            by_dep_l4.setdefault((dep, l4), []).append(r)

    groups: List[Dict] = []
    for dep in MOEF_KPS_DEPT_ORDER:
        used_ids: set[int] = set()
        rows_for_dep: List[Dict] = []

        leader_pos = MOEF_KPS_EXPECTED_POS.get(dep, "-")
        leader_row = _pick_best(by_dep_pos.get((dep, leader_pos), []))
        if leader_row:
            used_ids.add(leader_row.get("id"))
            rows_for_dep.append({
                "pos": leader_pos,
                "name": (leader_row.get("name") or "-").strip() or "-",
                "phone": (leader_row.get("phone") or "-").strip() or "-",
                "task": (leader_row.get("task") or "-").strip() or "-",
            })
        else:
            rows_for_dep.append({"pos": leader_pos, "name": "(공석)", "phone": "-", "task": "-"})

        for d, l4, role in MOEF_KPS_PHONE_ROLE_LAST4:
            if d != dep:
                continue
            cands = [x for x in by_dep_l4.get((dep, l4), []) if x.get("id") not in used_ids]
            pick = _pick_best(cands)
            if pick:
                used_ids.add(pick.get("id"))
                rows_for_dep.append({
                    "pos": (pick.get("position") or "").strip() or role,
                    "name": (pick.get("name") or "-").strip() or "-",
                    "phone": (pick.get("phone") or "-").strip() or "-",
                    "task": (pick.get("task") or "-").strip() or "-",
                })
            else:
                rows_for_dep.append({"pos": role, "name": "(공석)", "phone": "-", "task": "-"})

        remaining = [x for x in by_dep.get(dep, []) if x.get("id") not in used_ids]
        remaining.sort(key=lambda x: ((x.get("position") or ""), (x.get("name") or "")))
        for r in remaining:
            used_ids.add(r.get("id"))
            rows_for_dep.append({
                "pos": (r.get("position") or "-").strip() or "-",
                "name": (r.get("name") or "-").strip() or "-",
                "phone": (r.get("phone") or "-").strip() or "-",
                "task": (r.get("task") or "-").strip() or "-",
            })

        groups.append({"department": dep, "rows": rows_for_dep})

    return templates.TemplateResponse("gov/moef/kps.html", {
        "request": request, "groups": groups,
    })
