"""The notification API (M5 engine, M6 projection): the viewer's
notifications (newest first, capped) plus mark-read endpoints. Sync def
(react.md: sync for DB routes). Auth: the default-deny middleware gates
every route here; the RECIPIENT is never accepted from the client
(mirrors ref §2.7's authorship-stamping port note applied to `recipient`
instead of `author`).

M6 read/write split: the GET list is a READ, so it belongs to the
resolved VIEWER (View As shows the target's bell — that is the
walkthrough tool working as designed) with actors rep()'d for that
viewer; mark-read/mark-all-read are WRITES and stay bound to the real
session player, so a read-only View As can peek at a bell but never
silently clear it."""
from __future__ import annotations

import uuid

from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse
from sqlalchemy.orm import Session

from ..auth import current_player
from ..db import get_db
from ..schemas import NotificationOut, NotificationsOut
from ..services import notifications as notifications_service
from ..services import viewer as viewer_service

router = APIRouter()


def _error_response(err: notifications_service.NotificationError) -> JSONResponse:
    return JSONResponse(
        status_code=err.status_code,
        content={
            "error_code": err.error_code,
            "summary": err.summary,
            "detail": err.detail,
        },
    )


@router.get("/api/notifications", response_model=NotificationsOut)
def list_notifications(request: Request, db: Session = Depends(get_db)):
    viewer = viewer_service.resolve_viewer(request, db)
    if viewer is None:
        # A signed-in BW user with no Player row yet has no recipient
        # identity — nothing is theirs (mirrors create_ball/create_comment's
        # tolerance of a None actor, just on the read side).
        return {"items": [], "unread_count": 0, "unresolved_count": 0}
    return notifications_service.list_for_recipient(db, viewer.id)


@router.post("/api/notifications/{notification_id}/read", response_model=NotificationOut)
def mark_read(notification_id: uuid.UUID, request: Request, db: Session = Depends(get_db)):
    actor = current_player(request)
    try:
        return notifications_service.mark_read(db, notification_id, actor)
    except notifications_service.NotificationError as err:
        return _error_response(err)


@router.post("/api/notifications/read-all")
def mark_all_read(request: Request, db: Session = Depends(get_db)):
    actor = current_player(request)
    updated = notifications_service.mark_all_read(db, actor)
    return {"updated": updated}
