# =============================================================================
# 企微IT智能服务台 — 配置管理模块
# =============================================================================
# 说明：使用 pydantic-settings 从环境变量读取所有配置项
# 优先级：环境变量 > .env 文件 > 默认值
# 所有配置项集中管理，避免散落在代码各处
# =============================================================================

from typing import List

import redis.asyncio as aioredis
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    """应用配置类。

    使用 pydantic-settings 自动从环境变量读取配置值。
    支持 .env 文件自动加载（开发环境便利）。

    Attributes:
        wecom_corp_id: 企业微信企业ID
        wecom_agent_id: 企业微信应用AgentId
        wecom_secret: 企业微信应用Secret
        wecom_token: 企业微信回调Token
        wecom_encoding_aes_key: 企业微信回调EncodingAESKey（43位）
        database_url: PostgreSQL 数据库连接地址
        redis_url: Redis 连接地址
        backend_host: 后端监听地址
        backend_port: 后端监听端口
        cors_origins: CORS 允许的源地址（逗号分隔）
    """

    # ----------------------------------------------------------------------
    # 企微自建应用配置
    # ----------------------------------------------------------------------
    # 企业ID（在企微管理后台 > 我的企业 > 企业信息 中查看）
    wecom_corp_id: str = "ww1234567890abcdef"
    # 应用AgentId（在企微管理后台 > 应用管理 > 自建应用 中查看）
    wecom_agent_id: str = "1000002"
    # 应用Secret（在企微管理后台 > 应用管理 > 自建应用 中查看）
    wecom_secret: str = "your-agent-secret"
    # 回调Token（在企微管理后台 > 应用管理 > 接收消息 中设置）
    wecom_token: str = "your-callback-token"
    # 回调EncodingAESKey（43位字符串，用于消息加解密）
    wecom_encoding_aes_key: str = "your-aes-key-43-characters-long-encoding-key"

    # ----------------------------------------------------------------------
    # 数据库配置
    # ----------------------------------------------------------------------
    # PostgreSQL 连接地址
    # Docker 环境使用容器名 postgres，本地开发使用 localhost
    database_url: str = "postgresql://wecom:wecom_secret@localhost:5432/wecom_it_desk"

    # ----------------------------------------------------------------------
    # Redis 配置
    # ----------------------------------------------------------------------
    # Redis 连接地址
    # Docker 环境使用容器名 redis，本地开发使用 localhost
    redis_url: str = "redis://localhost:6379/0"

    # ----------------------------------------------------------------------
    # 服务配置
    # ----------------------------------------------------------------------
    # 后端监听地址（0.0.0.0 表示监听所有网卡）
    backend_host: str = "0.0.0.0"
    # 后端监听端口
    backend_port: int = 8000
    # CORS 允许的源地址（逗号分隔的字符串）
    cors_origins: str = "http://localhost:5173,http://localhost:5174,http://localhost:5175"

    # ----------------------------------------------------------------------
    # AI 服务配置（Dify）
    # ----------------------------------------------------------------------
    # Dify API 端点（兼容 OpenAI Chat Completions 格式）
    # 必须通过环境变量 DIFY_API_URL 配置，不设置默认值（防止凭据泄露）
    dify_api_url: str = ""
    # Dify API Key（格式：base_url|app_id|app_name）
    # 必须通过环境变量 DIFY_API_KEY 配置，不设置默认值（防止凭据泄露）
    dify_api_key: str = ""
    # Dify API 请求超时（秒），在网络慢时可调大
    dify_timeout: int = 30

    # ----------------------------------------------------------------------
    # AI Wingman 服务配置（Dify Agent 2 — 坐席端辅助）
    # ----------------------------------------------------------------------
    # 坐席端 Wingman 专用 Dify API 端点（与员工端 Agent 分开）
    # 留空则禁用 Wingman 功能（不影响主流程）
    dify_wingman_api_url: str = ""
    # 坐席端 Wingman Dify API Key（需要新建 Agent 后填入，留空则禁用）
    # 格式：base_url|app_id|app_name（与 dify_api_key 相同格式）
    dify_wingman_api_key: str = ""
    # Wingman API 请求超时（秒）
    dify_wingman_timeout: int = 30

    # ----------------------------------------------------------------------
    # Mock 登录配置（测试阶段使用，跳过企微 OAuth2）
    # ----------------------------------------------------------------------
    # 是否启用 Mock 登录（默认 false，生产环境必须关闭）
    mock_login_enabled: bool = False

    # ----------------------------------------------------------------------
    # 开发模式配置(本地 docker-compose.dev.yml 用)
    # ----------------------------------------------------------------------
    # 是否启用开发模式(本地开发环境,启用后挂载 /api/dev/* Mock OAuth 路由)
    # ⚠️ 生产环境必须为 false / 不设置
    # 启用的副作用:
    #   1. 后端启动时挂载 /api/dev/login /users /health 三个 Mock 端点
    #   2. /api/dev/login 跳过企微 OAuth 直接生成 token
    #   3. 启动日志会大声警告 "🧪 DEV_MODE enabled"
    dev_mode: bool = False
    # 开发模式默认 userid(本地前端兜底用,实际由前端 /api/dev/login 传入)
    dev_default_userid: str = "dev-user-001"
    # 开发模式默认姓名
    dev_default_name: str = "开发测试用户"
    # 开发模式默认部门
    dev_default_dept: str = "信息技术部"

    # ----------------------------------------------------------------------
    # 审批模板配置（企微审批应用）
    # ----------------------------------------------------------------------
    # 资源申请审批模板ID（在企微审批应用设置中获取）
    approval_template_resource: str = ""
    # 设备申请审批模板ID（在企微审批应用设置中获取）
    approval_template_device: str = ""

    # ----------------------------------------------------------------------
    # v0.7.1 企微 SSO 入口配置 (task #85)
    # ----------------------------------------------------------------------
    # 是否启用企微 SSO（true = 优先用企微 OAuth2 静默授权,失败时降级扫码）
    # 通过环境变量 WECOM_SSO_ENABLED 控制（默认 false,避免老用户被打扰）
    wecom_sso_enabled: bool = False
    # SSO OAuth 回调 base URL（企微要求 redirect_uri 必须用可信域名）
    # 生产: https://itsupport.servyou.com.cn  开发: http://localhost:5176
    wecom_sso_callback_base: str = ""

    # ----------------------------------------------------------------------
    # v0.5.4 应急页身份检测配置
    # ----------------------------------------------------------------------
    # IT支持-咨询坐席 通讯录标签 ID（在企微管理后台 > 通讯录管理 > 标签管理 中查看）
    # 配置后,应急页会通过此标签判断当前用户是否为坐席
    # 留空则降级到下面的硬编码名单
    wecom_agent_tag_id: str = ""
    # 硬编码坐席 userid 列表（逗号分隔），作为标签检测的降级方案
    # 例："zhangsan,lisi,wangwu"（生产环境建议用标签方案）
    wecom_agent_userids: str = ""

    # ----------------------------------------------------------------------
    # v0.6.0 内容审核报警配置（占位,后续完善）
    # ----------------------------------------------------------------------
    # 合规通知企微群机器人 webhook
    content_audit_webhook: str = ""
    # 主管接收报警的 userid（多个用逗号分隔）
    content_audit_supervisor_userids: str = ""

    # ----------------------------------------------------------------------
    # Pydantic-settings 配置
    # ----------------------------------------------------------------------
    model_config = SettingsConfigDict(
        # 自动从 .env 文件加载环境变量
        env_file=".env",
        # .env 文件编码
        env_file_encoding="utf-8",
        # 环境变量名大小写不敏感
        case_sensitive=False,
        # 额外字段不允许（防止拼写错误的配置被忽略）
        extra="ignore",
    )

    @property
    def cors_origins_list(self) -> List[str]:
        """将 CORS 源地址字符串解析为列表。

        将逗号分隔的字符串（如 "http://a,http://b"）
        转换为列表（如 ["http://a", "http://b"]），
        方便 FastAPI 的 CORSMiddleware 使用。

        Returns:
            List[str]: CORS 允许的源地址列表
        """
        # 去除每项的前后空格，过滤空字符串
        return [origin.strip() for origin in self.cors_origins.split(",") if origin.strip()]

    def create_redis_client(self) -> aioredis.Redis:
        """创建 Redis 异步客户端实例。

        自动附加 protocol=2 参数，强制使用 RESP2 协议。
        原因：Windows 版 Redis 3.x 不支持 RESP3 协议（HELLO 命令），
        而 redis-py 8.0+ 默认使用 RESP3，会导致连接失败。
        全项目统一使用此方法创建 Redis 客户端，避免协议不匹配。

        Returns:
            aioredis.Redis: 配置好的 Redis 异步客户端
        """
        return aioredis.from_url(self.redis_url, protocol=2)


# 创建全局配置实例
# 整个应用通过 from app.config import settings 使用同一个实例
settings = Settings()
