"""User custom sticker HTTP routes."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field

if TYPE_CHECKING:
    from niannian.client import NianNian


class CreateUserStickerBody(BaseModel):
    attachment_id: str = Field(min_length=1)
    label: str | None = Field(default=None, max_length=32)


def create_chat_user_stickers_router(nn: NianNian) -> APIRouter:
    router = APIRouter(prefix="/v1/chat/stickers", tags=["chat"])

    @router.get("/user")
    def list_user_stickers_route(request: Request) -> dict[str, Any]:
        from niannian.chat.user_stickers import list_user_stickers
        from niannian.tenant.context import resolve_request_context
        from niannian.token.budget import chat_sticker_allows, load_token_budget

        ctx = resolve_request_context(request, nn._config, home=nn._home)
        budget = load_token_budget(nn._home, ctx.user_id)
        if not chat_sticker_allows(budget, "user"):
            raise HTTPException(
                status_code=403,
                detail={"code": "token_budget_sticker_disabled", "message": "聊天表情包已在 Token 页关闭"},
            )
        return list_user_stickers(nn._home, ctx.user_id)

    @router.post("/user", status_code=201)
    def create_user_sticker_route(request: Request, payload: CreateUserStickerBody) -> dict[str, Any]:
        from niannian.chat.user_stickers import UserStickerError, add_user_sticker_from_attachment
        from niannian.tenant.context import resolve_request_context
        from niannian.token.budget import chat_sticker_allows, load_token_budget

        ctx = resolve_request_context(request, nn._config, home=nn._home)
        budget = load_token_budget(nn._home, ctx.user_id)
        if not chat_sticker_allows(budget, "user"):
            raise HTTPException(
                status_code=403,
                detail={"code": "token_budget_sticker_disabled", "message": "聊天表情包已在 Token 页关闭"},
            )
        try:
            sticker = add_user_sticker_from_attachment(
                nn._home,
                ctx.user_id,
                payload.attachment_id,
                label=payload.label,
            )
        except UserStickerError as exc:
            status = 404 if exc.code in {"invalid_attachment", "sticker_not_found"} else 400
            if exc.code == "sticker_limit_reached":
                status = 409
            raise HTTPException(status_code=status, detail={"code": exc.code, "message": exc.message}) from exc
        return {"sticker": sticker}

    @router.delete("/user/{sticker_id}")
    def delete_user_sticker_route(request: Request, sticker_id: str) -> dict[str, Any]:
        from niannian.chat.user_stickers import delete_user_sticker, is_user_sticker_id
        from niannian.tenant.context import resolve_request_context

        ctx = resolve_request_context(request, nn._config, home=nn._home)
        if not is_user_sticker_id(sticker_id):
            raise HTTPException(status_code=400, detail={"code": "invalid_sticker_id"})
        if not delete_user_sticker(nn._home, ctx.user_id, sticker_id):
            raise HTTPException(status_code=404, detail={"code": "sticker_not_found"})
        return {"ok": True, "sticker_id": sticker_id}

    @router.get("/user/{sticker_id}/image")
    def get_user_sticker_image(request: Request, sticker_id: str) -> FileResponse:
        from niannian.chat.user_stickers import is_user_sticker_id, user_sticker_image_path
        from niannian.tenant.context import resolve_request_context

        ctx = resolve_request_context(request, nn._config, home=nn._home)
        if not is_user_sticker_id(sticker_id):
            raise HTTPException(status_code=400, detail={"code": "invalid_sticker_id"})
        path = user_sticker_image_path(nn._home, ctx.user_id, sticker_id)
        if path is None:
            raise HTTPException(status_code=404, detail={"code": "sticker_not_found"})
        return FileResponse(path, media_type="image/png")

    return router
