"""API 管理：Key 生成 + 调用日志 + Webhook"""

import secrets
import uuid as _uuid
from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
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.core.tenant_context import tenant_ctx
from app.db import get_db
from app.models.operations import ApiKey, ApiUsageLog

router = APIRouter()


class CreateApiKeyRequest(BaseModel):
    name: str
    scopes: list[str] = ["read"]


class CreateWebhookRequest(BaseModel):
    url: str
    events: list[str] = ["literature.new"]


@router.get("/keys", summary="密钥列表")
async def list_keys(db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    tid = tenant_ctx.get()
    if not tid: return {"items": [], "total": 0}
    result = await db.execute(
        select(ApiKey).where(ApiKey.tenant_id == _uuid.UUID(tid), ApiKey.is_active == True)
    )
    keys = result.scalars().all()
    return {"items": [{"id": str(k.id), "name": k.name, "prefix": k.key_prefix,
                        "scopes": k.scopes, "last_used": k.last_used_at.isoformat() if k.last_used_at else None,
                        "created_at": k.created_at.isoformat() if k.created_at else None}
                      for k in keys], "total": len(keys)}


@router.post("/keys", summary="创建密钥")
async def create_key(req: CreateApiKeyRequest, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    tid = tenant_ctx.get()
    if not tid: return {"status": "skipped", "note": "请先加入团队以使用 API 管理功能"}
    raw_key = "sk-" + secrets.token_hex(32)
    import hashlib
    key_hash = hashlib.sha256(raw_key.encode()).hexdigest()
    key = ApiKey(
        id=_uuid.uuid4(), tenant_id=_uuid.UUID(tid), user_id=_uuid.UUID(user["sub"]),
        name=req.name, key_prefix=raw_key[:12], key_hash=key_hash, scopes=req.scopes, is_active=True,
    )
    db.add(key); await db.commit()
    return {"status": "created", "api_key": raw_key, "prefix": raw_key[:12], "note": "保存此密钥，此后不再显示完整密钥"}


@router.delete("/keys/{kid}", summary="撤销密钥")
async def revoke_key(kid: str, db: AsyncSession = Depends(get_db)):
    k = (await db.execute(select(ApiKey).where(ApiKey.id == _uuid.UUID(kid)))).scalar()
    if not k: raise HTTPException(404)
    k.is_active = False; await db.commit()
    return {"status": "revoked"}


@router.get("/usage", summary="调用统计")
async def api_usage(
    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),
):
    tid = tenant_ctx.get()
    if not tid: return {"total": 0, "items": []}
    offset = (page - 1) * page_size
    tid_uuid = _uuid.UUID(tid)
    total = (await db.execute(select(func.count(ApiUsageLog.id)).where(ApiUsageLog.tenant_id == tid_uuid))).scalar() or 0
    result = await db.execute(
        select(ApiUsageLog).where(ApiUsageLog.tenant_id == tid_uuid)
        .order_by(ApiUsageLog.created_at.desc()).offset(offset).limit(page_size)
    )
    logs = result.scalars().all()
    return {"total": total, "items": [{"endpoint": log.endpoint, "method": log.method, "status": log.status_code,
                                       "ms": log.response_ms, "ip": log.ip_address,
                                       "time": log.created_at.isoformat() if log.created_at else None}
                                     for log in logs]}


# Webhook 管理（暂存于 tenant settings）
@router.get("/webhooks", summary="Webhook列表")
async def list_webhooks(db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    tid = tenant_ctx.get()
    if not tid: return {"items": [], "total": 0}
    from app.models.user import Tenant
    t = (await db.execute(select(Tenant.settings).where(Tenant.id == _uuid.UUID(tid)))).scalar()
    hooks = (t or {}).get("webhooks", [])
    return {"items": hooks, "total": len(hooks)}


@router.post("/webhooks", summary="创建Webhook")
async def create_webhook(req: CreateWebhookRequest, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    tid = tenant_ctx.get()
    if not tid: return {"status": "skipped", "note": "请先加入团队以使用 Webhook 功能"}
    from app.models.user import Tenant
    t = (await db.execute(select(Tenant).where(Tenant.id == _uuid.UUID(tid)))).scalar()
    if not t: raise HTTPException(404)
    settings = dict(t.settings or {})
    hooks = settings.get("webhooks", [])
    hooks.append({"id": _uuid.uuid4().hex[:8], "url": req.url, "events": req.events,
                   "created_at": datetime.now(UTC).isoformat()})
    settings["webhooks"] = hooks
    t.settings = settings
    await db.commit()
    return {"status": "created"}


@router.delete("/webhooks/{wid}", summary="删除Webhook")
async def delete_webhook(wid: str, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    tid = tenant_ctx.get()
    if not tid: return {"status": "skipped", "note": "请先加入团队以使用 Webhook 功能"}
    from app.models.user import Tenant
    t = (await db.execute(select(Tenant).where(Tenant.id == _uuid.UUID(tid)))).scalar()
    if not t: raise HTTPException(404)
    settings = dict(t.settings or {})
    hooks = settings.get("webhooks", [])
    settings["webhooks"] = [h for h in hooks if h.get("id") != wid]
    t.settings = settings
    await db.commit()
    return {"status": "deleted"}
