import {
  buildDefaultHermesEmployeeForm,
  isHermesEmployeeSettingsReady,
  mergeHermesEmployeeForm
} from './hermesEmployeeSettingsModel.js'

export const SETTINGS_STORAGE_KEY = 'x-financial-settings-draft'
export const CURRENT_YEAR = new Date().getFullYear()
export const CUSTOM_OPENAI_PROVIDER = 'Custom OpenAI Compatible'
export const MODEL_SECRET_MASK = '********'
export const RENDER_SECRET_MASK = '********'

export const SECTION_DEFINITIONS = [
  {
    id: 'profile',
    label: '企业信息',
    title: '系统基本信息',
    desc: '公司名称、品牌与版权',
    longDesc: '统一维护企业名称、系统显示名称和版权信息，保存后会同步更新当前系统品牌展示。',
    actionLabel: '保存企业信息'
  },
  {
    id: 'appearance',
    label: '界面皮肤',
    title: '界面皮肤与主色',
    desc: '整体主色与控件观感',
    longDesc: '设置当前浏览器的界面主色。默认使用浅蓝企业主题，后续可扩展为企业级统一下发。',
    actionLabel: '保存皮肤设置'
  },
  {
    id: 'admin',
    label: '管理员安全',
    title: '管理员账号与安全策略',
    desc: '账号、密码与登录安全',
    longDesc: '集中管理管理员账号、邮箱和登录安全策略。密码仅在当前输入时可见，不会写入浏览器草稿。',
    actionLabel: '保存安全设置'
  },
  {
    id: 'session',
    label: '会话设置',
    title: '会话留存设置',
    desc: '会话保留天数',
    longDesc: '统一配置智能体会话的保留天数。超过保留期的历史会话会在后端清理，避免上下文和管理成本无限增长。',
    actionLabel: '保存会话设置'
  },
  {
    id: 'hermes',
    label: '数字员工设置',
    title: '数字员工设置',
    desc: '自动任务',
    longDesc: '选择需要自动执行的任务，并设置每天的执行时间。无需了解 Cron 或复杂调度规则。',
    actionLabel: '保存数字员工设置'
  },
  {
    id: 'llm',
    label: '大语言模型',
    title: '模型接入配置',
    desc: '主模型、备份模型与检索模型',
    longDesc: '集中维护主模型、备份模型、Embedding 模型和 Reranker 模型的接入参数，供 AI 助手和检索链路调用。',
    actionLabel: '保存模型配置'
  },
  {
    id: 'rendering',
    label: '文件渲染',
    title: '文件渲染',
    desc: '文档预览服务与访问密钥',
    longDesc: '维护文件渲染开关、文档服务对外地址和 JWT 密钥，后端回调地址继续由部署配置管理。',
    actionLabel: '保存文件渲染配置'
  },
  {
    id: 'logs',
    label: '日志策略',
    title: '日志与审计策略',
    desc: '日志级别、留存与脱敏',
    longDesc: '定义系统日志级别、留存周期和审计策略，保证问题排查和合规审计可追溯。',
    actionLabel: '保存日志策略'
  },
  {
    id: 'mail',
    label: '邮箱设置',
    title: '邮箱通知配置',
    desc: 'SMTP 与通知投递策略',
    longDesc: '维护系统邮件发送配置和通知投递策略，审批、告警和摘要邮件都会依赖这里的设置。',
    actionLabel: '保存邮箱配置'
  }
]

export const LOG_LEVELS = ['DEBUG', 'INFO', 'WARN', 'ERROR']

export const PROVIDER_OPTIONS = [
  'MiniMax',
  'GLM',
  'Kimi',
  'Ali',
  'Codex',
  'Claude',
  'Gemini',
  CUSTOM_OPENAI_PROVIDER
]

export const PROVIDER_ENDPOINTS = {
  MiniMax: 'https://api.minimaxi.com/v1',
  GLM: 'https://open.bigmodel.cn/api/paas/v4/',
  Kimi: 'https://api.moonshot.ai/v1',
  Ali: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
  Codex: 'https://api.openai.com/v1',
  Claude: 'https://api.anthropic.com/v1/',
  Gemini: 'https://generativelanguage.googleapis.com/v1beta/openai/',
  [CUSTOM_OPENAI_PROVIDER]: ''
}

export const RERANKER_PROVIDER_ENDPOINTS = {
  Ali: 'https://dashscope.aliyuncs.com/api/v1/services/rerank/text-rerank/text-rerank',
  [CUSTOM_OPENAI_PROVIDER]: ''
}

export const LEGACY_PROVIDER_MAP = {
  'OpenAI Compatible': 'Codex',
  'Azure OpenAI': CUSTOM_OPENAI_PROVIDER,
  Ollama: CUSTOM_OPENAI_PROVIDER,
  '自定义网关': CUSTOM_OPENAI_PROVIDER
}

export const MODEL_TEST_CONFIGS = {
  main: {
    label: '主模型',
    providerKey: 'mainProvider',
    modelKey: 'mainModel',
    endpointKey: 'mainEndpoint',
    apiKeyKey: 'mainApiKey',
    capability: 'chat'
  },
  backup: {
    label: '备份模型',
    providerKey: 'backupProvider',
    modelKey: 'backupModel',
    endpointKey: 'backupEndpoint',
    apiKeyKey: 'backupApiKey',
    capability: 'chat'
  },
  embedding: {
    label: 'Embedding 模型',
    providerKey: 'embeddingProvider',
    modelKey: 'embeddingModel',
    endpointKey: 'embeddingEndpoint',
    apiKeyKey: 'embeddingApiKey',
    capability: 'embedding'
  },
  reranker: {
    label: 'Reranker 模型',
    providerKey: 'rerankerProvider',
    modelKey: 'rerankerModel',
    endpointKey: 'rerankerEndpoint',
    apiKeyKey: 'rerankerApiKey',
    capability: 'reranker'
  }
}

export const MODEL_API_KEY_CONFIGS = Object.values(MODEL_TEST_CONFIGS)
export const SESSION_RETENTION_OPTIONS = Array.from({ length: 10 }, (_item, index) => ({
  value: index + 1,
  label: `${index + 1} 天`
}))

export function normalizeValue(value) {
  return String(value ?? '').trim()
}

export function normalizeProviderValue(value, fallback = 'Codex') {
  const normalized = normalizeValue(value)

  if (PROVIDER_OPTIONS.includes(normalized)) {
    return normalized
  }

  if (LEGACY_PROVIDER_MAP[normalized]) {
    return LEGACY_PROVIDER_MAP[normalized]
  }

  return fallback
}

export function getProviderEndpoint(provider) {
  return PROVIDER_ENDPOINTS[provider] ?? ''
}

export function getRerankerEndpoint(provider) {
  return RERANKER_PROVIDER_ENDPOINTS[provider] ?? getProviderEndpoint(provider)
}

export function buildDefaultState(companyProfile, currentUser) {
  const companyName = normalizeValue(companyProfile?.name) || 'X-Financial'
  const companyCode = normalizeValue(companyProfile?.code) || 'XF-001'
  const adminEmail =
    normalizeValue(companyProfile?.adminEmail) ||
    normalizeValue(currentUser?.email) ||
    'admin@example.com'
  const adminAccount = normalizeValue(currentUser?.username) || 'superadmin'

  return {
    companyForm: {
      companyName,
      displayName: companyName,
      companyCode,
      logo: normalizeValue(companyProfile?.logo) || '',
      recordNumber: '',
      copyright: `Copyright © 2024-${CURRENT_YEAR} ${companyName}. All Rights Reserved.`
    },
    appearanceForm: {
      themeSkin: 'sky'
    },
    adminForm: {
      adminAccount,
      adminEmail,
      newPassword: '',
      confirmPassword: '',
      sessionTimeout: Number(import.meta.env.VITE_AUTH_IDLE_TIMEOUT_MINUTES || 30),
      noticeEmail: adminEmail,
      mfaEnabled: true,
      strongPassword: true,
      loginAlertEnabled: true,
      adminPasswordConfigured: false
    },
    sessionForm: {
      conversationRetentionDays: 3
    },
    llmForm: {
      mainProvider: 'Codex',
      mainModel: 'codex-mini-latest',
      mainEndpoint: getProviderEndpoint('Codex'),
      mainApiKey: '',
      mainApiKeyConfigured: false,
      backupProvider: 'GLM',
      backupModel: 'glm-5.1',
      backupEndpoint: getProviderEndpoint('GLM'),
      backupApiKey: '',
      backupApiKeyConfigured: false,
      embeddingProvider: 'GLM',
      embeddingModel: 'Embedding-3',
      embeddingEndpoint: getProviderEndpoint('GLM'),
      embeddingApiKey: '',
      embeddingApiKeyConfigured: false,
      rerankerProvider: 'Ali',
      rerankerModel: 'gte-rerank-v2',
      rerankerEndpoint: getRerankerEndpoint('Ali'),
      rerankerApiKey: '',
      rerankerApiKeyConfigured: false
    },
    renderForm: {
      enabled: false,
      publicUrl: '',
      jwtSecret: '',
      jwtSecretConfigured: false
    },
    logForm: {
      level: 'INFO',
      retentionDays: 180,
      archiveCycle: 'weekly',
      logPath: 'server/logs/app.log',
      alertEmail: adminEmail,
      operationAudit: true,
      loginAudit: true,
      maskSensitive: true
    },
    hermesForm: buildDefaultHermesEmployeeForm(),
    mailForm: {
      smtpHost: 'smtp.exmail.qq.com',
      port: 465,
      encryption: 'SSL/TLS',
      senderName: companyName,
      senderAddress: adminEmail,
      username: adminEmail,
      password: '',
      passwordConfigured: false,
      alertEnabled: true,
      digestEnabled: false,
      digestTime: '09:00',
      defaultReceiver: adminEmail
    }
  }
}

export function readStoredSettings() {
  if (typeof window === 'undefined') {
    return null
  }

  const raw = window.sessionStorage.getItem(SETTINGS_STORAGE_KEY)
  if (!raw) {
    return null
  }

  try {
    return JSON.parse(raw)
  } catch {
    return null
  }
}

export function mergeState(baseState, overrideState) {
  const mergedLlmForm = { ...baseState.llmForm, ...(overrideState?.llmForm || {}) }

  mergedLlmForm.mainProvider = normalizeProviderValue(mergedLlmForm.mainProvider, baseState.llmForm.mainProvider)
  mergedLlmForm.backupProvider = normalizeProviderValue(mergedLlmForm.backupProvider, baseState.llmForm.backupProvider)
  mergedLlmForm.embeddingProvider = normalizeProviderValue(
    mergedLlmForm.embeddingProvider,
    baseState.llmForm.embeddingProvider
  )
  mergedLlmForm.rerankerProvider = normalizeProviderValue(
    mergedLlmForm.rerankerProvider,
    baseState.llmForm.rerankerProvider
  )

  return {
    companyForm: { ...baseState.companyForm, ...(overrideState?.companyForm || {}) },
    appearanceForm: { ...baseState.appearanceForm, ...(overrideState?.appearanceForm || {}) },
    adminForm: { ...baseState.adminForm, ...(overrideState?.adminForm || {}) },
    sessionForm: { ...baseState.sessionForm, ...(overrideState?.sessionForm || {}) },
    hermesForm: mergeHermesEmployeeForm({
      ...baseState.hermesForm,
      ...(overrideState?.hermesForm || {})
    }),
    llmForm: mergedLlmForm,
    renderForm: { ...baseState.renderForm, ...(overrideState?.renderForm || {}) },
    logForm: { ...baseState.logForm, ...(overrideState?.logForm || {}) },
    mailForm: { ...baseState.mailForm, ...(overrideState?.mailForm || {}) }
  }
}

export function sanitizeForStorage(state) {
  return {
    companyForm: { ...state.companyForm },
    appearanceForm: { ...state.appearanceForm },
    adminForm: {
      ...state.adminForm,
      newPassword: '',
      confirmPassword: ''
    },
    sessionForm: { ...state.sessionForm },
    hermesForm: mergeHermesEmployeeForm(state.hermesForm),
    llmForm: {
      ...state.llmForm,
      mainApiKey: '',
      backupApiKey: '',
      embeddingApiKey: '',
      rerankerApiKey: ''
    },
    renderForm: {
      ...state.renderForm,
      jwtSecret: ''
    },
    logForm: { ...state.logForm },
    mailForm: {
      ...state.mailForm,
      password: ''
    }
  }
}

export function getModelConfiguredKey(apiKeyKey) {
  return `${apiKeyKey}Configured`
}

export function isModelSecretMask(value) {
  return value === MODEL_SECRET_MASK
}

export function maskConfiguredModelSecrets(state) {
  for (const config of MODEL_API_KEY_CONFIGS) {
    const configuredKey = getModelConfiguredKey(config.apiKeyKey)

    if (state.llmForm[configuredKey] && !normalizeValue(state.llmForm[config.apiKeyKey])) {
      state.llmForm[config.apiKeyKey] = MODEL_SECRET_MASK
    }
  }

  return state
}

export function buildLlmPayload(llmForm) {
  const payload = { ...llmForm }

  for (const config of MODEL_API_KEY_CONFIGS) {
    if (isModelSecretMask(payload[config.apiKeyKey])) {
      payload[config.apiKeyKey] = ''
    }
  }

  return payload
}

export function isRenderSecretMask(value) {
  return value === RENDER_SECRET_MASK
}

export function maskConfiguredRenderSecret(state) {
  if (state.renderForm.jwtSecretConfigured && !normalizeValue(state.renderForm.jwtSecret)) {
    state.renderForm.jwtSecret = RENDER_SECRET_MASK
  }

  return state
}

export function buildRenderPayload(renderForm) {
  const payload = { ...renderForm }

  if (isRenderSecretMask(payload.jwtSecret)) {
    payload.jwtSecret = ''
  }

  return payload
}

export function persistSettings(state) {
  if (typeof window === 'undefined') {
    return
  }

  window.sessionStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(sanitizeForStorage(state)))
}

export function isModelConfigReady(provider, model, endpoint) {
  return Boolean(normalizeValue(provider) && normalizeValue(model) && normalizeValue(endpoint))
}

export function computeSectionStatus(state) {
  return {
    profile: Boolean(
      normalizeValue(state.companyForm.companyName) &&
        normalizeValue(state.companyForm.displayName) &&
        normalizeValue(state.companyForm.copyright)
    ),
    appearance: true,
    admin: Boolean(
      normalizeValue(state.adminForm.adminAccount) &&
        normalizeValue(state.adminForm.adminEmail) &&
        Number(state.adminForm.sessionTimeout) >= 5
    ),
    session: Boolean(
      Number(state.sessionForm.conversationRetentionDays) >= 1 &&
        Number(state.sessionForm.conversationRetentionDays) <= 10
    ),
    hermes: isHermesEmployeeSettingsReady(state.hermesForm),
    llm: Boolean(
      isModelConfigReady(state.llmForm.mainProvider, state.llmForm.mainModel, state.llmForm.mainEndpoint) &&
        isModelConfigReady(state.llmForm.backupProvider, state.llmForm.backupModel, state.llmForm.backupEndpoint) &&
        isModelConfigReady(
          state.llmForm.embeddingProvider,
          state.llmForm.embeddingModel,
          state.llmForm.embeddingEndpoint
        ) &&
        isModelConfigReady(
          state.llmForm.rerankerProvider,
          state.llmForm.rerankerModel,
          state.llmForm.rerankerEndpoint
        )
    ),
    rendering: Boolean(
      !state.renderForm.enabled ||
        (normalizeValue(state.renderForm.publicUrl) &&
          (normalizeValue(state.renderForm.jwtSecret) || state.renderForm.jwtSecretConfigured))
    ),
    logs: Boolean(
      normalizeValue(state.logForm.level) &&
        Number(state.logForm.retentionDays) > 0 &&
        normalizeValue(state.logForm.logPath)
    ),
    mail: Boolean(
      normalizeValue(state.mailForm.smtpHost) &&
        Number(state.mailForm.port) > 0 &&
        normalizeValue(state.mailForm.senderAddress) &&
        normalizeValue(state.mailForm.username)
    )
  }
}
