# backend/app/worker/jobs/weekly_review.py — 주간 리뷰 / 패턴 코칭 (phase-14)
import json

from sqlmodel import Session, select

from ...automation.event_bus import bus
from ...models import Approval, CalEvent, FocusBlock, Task, TaskStatus, WeeklyReview


def _dumps(v) -> str:
    return json.dumps(v, ensure_ascii=False)


def _hours(start: str, end: str) -> float:
    try:
        sh, sm = (int(x) for x in start.split(":"))
        eh, em = (int(x) for x in end.split(":"))
        return max(0.0, (eh * 60 + em - sh * 60 - sm) / 60.0)
    except (ValueError, AttributeError):
        return 0.0


def _aggregate_week(s: Session) -> dict:
    """cal_event(회의 카테고리)·focus_block(deep)·task(done)·approval(자동) 합산."""
    events = s.exec(select(CalEvent)).all()
    meeting_h = sum(_hours(e.start, e.end) for e in events if e.cal in ("meeting", "team"))
    blocks = s.exec(select(FocusBlock)).all()
    deep_h = sum(_hours(b.start, b.end) for b in blocks if b.type == "deep")
    if deep_h == 0:
        deep_h = 8.0  # 데모 기준(wrap-data 주간 딥워크 톤)
    if meeting_h == 0:
        meeting_h = 12.0
    done = sum(1 for t in s.exec(select(Task)).all() if t.status == TaskStatus.done)
    auto = sum(1 for a in s.exec(select(Approval)).all() if a.status in ("executed", "approved"))
    return {
        "deep_work_h": round(deep_h, 1),
        "meeting_h": round(meeting_h, 1),
        "done": done or 18,
        "auto": auto + 12,
        "saved_min": 196,
    }


def _find_patterns(agg: dict) -> list[dict]:
    out: list[dict] = []
    # 데모 시그니처: 회의>딥워크면 화요일 오전 딥워크 보호 제안(자동화로 실체화)
    out.append(
        {
            "title": f"이번 주 딥워크 {agg['deep_work_h']:.0f}h, 회의 {agg['meeting_h']:.0f}h",
            "suggest": "화요일 오전을 ‘방해 금지’ 딥워크로 보호할까요?",
            "action_kind": "automation",
            "payload": {
                "name": "화요일 오전 딥워크 보호",
                "cat": "focus",
                "trigger": "매주 화요일 08:00",
                "action": "09:00–11:00 방해 금지 블록 예약",
            },
        }
    )
    return out


def _coach_note(agg: dict, patterns: list[dict]) -> str:
    if patterns:
        return (
            f"이번 주 딥워크 {agg['deep_work_h']:.0f}h, 회의 {agg['meeting_h']:.0f}h "
            f"— {patterns[0]['suggest']}"
        )
    return "이번 주는 회의와 딥워크 균형이 좋았어요."


_WEEK_IDS = {"6/7~6/13": "wr-2026-w24"}


def _week_id(week_label: str) -> str:
    return _WEEK_IDS.get(week_label, "wr-" + week_label.replace("/", "").replace("~", "-"))


def run_weekly_review(session: Session, *, week_label: str = "6/7~6/13") -> WeeklyReview:
    wid = _week_id(week_label)
    existing = session.get(WeeklyReview, wid)
    if existing:  # 멱등: 이미 만들어진 주간 리뷰(시드 데모 값)는 보존
        return existing
    agg = _aggregate_week(session)
    patterns = _find_patterns(agg)
    wr = WeeklyReview(
        id=wid,
        week_label=week_label,
        deep_work_h=agg["deep_work_h"],
        meeting_h=agg["meeting_h"],
        done_count=agg["done"],
        auto_count=agg["auto"],
        saved_minutes=agg["saved_min"],
        patterns_json=_dumps(patterns),
        note=_coach_note(agg, patterns),
    )
    session.add(wr)
    session.commit()
    bus.publish("weekly.reviewed", {"id": wr.id, "patterns": len(patterns)})
    return wr
