"""Operational feed API. Spec 041 · OF-API-002."""

from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field

from app import auth
from app.ops_inbox_store import (
    add_message,
    get_event,
    inbox_stats,
    init_inbox_schema,
    list_events,
    patch_event,
)
from app.permissions import can_manage_users

router = APIRouter(prefix="/api/v1/ops-inbox", tags=["ops-inbox"])


class InboxMessageBody(BaseModel):
    body: str = Field(min_length=1, max_length=8000)
    note_type: str = Field(default="reply", pattern="^(reply|internal_note)$")


class InboxPatchBody(BaseModel):
    status: str | None = Field(default=None, pattern="^(open|pending|resolved)$")
    assignee: str | None = None
    priority: str | None = Field(default=None, pattern="^(normal|high|critical)$")


def _db():
    conn = auth.db()
    try:
        init_inbox_schema(conn)
        yield conn
    finally:
        conn.close()


def _require_inbox(user: auth.DeskUser) -> None:
    if not can_manage_users(user.role):
        raise HTTPException(403, "insufficient permissions")


@router.get("/stats")
def inbox_statistics(
    user: auth.DeskUser = Depends(auth.get_current_user),
    conn=Depends(_db),
):
    _require_inbox(user)
    return inbox_stats(conn)


@router.get("/events")
def inbox_events(
    channel: str | None = Query(default="all"),
    priority: str | None = Query(default=None),
    status: str | None = Query(default=None),
    q: str | None = Query(default=None),
    limit: int = Query(default=128, ge=1, le=500),
    user: auth.DeskUser = Depends(auth.get_current_user),
    conn=Depends(_db),
):
    _require_inbox(user)
    items = list_events(conn, channel=channel, priority=priority, status=status, q=q, limit=limit)
    return {"events": items, "total": len(items)}


@router.get("/events/{event_id}")
def inbox_event_detail(
    event_id: str,
    user: auth.DeskUser = Depends(auth.get_current_user),
    conn=Depends(_db),
):
    _require_inbox(user)
    ev = get_event(conn, event_id)
    if not ev:
        raise HTTPException(404, "event not found")
    return {"event": ev}


@router.post("/events/{event_id}/messages")
def inbox_post_message(
    event_id: str,
    body: InboxMessageBody,
    user: auth.DeskUser = Depends(auth.get_current_user),
    conn=Depends(_db),
):
    _require_inbox(user)
    if not get_event(conn, event_id):
        raise HTTPException(404, "event not found")
    author_type = "internal" if body.note_type == "internal_note" else "operator"
    label = user.display_name or user.username
    msg = add_message(conn, event_id, author_type, label, body.body)
    conn.commit()
    return {"message": msg}


@router.patch("/events/{event_id}")
def inbox_patch(
    event_id: str,
    body: InboxPatchBody,
    user: auth.DeskUser = Depends(auth.get_current_user),
    conn=Depends(_db),
):
    _require_inbox(user)
    ev = patch_event(
        conn,
        event_id,
        status=body.status,
        assignee=body.assignee,
        priority=body.priority,
    )
    if not ev:
        raise HTTPException(404, "event not found")
    conn.commit()
    return {"event": ev}
