# backend/app/routers/notify.py
import uuid

from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session, select

from ..auth.deps import current_user
from ..auth.scope import scoped
from ..automation.event_bus import publish
from ..db import get_session
from ..models import (
    Digest,
    Notification,
    NotificationGuard,
    NotifyBucket,
    NotifyStats,
    Person,
    SenderRule,
)
from ..schemas import (
    DigestOut,
    GuardOut,
    GuardPatch,
    NotificationOut,
    ReclassifyNotifRequest,
    SenderRuleCreate,
    SenderRuleOut,
    TriageOut,
)
from ..services.triage import detect_defer_pattern

router = APIRouter()


def _out(n: Notification) -> NotificationOut:
    return NotificationOut(
        id=n.id,
        bucket=n.bucket.value,
        src=n.src,
        app=n.app,
        title=n.title,
        sum=n.sum,
        time=n.time,
        why=n.why,
        tone=n.tone,
        act=n.act,
    )


@router.get("/notifications", response_model=TriageOut)
def triage(s: Session = Depends(get_session), user: Person = Depends(current_user)):
    rows = s.exec(
        scoped(select(Notification), Notification, user.id).order_by(Notification.sort_order)
    ).all()
    stats = s.get(NotifyStats, 1)
    buckets: dict[str, list] = {"now": [], "later": [], "held": []}
    for n in rows:
        buckets[n.bucket.value].append(_out(n))
    counts = {
        "now": len(buckets["now"]),
        "later": len(buckets["later"]) + (stats.later_more if stats else 0),
        "held": len(buckets["held"]) + (stats.held_more if stats else 0),
    }
    return TriageOut(
        now=buckets["now"],
        later=buckets["later"],
        held=buckets["held"],
        counts=counts,
        stats=(
            {"total": stats.total, "seen": stats.seen, "filtered": stats.filtered} if stats else {}
        ),
    )


@router.post("/notifications/{nid}/reclassify", response_model=NotificationOut)
def reclassify(nid: str, body: ReclassifyNotifRequest, s: Session = Depends(get_session)):
    n = s.get(Notification, nid)
    if not n:
        raise HTTPException(404, "notification not found")
    prev = n.bucket.value
    n.bucket = NotifyBucket(body.to_bucket)
    if body.to_bucket == "later":
        n.why, n.tone, n.act = "내가 미룸", "muted", ""
    elif body.to_bucket == "now" and prev == "held":
        n.why, n.tone = "되돌림", "amber"
    s.add(n)
    s.commit()
    if body.to_bucket == "later":
        publish("notification.triaged", {"id": nid, "to": "later", "by": "user"})
        for cand in detect_defer_pattern(s):
            publish("automation.suggested", cand)
    return _out(n)


@router.post("/notifications/{nid}/undo", response_model=NotificationOut)
def undo(nid: str, s: Session = Depends(get_session)):
    """held → now 되돌리기."""
    n = s.get(Notification, nid)
    if not n:
        raise HTTPException(404, "notification not found")
    n.bucket = NotifyBucket.now
    n.why, n.tone = "되돌림", "amber"
    s.add(n)
    s.commit()
    publish("notification.triaged", {"id": nid, "to": "now", "by": "undo"})
    return _out(n)


@router.get("/notifications/guard", response_model=GuardOut)
def get_guard(s: Session = Depends(get_session)):
    g = s.get(NotificationGuard, 1)
    return GuardOut(on=g.on, until=g.until, held=g.held, quiet=g.quiet)


@router.post("/notifications/guard", response_model=GuardOut)
def set_guard(body: GuardPatch, s: Session = Depends(get_session)):
    g = s.get(NotificationGuard, 1)
    g.on = body.on
    s.add(g)
    s.commit()
    return GuardOut(on=g.on, until=g.until, held=g.held, quiet=g.quiet)


@router.get("/notifications/digests", response_model=list[DigestOut])
def digests(s: Session = Depends(get_session)):
    return s.exec(select(Digest).order_by(Digest.sort_order)).all()


@router.get("/notifications/senders", response_model=list[SenderRuleOut])
def senders(s: Session = Depends(get_session)):
    rows = s.exec(select(SenderRule).order_by(SenderRule.sort_order)).all()
    return [
        SenderRuleOut(
            id=r.id,
            who=r.who,
            from_label=r.from_label,
            rule=r.rule,
            tone=r.tone,
            bucket=r.bucket.value,
        )
        for r in rows
    ]


@router.post("/notifications/senders", response_model=SenderRuleOut)
def add_sender(body: SenderRuleCreate, s: Session = Depends(get_session)):
    rid = "sr-" + uuid.uuid4().hex[:6]
    last = s.exec(select(SenderRule)).all()
    r = SenderRule(
        id=rid,
        who=body.who,
        from_label=body.from_label,
        rule=body.rule,
        bucket=NotifyBucket(body.bucket),
        tone=body.tone,
        sort_order=len(last),
    )
    s.add(r)
    s.commit()
    return SenderRuleOut(
        id=r.id,
        who=r.who,
        from_label=r.from_label,
        rule=r.rule,
        tone=r.tone,
        bucket=r.bucket.value,
    )
