"""admin 反馈工单:列表筛选 + 审核采纳/拒绝(带金币发放与审计)。"""
from __future__ import annotations

from datetime import datetime
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query, Request

from app.admin.audit import write_audit
from app.admin.deps import AdminDb, get_client_ip, get_current_admin, require_role
from app.admin.repositories import mutations, queries
from app.admin.schemas.common import CursorPage, OkResponse
from app.admin.schemas.feedback import FeedbackApproveRequest, FeedbackOut, FeedbackRejectRequest
from app.models.admin import AdminUser
from app.models.feedback import Feedback
from app.repositories import wallet as wallet_repo

router = APIRouter(
    prefix="/admin/api/feedbacks",
    tags=["admin-feedback"],
    dependencies=[Depends(get_current_admin)],
)


def _ensure_pending(fb: Feedback) -> None:
    if fb.status not in {"pending", "new"}:
        raise HTTPException(status_code=400, detail="反馈已审核")


@router.get("", response_model=CursorPage[FeedbackOut], summary="反馈工单列表")
def list_feedbacks(
    db: AdminDb,
    status: Annotated[str | None, Query()] = None,
    user_id: Annotated[int | None, Query()] = None,
    content: Annotated[str | None, Query(max_length=100)] = None,
    created_from: Annotated[datetime | None, Query()] = None,
    created_to: Annotated[datetime | None, Query()] = None,
    sort_by: Annotated[str, Query(pattern="^(id|created_at)$")] = "id",
    sort_order: Annotated[str, Query(pattern="^(asc|desc)$")] = "desc",
    limit: Annotated[int, Query(ge=1, le=100)] = 20,
    cursor: Annotated[int | None, Query()] = None,
) -> CursorPage[FeedbackOut]:
    items, next_cursor, total = queries.list_feedbacks(
        db,
        status=status,
        user_id=user_id,
        content=content,
        created_from=created_from,
        created_to=created_to,
        sort_by=sort_by,
        sort_order=sort_order,
        limit=limit,
        cursor=cursor,
    )
    return CursorPage(
        items=[FeedbackOut.model_validate(f) for f in items],
        next_cursor=next_cursor,
        total=total,
    )


@router.post("/{feedback_id}/handle", response_model=OkResponse, summary="标记反馈已处理")
def handle_feedback(
    feedback_id: int,
    _admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
) -> OkResponse:
    fb = db.get(Feedback, feedback_id)
    if fb is None:
        raise HTTPException(status_code=404, detail="反馈不存在")
    raise HTTPException(status_code=400, detail="请使用采纳或拒绝接口审核反馈")


@router.post("/{feedback_id}/approve", response_model=FeedbackOut, summary="采纳反馈并发金币")
def approve_feedback(
    feedback_id: int,
    payload: FeedbackApproveRequest,
    request: Request,
    admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
) -> FeedbackOut:
    fb = db.get(Feedback, feedback_id)
    if fb is None:
        raise HTTPException(status_code=404, detail="反馈不存在")
    _ensure_pending(fb)

    before = fb.status
    mutations.review_feedback(
        db,
        fb,
        status="adopted",
        reward_coins=payload.reward_coins,
        review_note=payload.note,
        reviewed_by_admin_id=admin.id,
        commit=False,
    )
    wallet_repo.grant_coins(
        db,
        fb.user_id,
        payload.reward_coins,
        biz_type="feedback_reward",
        ref_id=str(fb.id),
        remark="意见反馈被采纳",
    )
    write_audit(
        db,
        admin,
        action="feedback.approve",
        target_type="feedback",
        target_id=feedback_id,
        detail={
            "before": before,
            "after": "adopted",
            "reward_coins": payload.reward_coins,
            "note": payload.note,
        },
        ip=get_client_ip(request),
        commit=False,
    )
    db.commit()
    db.refresh(fb)
    return FeedbackOut.model_validate(fb)


@router.post("/{feedback_id}/reject", response_model=FeedbackOut, summary="拒绝采纳反馈")
def reject_feedback(
    feedback_id: int,
    payload: FeedbackRejectRequest,
    request: Request,
    admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
) -> FeedbackOut:
    fb = db.get(Feedback, feedback_id)
    if fb is None:
        raise HTTPException(status_code=404, detail="反馈不存在")
    _ensure_pending(fb)

    before = fb.status
    mutations.review_feedback(
        db,
        fb,
        status="rejected",
        reject_reason=payload.reason,
        review_note=payload.note,
        reviewed_by_admin_id=admin.id,
        commit=False,
    )
    write_audit(
        db,
        admin,
        action="feedback.reject",
        target_type="feedback",
        target_id=feedback_id,
        detail={
            "before": before,
            "after": "rejected",
            "reason": payload.reason,
            "note": payload.note,
        },
        ip=get_client_ip(request),
        commit=False,
    )
    db.commit()
    db.refresh(fb)
    return FeedbackOut.model_validate(fb)
