"""API Key 管理路由"""

import hashlib
import secrets
from datetime import datetime

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

from yuxi.storage.postgres.models_business import User, APIKey
from server.utils.auth_middleware import get_db, get_required_user, get_superadmin_user
from yuxi.utils.datetime_utils import coerce_any_to_utc_datetime, utc_now_naive

apikey_router = APIRouter(prefix="/apikey", tags=["apikey"])


def generate_api_key() -> tuple[str, str, str]:
    """生成新的 API Key

    Returns: (full_key, key_hash, key_prefix)
    - full_key: 完整密钥，仅在创建时返回一次
    - key_hash: 存储到数据库的哈希值
    - key_prefix: 保存前缀用于显示
    """
    random_part = secrets.token_hex(24)
    full_key = f"yxkey_{random_part}"
    key_hash = hashlib.sha256(full_key.encode()).hexdigest()
    key_prefix = full_key[:12]
    return full_key, key_hash, key_prefix


class APIKeyCreate(BaseModel):
    name: str
    user_id: int | None = None
    department_id: int | None = None
    expires_at: str | None = None


class APIKeyUpdate(BaseModel):
    name: str | None = None
    expires_at: str | None = None
    is_enabled: bool | None = None


class APIKeyResponse(BaseModel):
    id: int
    key_prefix: str
    name: str
    user_id: int | None
    department_id: int | None
    expires_at: str | None
    is_enabled: bool
    last_used_at: str | None
    created_by: str
    created_at: str


class APIKeyCreateResponse(BaseModel):
    api_key: APIKeyResponse
    secret: str


@apikey_router.get("/", response_model=dict)
async def list_api_keys(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    current_user: User = Depends(get_required_user),
    db: AsyncSession = Depends(get_db),
):
    """列出当前用户的 API Keys"""
    # 普通用户只能看到自己的 API Keys
    if current_user.role == "superadmin":
        # superadmin 可以看到所有
        result = await db.execute(select(APIKey).order_by(APIKey.created_at.desc()).offset(skip).limit(limit))
        api_keys = result.scalars().all()
        total_result = await db.execute(select(func.count(APIKey.id)))
    else:
        # 普通用户只看自己的
        result = await db.execute(
            select(APIKey)
            .filter(APIKey.user_id == current_user.id)
            .order_by(APIKey.created_at.desc())
            .offset(skip)
            .limit(limit)
        )
        api_keys = result.scalars().all()
        total_result = await db.execute(
            select(func.count(APIKey.id)).filter(APIKey.user_id == current_user.id)
        )
    total = total_result.scalar()

    return {
        "api_keys": [key.to_dict() for key in api_keys],
        "total": total,
    }


@apikey_router.post("/", response_model=APIKeyCreateResponse)
async def create_api_key(
    data: APIKeyCreate,
    current_user: User = Depends(get_required_user),
    db: AsyncSession = Depends(get_db),
):
    """创建新 API Key（secret 仅在此处返回一次）"""
    # 生成 Key
    full_key, key_hash, key_prefix = generate_api_key()

    # 普通用户只能为自己创建 API Key，不能指定其他用户
    if data.user_id and data.user_id != current_user.id and current_user.role != "superadmin":
        raise HTTPException(status_code=403, detail="无权为其他用户创建 API Key")

    # 验证关联用户
    if data.user_id:
        result = await db.execute(select(User).filter(User.id == data.user_id))
        user = result.scalar_one_or_none()
        if not user or user.is_deleted:
            raise HTTPException(status_code=404, detail="关联的用户不存在")
    else:
        # 自动绑定为当前登录用户
        data.user_id = current_user.id

    # 解析过期时间（转换为 naive datetime 以匹配数据库字段）
    expires_at = None
    if data.expires_at:
        aware_dt = coerce_any_to_utc_datetime(data.expires_at)
        if aware_dt:
            expires_at = aware_dt.replace(tzinfo=None)

    # 创建记录
    api_key = APIKey(
        key_hash=key_hash,
        key_prefix=key_prefix,
        name=data.name,
        user_id=data.user_id,
        department_id=data.department_id,
        expires_at=expires_at,
        created_by=str(current_user.id),
    )

    db.add(api_key)
    await db.commit()
    await db.refresh(api_key)

    return APIKeyCreateResponse(
        api_key=APIKeyResponse(**api_key.to_dict()),
        secret=full_key,
    )


@apikey_router.get("/{api_key_id}", response_model=dict)
async def get_api_key(
    api_key_id: int,
    current_user: User = Depends(get_required_user),
    db: AsyncSession = Depends(get_db),
):
    """获取单个 API Key（只能操作自己的 Key）"""
    result = await db.execute(select(APIKey).filter(APIKey.id == api_key_id))
    api_key = result.scalar_one_or_none()

    if not api_key:
        raise HTTPException(status_code=404, detail="API Key 不存在")

    # 检查权限：只能操作自己的 Key，或者 superadmin 可以操作所有
    if api_key.user_id != current_user.id and current_user.role != "superadmin":
        raise HTTPException(status_code=403, detail="无权操作此 API Key")

    return {"api_key": api_key.to_dict()}


@apikey_router.put("/{api_key_id}", response_model=dict)
async def update_api_key(
    api_key_id: int,
    data: APIKeyUpdate,
    current_user: User = Depends(get_required_user),
    db: AsyncSession = Depends(get_db),
):
    """更新 API Key（只能操作自己的 Key）"""
    result = await db.execute(select(APIKey).filter(APIKey.id == api_key_id))
    api_key = result.scalar_one_or_none()

    if not api_key:
        raise HTTPException(status_code=404, detail="API Key 不存在")

    # 检查权限：只能操作自己的 Key，或者 superadmin 可以操作所有
    if api_key.user_id != current_user.id and current_user.role != "superadmin":
        raise HTTPException(status_code=403, detail="无权操作此 API Key")

    if data.name is not None:
        api_key.name = data.name

    if data.expires_at is not None:
        aware_dt = coerce_any_to_utc_datetime(data.expires_at)
        api_key.expires_at = aware_dt.replace(tzinfo=None) if aware_dt else None

    if data.is_enabled is not None:
        api_key.is_enabled = data.is_enabled

    await db.commit()
    await db.refresh(api_key)

    return {"api_key": api_key.to_dict()}


@apikey_router.delete("/{api_key_id}", response_model=dict)
async def delete_api_key(
    api_key_id: int,
    current_user: User = Depends(get_required_user),
    db: AsyncSession = Depends(get_db),
):
    """删除 API Key（只能操作自己的 Key）"""
    result = await db.execute(select(APIKey).filter(APIKey.id == api_key_id))
    api_key = result.scalar_one_or_none()

    if not api_key:
        raise HTTPException(status_code=404, detail="API Key 不存在")

    # 检查权限：只能操作自己的 Key，或者 superadmin 可以操作所有
    if api_key.user_id != current_user.id and current_user.role != "superadmin":
        raise HTTPException(status_code=403, detail="无权操作此 API Key")

    await db.delete(api_key)
    await db.commit()

    return {"success": True}


@apikey_router.post("/{api_key_id}/regenerate", response_model=APIKeyCreateResponse)
async def regenerate_api_key(
    api_key_id: int,
    current_user: User = Depends(get_required_user),
    db: AsyncSession = Depends(get_db),
):
    """重新生成 API Key 密钥（secret 仅在此处返回一次，只能操作自己的 Key）"""
    result = await db.execute(select(APIKey).filter(APIKey.id == api_key_id))
    api_key = result.scalar_one_or_none()

    if not api_key:
        raise HTTPException(status_code=404, detail="API Key 不存在")

    # 检查权限：只能操作自己的 Key，或者 superadmin 可以操作所有
    if api_key.user_id != current_user.id and current_user.role != "superadmin":
        raise HTTPException(status_code=403, detail="无权操作此 API Key")

    # 生成新密钥
    full_key, key_hash, key_prefix = generate_api_key()

    api_key.key_hash = key_hash
    api_key.key_prefix = key_prefix

    await db.commit()
    await db.refresh(api_key)

    return APIKeyCreateResponse(
        api_key=APIKeyResponse(**api_key.to_dict()),
        secret=full_key,
    )
