# -*- coding: utf-8 -*-
"""
小程序头像上传路由。

端点清单：
- POST /api/xcx/avatar/upload  — 上传头像（chooseAvatar 临时文件 → 服务器持久化）
- GET  /api/xcx/avatar/{user_id} — 获取头像文件（静态文件服务）
"""

from __future__ import annotations

import logging
from pathlib import Path

from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, status
from fastapi.responses import FileResponse

from app import config
from app.auth.dependencies import CurrentUser, get_current_user_or_limited
from app.database import get_connection
from app.schemas.base import CamelModel
from app.trace.decorators import trace_service

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/xcx/avatar", tags=["小程序头像"])


def _get_avatar_dir() -> Path:
    """获取头像存储目录，不存在则创建。"""
    avatar_path = config.AVATAR_EXPORT_PATH
    if not avatar_path:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="AVATAR_EXPORT_PATH 未配置",
        )
    p = Path(avatar_path)
    p.mkdir(parents=True, exist_ok=True)
    return p


class AvatarUploadResponse(CamelModel):
    """头像上传响应。"""
    avatar_url: str


# ── POST /api/xcx/avatar/upload ──────────────────────────

@router.post("/upload", response_model=AvatarUploadResponse)
@trace_service("上传头像", "Upload avatar")
async def upload_avatar(
    file: UploadFile = File(...),
    user: CurrentUser = Depends(get_current_user_or_limited),
):
    """
    接收小程序 chooseAvatar 上传的头像文件。

    流程：
    1. 读取上传文件内容
    2. 保存到 AVATAR_EXPORT_PATH/{user_id}.jpg（覆盖式，幂等）
    3. 更新 auth.users.avatar_url
    4. 返回相对路径
    """
    avatar_dir = _get_avatar_dir()
    # 固定 jpg 后缀，覆盖式保存
    filename = f"{user.user_id}.jpg"
    filepath = avatar_dir / filename
    relative_url = f"avatars/{filename}"

    # 读取并保存文件
    content = await file.read()
    if len(content) == 0:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="上传文件为空",
        )
    # 限制 2MB
    if len(content) > 2 * 1024 * 1024:
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail="头像文件不能超过 2MB",
        )

    filepath.write_bytes(content)
    logger.info("头像已保存: user_id=%s, path=%s", user.user_id, filepath)

    # 更新数据库
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                "UPDATE auth.users SET avatar_url = %s WHERE id = %s",
                (relative_url, user.user_id),
            )
            conn.commit()
    finally:
        conn.close()

    return AvatarUploadResponse(avatar_url=relative_url)


# ── GET /api/xcx/avatar/{user_id} ────────────────────────

@router.get("/{user_id}")
async def get_avatar(user_id: int):
    """
    获取用户头像文件。

    无需鉴权（头像为公开资源，通过 user_id 访问）。
    文件不存在时返回 404。
    """
    avatar_dir = _get_avatar_dir()
    filepath = avatar_dir / f"{user_id}.jpg"

    if not filepath.exists():
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="头像不存在",
        )

    return FileResponse(
        path=str(filepath),
        media_type="image/jpeg",
        headers={"Cache-Control": "public, max-age=3600"},
    )
