from __future__ import annotations
from typing import Optional, List, Dict, Any
from datetime import datetime, date
from fastapi import APIRouter, Request, Query
from fastapi.responses import HTMLResponse
from app.web.deps import templates, sb, logger

router = APIRouter()

def _ensure_moef_url(row: Dict[str, Any]) -> Optional[str]:
    DETAIL_URL = "https://www.moef.go.kr/nw/notice/hrDetail.do"
    menuNo = "4050300"
    bbsId = row.get("bbsId"); postId = row.get("postId")
    if not (bbsId and postId):
        rid = str(row.get("id") or "")
        if "-" in rid:
            parts = rid.split("-", 1)
            if len(parts) == 2:
                bbsId, postId = parts
    if bbsId and postId:
        return f"{DETAIL_URL}?searchBbsId1={bbsId}&searchNttId1={postId}&menuNo={menuNo}"
    return None

def _ensure_motie_url(row: Dict[str, Any]) -> Optional[str]:
    BASE = "https://www.motie.go.kr"
    aid = row.get("id")
    if aid is None: return None
    return f"{BASE}/kor/article/ATCL6e90bb9de/{aid}/view?"

def _ensure_me_url(row: Dict[str, Any]) -> Optional[str]:
    BASE = "https://me.go.kr"
    PATH = "/home/web/board/read.do"
    rid = row.get("id")
    if not rid:
        return None
    # 표준 쿼리 구성
    return f"{BASE}{PATH}?boardId={rid}&menuId=10527&boardMasterId=22"

@router.get("/gov/timeline", response_class=HTMLResponse)
async def gov_timeline(
    request: Request,
    src: str = Query(default="all"),
    q: Optional[str] = Query(default=None),
    start: Optional[str] = Query(default=None),
    end: Optional[str] = Query(default=None),
    page: Optional[int] = Query(default=1),
    page_size: int = Query(default=20, ge=5, le=100),
):
    q_norm = (q or "").strip().lower()

    def _to_date(s: Optional[str]) -> Optional[date]:
        if not s: return None
        try: return datetime.strptime(str(s)[:10], "%Y-%m-%d").date()
        except Exception: return None

    s_date = _to_date(start); e_date = _to_date(end)
    page = page or 1
    items: List[Dict[str, Any]] = []

    def fetch_motie() -> List[Dict[str, Any]]:
        try:
            res = sb.table("motie_id").select("*").order("id", desc=True).limit(1000).execute()
            data = res.data or []
        except Exception as e:
            logger.warning(f"motie_id fetch failed: {e}")
            data = []
        for r in data:
            r["source"] = "MOTIE"
            r["url"] = _ensure_motie_url(r)
        return data

    def fetch_moef() -> List[Dict[str, Any]]:
        try:
            res = sb.table("moef_id").select("*").order("id", desc=True).limit(1000).execute()
            data = res.data or []
        except Exception as e:
            logger.warning(f"moef_id fetch failed: {e}")
            data = []
        for r in data:
            r["source"] = "MOEF"
            r["url"] = _ensure_moef_url(r)
        return data

    def fetch_me() -> List[Dict[str, Any]]:
        try:
            res = sb.table("me_id").select("*").order("id", desc=True).limit(1000).execute()
            data = res.data or []
        except Exception as e:
            logger.warning(f"me_id fetch failed: {e}")
            data = []
        for r in data:
            r["source"] = "ME"
            r["url"] = r.get("url") or _ensure_me_url(r)
        return data

    if src in ("MOTIE","all"): items.extend(fetch_motie())
    if src in ("MOEF","all"):  items.extend(fetch_moef())
    if src in ("ME","all"):    items.extend(fetch_me())

    # 보정: posted_at이 없는 경우 created_at로 대체하여 정렬/필터에 포함
    for r in items:
        if not r.get("posted_at") and r.get("created_at"):
            try:
                r["posted_at"] = str(r["created_at"])[:10]
            except Exception:
                pass

    if q_norm:
        def hit_text(r):
            title = (r.get("title") or "").lower()
            tag = (r.get("tag") or "").lower()
            return q_norm in title or q_norm in tag
        items = [r for r in items if hit_text(r)]

    if s_date or e_date:
        def d_of(r) -> Optional[date]:
            p = r.get("posted_at") or r.get("created_at")
            try: return datetime.strptime(str(p)[:10], "%Y-%m-%d").date() if p else None
            except Exception: return None
        def in_range(r):
            d = d_of(r)
            if not d: return False
            if s_date and d < s_date: return False
            if e_date and d > e_date: return False
            return True
        items = [r for r in items if in_range(r)]

    def sort_key(r):
        def d_try(k):
            try: return datetime.strptime(str(r.get(k) or "")[:10], "%Y-%m-%d").date()
            except Exception: return date.min
        return (d_try("posted_at"), d_try("created_at"), str(r.get("id") or ""))
    items.sort(key=sort_key, reverse=True)

    total = len(items)
    start_idx = (page-1)*page_size
    end_idx = start_idx + page_size
    page_rows = items[start_idx:end_idx]
    has_more = end_idx < total

    return templates.TemplateResponse("gov/timeline.html", {
        "request": request,
        "src": src, "q": q or "", "start": start or "", "end": end or "",
        "page": page, "rows": page_rows, "has_more": has_more,
    })
