# =============================================================================
# 企微IT智能服务台 — 快速回复模板 API
# =============================================================================
# 说明：坐席端的快速回复模板管理接口，包括：
#   1. GET /api/quick-replies — 获取模板列表（按分类）
#   2. POST /api/quick-replies — 创建模板
#   3. PUT /api/quick-replies/{id} — 更新模板
#   4. DELETE /api/quick-replies/{id} — 删除模板
# =============================================================================

import logging
from typing import Optional
from uuid import UUID

from fastapi import APIRouter, Depends, Header, Query
from sqlalchemy import or_, and_
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.models.agent import Agent
from app.models.quick_reply_template import QuickReplyTemplate
from app.schemas.quick_reply import (
    QuickReplyCreate,
    QuickReplyResponse,
    QuickReplyUpdate,
)
from app.utils.response import AppException, ERR_NOT_FOUND, ERR_UNAUTHORIZED, success_response

logger = logging.getLogger(__name__)

# 创建路由器
router = APIRouter()


# --------------------------------------------------------------------------
# 可选坐席认证（有 token 则认证，无 token 则跳过）
# --------------------------------------------------------------------------
async def get_optional_agent(
    authorization: Optional[str] = Header(None, alias="Authorization"),
    db: AsyncSession = Depends(get_db),
) -> Optional[Agent]:
    """可选坐席认证依赖。

    有 Authorization 头时尝试认证，无或认证失败时返回 None。

    Args:
        authorization: 请求头中的 Authorization 字段
        db: 数据库会话

    Returns:
        Optional[Agent]: 认证成功返回坐席对象，否则返回 None
    """
    if not authorization:
        return None

    token = authorization.replace("Bearer ", "") if authorization.startswith("Bearer ") else authorization
    if not token:
        return None

    try:
        import redis.asyncio as aioredis
        from app.config import settings

        redis_client = settings.create_redis_client()
        try:
            agent_user_id = await redis_client.get(f"agent:token:{token}")
            if not agent_user_id:
                return None

            uid = agent_user_id.decode("utf-8") if isinstance(agent_user_id, bytes) else agent_user_id
            stmt = select(Agent).where(Agent.user_id == uid)
            result = await db.execute(stmt)
            agent = result.scalars().first()
            return agent
        finally:
            try:
                await redis_client.close()
            except Exception:
                pass
    except Exception as e:
        logger.warning(f"可选坐席认证失败: {e}")
        return None


# --------------------------------------------------------------------------
# GET /api/quick-replies — 获取模板列表
# --------------------------------------------------------------------------
@router.get("/quick-replies")
async def list_quick_replies(
    category: Optional[str] = Query(None, description="按分类过滤: 账号/网络/软件/硬件/通用"),
    db: AsyncSession = Depends(get_db),
    agent: Optional[Agent] = Depends(get_optional_agent),
):
    """获取快速回复模板列表。

    支持按分类过滤，按 sort_order 排序。
    坐席端可见性规则：
    - 有认证：返回 approved + 自己的 pending_review
    - 无认证：只返回 approved

    Args:
        category: 按分类过滤（可选）
        db: 数据库会话
        agent: 当前坐席（可选认证）

    Returns:
        Dict: 统一响应格式，包含模板列表
    """
    stmt = select(QuickReplyTemplate).order_by(
        QuickReplyTemplate.category, QuickReplyTemplate.sort_order
    )

    if category:
        stmt = stmt.where(QuickReplyTemplate.category == category)

    # 状态筛选：坐席端可见性规则
    if agent:
        # 有认证：approved + 自己的 pending_review
        stmt = stmt.where(
            or_(
                QuickReplyTemplate.status == "approved",
                and_(
                    QuickReplyTemplate.status == "pending_review",
                    QuickReplyTemplate.submitted_by == agent.id,
                ),
            )
        )
    else:
        # 无认证：只返回 approved
        stmt = stmt.where(QuickReplyTemplate.status == "approved")

    result = await db.execute(stmt)
    templates = list(result.scalars().all())

    items = [QuickReplyResponse.model_validate(t).model_dump() for t in templates]
    return success_response(data={"items": items})


# --------------------------------------------------------------------------
# POST /api/quick-replies — 创建模板
# --------------------------------------------------------------------------
@router.post("/quick-replies")
async def create_quick_reply(
    body: QuickReplyCreate,
    db: AsyncSession = Depends(get_db),
):
    """创建快速回复模板。

    Args:
        body: 创建请求体（包含 category、title、content、variables、sort_order）
        db: 数据库会话

    Returns:
        Dict: 统一响应格式，包含创建的模板
    """
    template = QuickReplyTemplate(
        category=body.category,
        title=body.title,
        content=body.content,
        variables=body.variables,
        sort_order=body.sort_order,
    )
    db.add(template)
    await db.flush()

    logger.info(f"创建快速回复模板: category={body.category}, title={body.title}")

    template_data = QuickReplyResponse.model_validate(template).model_dump()
    return success_response(data=template_data)


# --------------------------------------------------------------------------
# PUT /api/quick-replies/{id} — 更新模板
# --------------------------------------------------------------------------
@router.put("/quick-replies/{template_id}")
async def update_quick_reply(
    template_id: UUID,
    body: QuickReplyUpdate,
    db: AsyncSession = Depends(get_db),
):
    """更新快速回复模板。

    只更新传入的字段（部分更新）。

    Args:
        template_id: 模板ID
        body: 更新请求体（所有字段可选）
        db: 数据库会话

    Returns:
        Dict: 统一响应格式，包含更新后的模板
    """
    # 查找模板
    stmt = select(QuickReplyTemplate).where(QuickReplyTemplate.id == template_id)
    result = await db.execute(stmt)
    template = result.scalars().first()

    if not template:
        raise ERR_NOT_FOUND

    # 只更新传入的字段
    if body.category is not None:
        template.category = body.category
    if body.title is not None:
        template.title = body.title
    if body.content is not None:
        template.content = body.content
    if body.variables is not None:
        template.variables = body.variables
    if body.sort_order is not None:
        template.sort_order = body.sort_order

    db.add(template)
    await db.flush()

    logger.info(f"更新快速回复模板: id={template_id}")

    template_data = QuickReplyResponse.model_validate(template).model_dump()
    return success_response(data=template_data)


# --------------------------------------------------------------------------
# DELETE /api/quick-replies/{id} — 删除模板
# --------------------------------------------------------------------------
@router.delete("/quick-replies/{template_id}")
async def delete_quick_reply(
    template_id: UUID,
    db: AsyncSession = Depends(get_db),
):
    """删除快速回复模板。

    第一步使用物理删除。

    Args:
        template_id: 模板ID
        db: 数据库会话

    Returns:
        Dict: 统一响应格式
    """
    # 查找模板
    stmt = select(QuickReplyTemplate).where(QuickReplyTemplate.id == template_id)
    result = await db.execute(stmt)
    template = result.scalars().first()

    if not template:
        raise ERR_NOT_FOUND

    # 物理删除
    await db.delete(template)
    await db.flush()

    logger.info(f"删除快速回复模板: id={template_id}")

    return success_response(data=None, message="删除成功")
