"""用户通知中心 API"""

import uuid as _uuid
from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.compat import UTC
from app.core.permissions import get_current_user
from app.db import get_db
from app.models.operations import SystemNotification

router = APIRouter()

def uid(u: dict) -> _uuid.UUID: return _uuid.UUID(u["sub"])


@router.get("", response_model=dict, summary="通知列表")
async def list_notifications(
    db: AsyncSession = Depends(get_db),
    user: dict = Depends(get_current_user),
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
):
    """获取用户通知列表"""
    offset = (page - 1) * page_size
    # 先获取总数
    count_result = await db.execute(
        select(func.count(SystemNotification.id))
        .where((SystemNotification.target_type == "all") | (SystemNotification.target_id == uid(user)))
    )
    total = count_result.scalar() or 0
    # 分页获取
    result = await db.execute(
        select(SystemNotification)
        .where((SystemNotification.target_type == "all") | (SystemNotification.target_id == uid(user)))
        .order_by(SystemNotification.created_at.desc())
        .offset(offset).limit(page_size)
    )
    items = result.scalars().all()
    unread = sum(1 for n in items if not n.is_read)
    return {
        "items": [{"id": str(n.id), "title": n.title, "content": n.content, "is_read": n.is_read,
                    "created_at": n.created_at.isoformat() if n.created_at else None} for n in items],
        "unread": unread, "total": total,
    }


@router.post("/{nid}/read", response_model=dict, summary="标记已读")
async def mark_read(nid: str, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    result = await db.execute(select(SystemNotification).where(SystemNotification.id == _uuid.UUID(nid)))
    n = result.scalar()
    if n: n.is_read = True; n.read_at = datetime.now(UTC); await db.commit()
    return {"status": "ok"}


@router.delete("/{nid}", response_model=dict, summary="删除通知")
async def delete_notification(nid: str, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    try:
        nid_uuid = _uuid.UUID(nid)
    except ValueError:
        raise HTTPException(status_code=400, detail="Invalid notification ID")
    result = await db.execute(
        select(SystemNotification).where(
            SystemNotification.id == nid_uuid,
            (SystemNotification.target_id == uid(user)) | (SystemNotification.target_type == "all"),
        )
    )
    n = result.scalar()
    if not n:
        raise HTTPException(status_code=404, detail="Notification not found")
    await db.delete(n)
    await db.commit()
    return {"status": "deleted"}


@router.post("/read-all", response_model=dict, summary="全部已读")
async def mark_all_read(db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    result = await db.execute(
        select(SystemNotification)
        .where(
            SystemNotification.is_read == False,
            (SystemNotification.target_id == uid(user)) | (SystemNotification.target_type == "all"),
        )
    )
    for n in result.scalars(): n.is_read = True
    await db.commit()
    return {"status": "ok"}
