# =============================================================================
# 企微IT智能服务台 — 扫码登录 Pydantic Schema
# =============================================================================
# 说明：定义扫码登录的请求/响应数据结构
# 涵盖 4 个端点的入参/出参:
#   1. POST /api/auth_qrcode/create  — 创建扫码登录票据
#   2. GET  /api/auth_qrcode/poll/{ticket} — 前端轮询扫码状态
#   3. POST /api/auth_qrcode/scan    — 企微用户扫码后 OAuth code 回调
#   4. POST /api/auth_qrcode/confirm — 当前已登录用户确认授权
# =============================================================================

from datetime import datetime
from typing import List, Optional

from pydantic import BaseModel, Field


# --------------------------------------------------------------------------
# POST /api/auth_qrcode/create — 创建扫码登录票据
# --------------------------------------------------------------------------
class QrcodeCreateResponse(BaseModel):
    """扫码登录票据创建响应。

    Attributes:
        ticket: 票据 UUID,前端用此票据轮询状态
        qrcode_url: 企微 OAuth2 授权 URL(前端渲染二维码)
        expires_in: 票据有效期(秒),默认 120
        expires_at: 票据过期时间(ISO 8601 字符串)
    """

    ticket: str = Field(..., description="票据 UUID")
    qrcode_url: str = Field(..., description="企微 OAuth2 授权 URL")
    expires_in: int = Field(120, description="有效期(秒)")
    expires_at: datetime = Field(..., description="过期时间(ISO 8601)")


# --------------------------------------------------------------------------
# GET /api/auth_qrcode/poll/{ticket} — 轮询扫码状态
# --------------------------------------------------------------------------
class QrcodePollResponse(BaseModel):
    """扫码登录票据轮询响应。

    status 取值:
      - waiting:   票据有效,等待扫码
      - scanned:   已扫码,等待确认
      - confirmed: 已确认登录成功,附带 token
      - expired:   票据过期/不存在

    Attributes:
        status: 扫码状态
        employee_id: 企微用户 ID(scanned/confirmed 时返回)
        name: 企微用户姓名(scanned/confirmed 时返回)
        token: 登录 Token(confirmed 时返回,前端存 localStorage)
    """

    status: str = Field(..., description="等待/已扫码/已确认/已过期")
    employee_id: Optional[str] = Field(None, description="企微用户 ID")
    name: Optional[str] = Field(None, description="企微用户姓名")
    token: Optional[str] = Field(None, description="登录 Token")


# --------------------------------------------------------------------------
# POST /api/auth_qrcode/scan — 企微 OAuth code 回调
# --------------------------------------------------------------------------
class QrcodeScanRequest(BaseModel):
    """扫码登录扫码请求体。

    Attributes:
        ticket: 扫码登录票据(UUID)
        code: 企微 OAuth2 授权回调 code
    """

    ticket: str = Field(..., min_length=1, description="扫码登录票据")
    code: str = Field(..., min_length=1, description="企微 OAuth2 授权 code")


class QrcodeScanResponse(BaseModel):
    """扫码登录扫码响应。

    Attributes:
        success: 是否成功
        message: 提示消息
    """

    success: bool = Field(..., description="是否成功")
    message: str = Field(..., description="提示消息")


# --------------------------------------------------------------------------
# POST /api/auth_qrcode/confirm — 当前已登录用户确认授权
# --------------------------------------------------------------------------
class QrcodeConfirmRequest(BaseModel):
    """扫码登录确认请求体。

    Attributes:
        ticket: 扫码登录票据(UUID)
        otp_code: OTP 动态码(管理员场景下可选,普通坐席可空)
    """

    ticket: str = Field(..., min_length=1, description="扫码登录票据")
    otp_code: Optional[str] = Field(
        None,
        min_length=6,
        max_length=6,
        description="OTP 动态码(管理员可选,普通坐席留空)",
    )


class QrcodeConfirmResponse(BaseModel):
    """扫码登录确认响应。

    Attributes:
        token: 登录 Token(scanned 用户换发的新 token)
        employee_id: 企微用户 ID
        name: 用户姓名
        roles: 用户角色列表
        require_otp: 是否需要 OTP 二次验证(预留,本任务不强制)
    """

    token: str = Field(..., description="登录 Token")
    employee_id: str = Field(..., description="企微用户 ID")
    name: str = Field(..., description="用户姓名")
    roles: List[str] = Field(default_factory=list, description="用户角色列表")
    require_otp: Optional[bool] = Field(
        None,
        description="是否需要 OTP 二次验证(预留字段,Phase 2.1 实现)",
    )