export type SystemSettingValue = string | number | boolean;
type SystemSettingType = "number" | "switch" | "text" | "password" | "select";

interface SystemSettingOption {
  label: string;
  value: string;
}

export interface SystemSettingDefinition {
  key: string;
  label: string;
  type: SystemSettingType;
  defaultValue: SystemSettingValue;
  min?: number;
  max?: number;
  placeholder?: string;
  options?: SystemSettingOption[];
  description: string;
  valueHint?: (value: SystemSettingValue) => string;
}

export interface SystemSettingSection {
  title: string;
  description: string;
  settings: SystemSettingDefinition[];
}

export const systemSettingSections: SystemSettingSection[] = [
  {
    title: "用户与登录",
    description: "控制学员准入、默认资料、验证码和登录态有效时间。",
    settings: [
      {
        key: "daily_chat_limit",
        label: "默认每日聊天额度",
        type: "number",
        defaultValue: 100,
        min: 0,
        max: 100000,
        description: "新建或导入学员未单独填写额度时使用。",
      },
      {
        key: "access_token_expire_minutes",
        label: "登录 Token 有效期（分钟）",
        type: "number",
        defaultValue: 43200,
        min: 5,
        max: 43200,
        description: "用户端和管理端登录后的 Token 有效期。",
      },
      {
        key: "sms_code_expire_minutes",
        label: "验证码有效期（分钟）",
        type: "number",
        defaultValue: 5,
        min: 1,
        max: 60,
        description: "短信验证码生成后的可使用时间。",
      },
      {
        key: "mock_sms_enabled",
        label: "使用 mock 短信",
        type: "switch",
        defaultValue: true,
        description: "开发和演示环境可开启，生产环境应关闭并接入真实短信。",
      },
      {
        key: "mock_sms_code",
        label: "mock 短信验证码",
        type: "text",
        defaultValue: "123456",
        placeholder: "例如 123456",
        description: "mock 短信开启时使用的固定验证码。",
      },
      {
        key: "aliyun_sms_access_key_id",
        label: "阿里云 AccessKey ID",
        type: "password",
        defaultValue: "",
        placeholder: "请输入 RAM 用户 AccessKey ID",
        description: "关闭 mock 短信后用于调用阿里云短信服务。",
      },
      {
        key: "aliyun_sms_access_key_secret",
        label: "阿里云 AccessKey Secret",
        type: "password",
        defaultValue: "",
        placeholder: "请输入 RAM 用户 AccessKey Secret",
        description: "敏感配置，建议使用最小权限 RAM 用户。",
      },
      {
        key: "aliyun_sms_sign_name",
        label: "阿里云短信签名",
        type: "text",
        defaultValue: "",
        placeholder: "例如 某某课堂",
        description: "需与阿里云短信控制台审核通过的签名一致。",
      },
      {
        key: "aliyun_sms_template_code",
        label: "阿里云模板 Code",
        type: "text",
        defaultValue: "",
        placeholder: "例如 SMS_123456789",
        description: "验证码短信模板 Code。",
      },
      {
        key: "aliyun_sms_template_param_key",
        label: "验证码变量名",
        type: "text",
        defaultValue: "code",
        placeholder: "默认 code",
        description: "模板中验证码变量名，例如模板变量为 ${code} 时填写 code。",
      },
      {
        key: "aliyun_sms_endpoint",
        label: "阿里云短信 Endpoint",
        type: "text",
        defaultValue: "dysmsapi.aliyuncs.com",
        placeholder: "dysmsapi.aliyuncs.com",
        description: "一般保持默认值即可。",
      },
      {
        key: "default_user_name_prefix",
        label: "默认用户名前缀",
        type: "text",
        defaultValue: "用户",
        placeholder: "例如 用户",
        description: "系统需要生成默认名称时使用的前缀。",
      },
    ],
  },
  {
    title: "AI 问答",
    description: "控制 Agent 调用、上下文和用户端回答展示策略。",
    settings: [
      {
        key: "ai_timeout_seconds",
        label: "AI 请求超时（秒）",
        type: "number",
        defaultValue: 60,
        min: 5,
        max: 300,
        description: "真实模型请求超过该时间应判定为超时。",
      },
      {
        key: "mock_model_enabled",
        label: "使用 mock 大模型",
        type: "switch",
        defaultValue: true,
        description: "开发和演示环境可开启，真实模型验收前应关闭。",
      },
      {
        key: "chat_context_message_count",
        label: "上下文消息数",
        type: "number",
        defaultValue: 10,
        min: 0,
        max: 100,
        description: "当前会话带入模型的最近历史消息条数；更早内容会滚动摘要，设为 0 将关闭会话记忆。修改后下一次提问立即生效。",
      },
      {
        key: "show_reference_sources",
        label: "用户端展示引用来源",
        type: "switch",
        defaultValue: true,
        description: "后台始终记录引用；此项控制用户端是否展示。",
      },
      {
        key: "chat_model_routing_mode",
        label: "正式问答模型分流规则",
        type: "select",
        defaultValue: "fixed_only",
        options: [
          { label: "关闭分流（全部使用主模型）", value: "off" },
          { label: "仅固定信息（推荐）", value: "fixed_only" },
          { label: "保守分流（固定信息 + 简单知识）", value: "conservative" },
        ],
        description: "“简单知识”只覆盖短问题、明确知识问法且仅召回课程/问答/通用知识；涉及个人情况、情绪、关系、建议或混合固定信息时仍使用主模型。",
      },
      {
        key: "chat_max_active_requests",
        label: "问答最大并发数",
        type: "number",
        defaultValue: 30,
        min: 1,
        max: 1000,
        description: "用户正式问答的全局执行上限；Redis 可用时由所有后端实例共享，超过后进入排队。",
        valueHint: concurrentCapacityHint,
      },
      {
        key: "chat_max_queue_size",
        label: "问答最大排队数",
        type: "number",
        defaultValue: 90,
        min: 0,
        max: 10000,
        description: "超过最大并发后允许等待的请求数量。默认按并发数的 3 倍预留，避免课程结束后的集中提问被直接拒绝。",
      },
      {
        key: "chat_queue_timeout_seconds",
        label: "问答排队超时（秒）",
        type: "number",
        defaultValue: 90,
        min: 1,
        max: 3600,
        description: "请求在排队中超过该时间后自动结束。默认 90 秒可覆盖 30 并发下约三轮请求释放。",
      },
      {
        key: "chat_active_lease_seconds",
        label: "问答执行租约（秒）",
        type: "number",
        defaultValue: 900,
        min: 60,
        max: 86400,
        description: "Redis 全局队列中执行名额的自动过期时间，防止 worker 异常退出后长期占用并发名额。",
      },
      {
        key: "voice_input_enabled",
        label: "启用语音输入",
        type: "switch",
        defaultValue: false,
        description: "关闭后用户端不展示麦克风入口，后端也会拒绝语音转写请求。",
      },
      {
        key: "voice_max_duration_seconds",
        label: "单条语音最大时长（秒）",
        type: "number",
        defaultValue: 60,
        min: 5,
        max: 60,
        description: "达到设定时长后自动停止并转成文字，阿里云一句话识别上限为 60 秒。",
      },
      {
        key: "aliyun_nls_app_key",
        label: "阿里云语音 AppKey",
        type: "text",
        defaultValue: "",
        placeholder: "请输入智能语音交互项目 AppKey",
        description: "填写阿里云智能语音交互控制台中对应应用的 AppKey。",
      },
      {
        key: "aliyun_nls_access_key_id",
        label: "语音服务 AccessKey ID",
        type: "password",
        defaultValue: "",
        placeholder: "请单独填写语音服务 AccessKey ID",
        description: "语音服务独立配置；如与短信使用同一账号，也需要在这里手动填写。",
      },
      {
        key: "aliyun_nls_access_key_secret",
        label: "语音服务 AccessKey Secret",
        type: "password",
        defaultValue: "",
        placeholder: "请单独填写语音服务 AccessKey Secret",
        description: "加密保存且不会明文回显，不再从短信配置中读取。",
      },
      {
        key: "aliyun_nls_endpoint",
        label: "阿里云语音 Endpoint",
        type: "text",
        defaultValue: "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/asr",
        placeholder: "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/asr",
        description: "一句话识别服务地址，一般保持默认值即可。",
      },
    ],
  },
  {
    title: "外部服务",
    description: "控制飞书搜索接口、飞书直读超时和重试策略。",
    settings: [
      {
        key: "feishu_search_url",
        label: "飞书检索服务地址",
        type: "text",
        defaultValue: "",
        placeholder: "例如 https://example.com/search",
        description: "如使用独立飞书检索适配服务，在这里填写调用地址。",
      },
      {
        key: "feishu_app_id",
        label: "飞书应用 AppID",
        type: "text",
        defaultValue: "",
        placeholder: "填写飞书开放平台应用 AppID",
        description: "用于后端直读飞书知识库；系统设置优先于环境变量。",
      },
      {
        key: "feishu_app_secret",
        label: "飞书应用 AppSecret",
        type: "password",
        defaultValue: "",
        placeholder: "填写飞书开放平台应用 AppSecret",
        description: "用于后端获取飞书 tenant_access_token，保存后立即生效。",
      },
      {
        key: "feishu_timeout_seconds",
        label: "飞书请求超时（秒）",
        type: "number",
        defaultValue: 20,
        min: 1,
        max: 120,
        description: "飞书相关接口调用超过该时间应判定为超时。",
      },
      {
        key: "feishu_retry_count",
        label: "飞书检索重试次数",
        type: "number",
        defaultValue: 2,
        min: 0,
        max: 10,
        description: "飞书检索失败时的最大重试次数。",
      },
    ],
  },
  {
    title: "系统开关",
    description: "控制系统级展示和运行策略，不包含密钥类配置。",
    settings: [
      {
        key: "show_operation_log_detail",
        label: "展示操作日志详情",
        type: "switch",
        defaultValue: true,
        description: "开启后后台审计页可展示更完整的操作上下文。",
      },
      {
        key: "chat_export_enabled",
        label: "允许导出聊天记录",
        type: "switch",
        defaultValue: true,
        description: "关闭后后台不应提供聊天记录导出能力。",
      },
      {
        key: "maintenance_mode",
        label: "维护模式",
        type: "switch",
        defaultValue: false,
        description: "预留给后续停机维护提示和访问控制使用。",
      },
    ],
  },
];

function concurrentCapacityHint(value: SystemSettingValue) {
  const concurrency = Math.max(1, Number(value) || 1);
  const lower = roundDownToTen((concurrency * 120) / 25 / 1.4);
  const upper = roundDownToTen((concurrency * 120) / 25 / 1.2);
  const capacity = lower === upper ? `约 ${lower} 人` : `约 ${lower}–${upper} 人`;
  return `容量估算：按单次问答约 25 秒并预留 20%–40% 波动，当前 ${concurrency} 并发可承接 2 分钟内${capacity}集中提问。实际能力还受模型服务商额度和回答时长影响。`;
}

function roundDownToTen(value: number) {
  return Math.max(1, Math.floor(value / 10) * 10);
}

export const systemSettingDefinitions = systemSettingSections.flatMap((section) => section.settings);
