import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import { useSystemState } from './useSystemState.js'
import { normalizeThemeMode, useThemeSkin } from './useThemeSkin.js'
import { clearSystemCaches, fetchSettings, saveSettings } from '../services/settings.js'
import { useToast } from './useToast.js'
import {
  isHermesEmployeeSettingsReady
} from '../utils/hermesEmployeeSettingsModel.js'
import {
  LOG_LEVELS,
  PROVIDER_OPTIONS,
  SECTION_DEFINITIONS,
  SESSION_RETENTION_OPTIONS,
  buildDefaultState,
  buildLlmPayload,
  buildRenderPayload,
  computeSectionStatus,
  isModelConfigReady,
  isRenderSecretMask,
  maskConfiguredModelSecrets,
  maskConfiguredRenderSecret,
  mergeState,
  normalizeLlmModelRows,
  normalizeValue,
  persistSettings,
  readStoredSettings
} from '../utils/settingsModelHelper.js'

const sectionIds = new Set(SECTION_DEFINITIONS.map((section) => section.id))

function resolveSectionId(value) {
  const sectionId = String(value || '').trim()
  return sectionIds.has(sectionId) ? sectionId : 'profile'
}

function resolveInitialSectionId(route) {
  return route.name === 'app-log-detail' ? 'systemLogs' : resolveSectionId(route.query.section)
}

export function useSettings() {
  const route = useRoute()
  const router = useRouter()
  const { toast } = useToast()
  const { companyProfile, currentUser, updateCompanyProfilePreview } = useSystemState()
  const {
    activeThemeSkin,
    activeThemeSkinId,
    setThemeSkin,
    themeSkinOptions
  } = useThemeSkin()

  const buildResolvedDefaults = () => buildDefaultState(companyProfile.value, currentUser.value)
  const pageState = ref(mergeState(buildResolvedDefaults(), readStoredSettings()))
  const activeSection = ref(resolveInitialSectionId(route))
  const sessionRetentionPickerOpen = ref(false)
  const sessionRetentionPickerRef = ref(null)
  const logoInputRef = ref(null)
  const cacheClearing = ref(false)
  const cacheClearItems = ref([])
  const cacheClearMessage = ref('')
  const cacheClearFailed = ref(false)

  pageState.value.appearanceForm.themeSkin = setThemeSkin(pageState.value.appearanceForm.themeSkin)

  const sections = SECTION_DEFINITIONS
  const logLevels = LOG_LEVELS
  const providerOptions = PROVIDER_OPTIONS
  const sessionRetentionOptions = SESSION_RETENTION_OPTIONS
  const archiveCycleOptions = [
    { label: '按天归档', value: 'daily' },
    { label: '按周归档', value: 'weekly' },
    { label: '按月归档', value: 'monthly' }
  ]

  const sectionStatus = computed(() => computeSectionStatus(pageState.value))
  const completedSectionCount = computed(() => Object.values(sectionStatus.value).filter(Boolean).length)
  const systemLogDetailMode = computed(() => route.name === 'app-log-detail')
  const activeSectionConfig = computed(
    () => sections.find((section) => section.id === activeSection.value) || sections[0]
  )

  function updateBrandPreviewFromState(state) {
    updateCompanyProfilePreview({
      name: normalizeValue(state.companyForm.displayName),
      code: normalizeValue(state.companyForm.companyCode),
      adminEmail: normalizeValue(state.adminForm.adminEmail),
      logo: state.companyForm.logo
    })
  }

  function applyLoadedSnapshot(snapshot, options = {}) {
    const {
      mergeDraft = false,
      preserveModelApiKeys = false,
      preserveAdminPasswords = false,
      preserveRenderSecret = false,
      preserveMailPassword = false
    } = options

    const currentState = pageState.value
    let nextState = mergeState(buildResolvedDefaults(), snapshot)

    if (mergeDraft) {
      nextState = mergeState(nextState, readStoredSettings())
    }

    if (preserveModelApiKeys) {
      nextState.llmForm.mainApiKey = currentState.llmForm.mainApiKey
      nextState.llmForm.backupApiKey = currentState.llmForm.backupApiKey
      nextState.llmForm.embeddingApiKey = currentState.llmForm.embeddingApiKey
      nextState.llmForm.rerankerApiKey = currentState.llmForm.rerankerApiKey
      const modelApiKeysBySlot = new Map(
        normalizeLlmModelRows(currentState.llmForm.models).map((row) => [row.slot, row.apiKey])
      )
      nextState.llmForm.models = normalizeLlmModelRows(nextState.llmForm.models).map((row) => ({
        ...row,
        apiKey: modelApiKeysBySlot.get(row.slot) ?? row.apiKey
      }))
    }

    if (preserveAdminPasswords) {
      nextState.adminForm.newPassword = currentState.adminForm.newPassword
      nextState.adminForm.confirmPassword = currentState.adminForm.confirmPassword
    }

    if (preserveRenderSecret) {
      nextState.renderForm.jwtSecret = currentState.renderForm.jwtSecret
    }

    if (preserveMailPassword) {
      nextState.mailForm.password = currentState.mailForm.password
    }

    const normalizedThemeMode = normalizeThemeMode(nextState.appearanceForm?.themeSkin)
    nextState.appearanceForm = {
      ...nextState.appearanceForm,
      themeSkin: normalizedThemeMode
    }

    pageState.value = maskConfiguredRenderSecret(maskConfiguredModelSecrets(nextState))
    persistSettings(pageState.value)
    updateBrandPreviewFromState(pageState.value)
    setThemeSkin(normalizedThemeMode)
  }

  async function loadSettingsSnapshot() {
    try {
      const snapshot = await fetchSettings()
      applyLoadedSnapshot(snapshot, { mergeDraft: true })
    } catch (error) {
      persistSettings(pageState.value)
      updateBrandPreviewFromState(pageState.value)
      toast(error.message || '无法加载已保存设置，继续使用当前会话草稿。')
    }
  }

  function buildSettingsPayload() {
    return {
      companyForm: { ...pageState.value.companyForm },
      appearanceForm: { ...pageState.value.appearanceForm },
      adminForm: { ...pageState.value.adminForm },
      sessionForm: { ...pageState.value.sessionForm },
      llmForm: buildLlmPayload(pageState.value.llmForm),
      hermesForm: { ...pageState.value.hermesForm },
      renderForm: buildRenderPayload(pageState.value.renderForm),
      logForm: { ...pageState.value.logForm },
      mailForm: { ...pageState.value.mailForm }
    }
  }

  async function persistRemoteSettings(successMessage, options = {}) {
    try {
      const snapshot = await saveSettings(buildSettingsPayload())
      applyLoadedSnapshot(snapshot, options)
      toast(successMessage)
      return true
    } catch (error) {
      toast(error.message || '设置保存失败，请稍后重试。')
      return false
    }
  }

  function syncActiveSectionRoute(sectionId) {
    if (route.name !== 'app-settings') {
      return
    }

    const nextQuery = { ...route.query }
    if (sectionId === 'profile') {
      delete nextQuery.section
    } else {
      nextQuery.section = sectionId
    }

    if (String(route.query.section || '') === String(nextQuery.section || '')) {
      return
    }

    void router.replace({
      name: 'app-settings',
      query: nextQuery,
      hash: route.hash
    })
  }

  function activateSection(sectionId, options = {}) {
    const nextSectionId = resolveSectionId(sectionId)
    sessionRetentionPickerOpen.value = false
    activeSection.value = nextSectionId

    if (!options.skipRouteSync) {
      syncActiveSectionRoute(nextSectionId)
    }
  }

  function toggleBoolean(formKey, field) {
    pageState.value[formKey][field] = !pageState.value[formKey][field]
  }

  function toggleSessionRetentionPicker() {
    sessionRetentionPickerOpen.value = !sessionRetentionPickerOpen.value
  }

  function closeSessionRetentionPicker() {
    sessionRetentionPickerOpen.value = false
  }

  function selectSessionRetentionDays(value) {
    pageState.value.sessionForm.conversationRetentionDays = Number(value)
    closeSessionRetentionPicker()
  }

  function handleDocumentPointerDown(event) {
    if (!sessionRetentionPickerOpen.value) {
      return
    }

    const target = event.target
    if (sessionRetentionPickerRef.value?.contains(target)) {
      return
    }

    closeSessionRetentionPicker()
  }

  function clearRenderSecretMask() {
    if (isRenderSecretMask(pageState.value.renderForm.jwtSecret)) {
      pageState.value.renderForm.jwtSecret = ''
    }
  }

  async function saveProfileSection() {
    const companyForm = pageState.value.companyForm

    if (!normalizeValue(companyForm.companyName)) {
      toast('请输入企业名称。')
      return
    }

    if (!normalizeValue(companyForm.displayName)) {
      toast('请输入系统显示名称。')
      return
    }

    if (!normalizeValue(companyForm.copyright)) {
      toast('请输入版权信息。')
      return
    }

    pageState.value.mailForm.senderName = normalizeValue(companyForm.displayName)
    await persistRemoteSettings('企业信息已保存并应用到当前系统。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: true,
      preserveMailPassword: true
    })
  }

  async function saveAdminSection() {
    const adminForm = pageState.value.adminForm

    if (!normalizeValue(adminForm.adminAccount)) {
      toast('请输入管理员账号。')
      return
    }

    if (!normalizeValue(adminForm.adminEmail)) {
      toast('请输入管理员邮箱。')
      return
    }

    if (Number(adminForm.sessionTimeout) < 5) {
      toast('会话超时时间不能少于 5 分钟。')
      return
    }

    if (adminForm.newPassword) {
      if (adminForm.newPassword.length < 5) {
        toast('管理员密码至少需要 5 位。')
        return
      }

      if (adminForm.newPassword !== adminForm.confirmPassword) {
        toast('两次输入的管理员密码不一致。')
        return
      }
    }

    await persistRemoteSettings('管理员安全设置已保存。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: false,
      preserveRenderSecret: true,
      preserveMailPassword: true
    })
  }

  function toggleHermesMaster() {
    pageState.value.hermesForm.masterEnabled = !pageState.value.hermesForm.masterEnabled
  }

  function toggleHermesFlag(field) {
    pageState.value.hermesForm[field] = !pageState.value.hermesForm[field]
  }

  function toggleHermesTask(taskId) {
    const schedule = pageState.value.hermesForm.schedules[taskId]
    if (!schedule) {
      return
    }

    const enabled = !(pageState.value.hermesForm.capabilities[taskId] && schedule.enabled)
    pageState.value.hermesForm.capabilities[taskId] = enabled
    schedule.enabled = enabled
  }

  function updateHermesTaskTime({ taskId, time }) {
    const schedule = pageState.value.hermesForm.schedules[taskId]
    if (!schedule) {
      return
    }
    schedule.time = time
  }

  function saveHermesSection() {
    if (!isHermesEmployeeSettingsReady(pageState.value.hermesForm)) {
      toast('请至少开启一项 Hermes 能力，或关闭总控开关。')
      return
    }

    persistSettings(pageState.value)
    toast('数字员工设置已保存。')
  }

  async function saveSessionSection() {
    const sessionForm = pageState.value.sessionForm
    const retentionDays = Number(sessionForm.conversationRetentionDays)

    if (retentionDays < 1 || retentionDays > 10) {
      toast('会话保留天数必须在 1 到 10 天之间。')
      return
    }

    await persistRemoteSettings('会话设置已保存。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: true,
      preserveMailPassword: true
    })
  }

  function selectThemeSkin(skinId) {
    pageState.value.appearanceForm.themeSkin = setThemeSkin(skinId)
  }

  async function saveAppearanceSection() {
    pageState.value.appearanceForm.themeSkin = normalizeThemeMode(pageState.value.appearanceForm.themeSkin)
    await persistRemoteSettings('主题设置已保存并应用到企业配置。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: true,
      preserveMailPassword: true
    })
  }

  async function saveLlmSection() {
    const llmForm = pageState.value.llmForm
    const modelRows = normalizeLlmModelRows(llmForm.models)

    if (modelRows.length === 0) {
      toast('请至少添加一个模型配置。')
      return
    }

    for (const row of modelRows) {
      if (!isModelConfigReady(row.provider, row.modelId, row.url)) {
        toast('请完整填写每个模型的供应商、model_id 和接口地址。')
        return
      }
    }

    await persistRemoteSettings('模型配置已保存。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: true,
      preserveMailPassword: true
    })
  }

  async function saveRenderingSection() {
    const renderForm = pageState.value.renderForm

    if (renderForm.enabled && !normalizeValue(renderForm.publicUrl)) {
      toast('启用 ONLYOFFICE 时请输入服务地址。')
      return
    }

    if (renderForm.enabled && !normalizeValue(renderForm.jwtSecret) && !renderForm.jwtSecretConfigured) {
      toast('启用 ONLYOFFICE 时请输入 JWT 密钥。')
      return
    }

    await persistRemoteSettings('文件渲染配置已保存。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: false,
      preserveMailPassword: true
    })
  }

  async function saveLogsSection() {
    const logForm = pageState.value.logForm

    if (!normalizeValue(logForm.level) || Number(logForm.retentionDays) <= 0) {
      toast('请填写有效的日志级别和留存天数。')
      return
    }

    if (!normalizeValue(logForm.logPath)) {
      toast('请输入日志路径。')
      return
    }

    await persistRemoteSettings('日志策略已保存。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: true,
      preserveMailPassword: true
    })
  }

  function normalizeCacheClearErrorMessage(error) {
    const message = String(error?.message || '').trim()

    if (!message || /^not found$/i.test(message)) {
      return '缓存清理接口暂不可用，请确认后端服务已加载最新路由后重试。'
    }

    return message
  }

  async function clearAllCaches() {
    if (cacheClearing.value) {
      return
    }

    cacheClearing.value = true
    cacheClearMessage.value = ''
    cacheClearItems.value = []
    cacheClearFailed.value = false

    try {
      const payload = await clearSystemCaches()
      const items = Array.isArray(payload?.items) ? payload.items : []
      const totalCleared = Number(payload?.totalCleared || 0)
      cacheClearItems.value = items
      cacheClearMessage.value = totalCleared > 0
        ? `已清理 ${totalCleared} 条缓存。`
        : '当前没有可清理的缓存。'
      cacheClearFailed.value = false
      toast(cacheClearMessage.value)
    } catch (error) {
      const message = normalizeCacheClearErrorMessage(error)
      cacheClearFailed.value = true
      cacheClearMessage.value = message
      toast(message)
    } finally {
      cacheClearing.value = false
    }
  }

  async function saveMailSection() {
    const mailForm = pageState.value.mailForm

    if (!normalizeValue(mailForm.smtpHost) || Number(mailForm.port) <= 0) {
      toast('请填写有效的 SMTP Host 和端口。')
      return
    }

    if (!normalizeValue(mailForm.senderAddress) || !normalizeValue(mailForm.username)) {
      toast('请填写发件人邮箱和 SMTP 登录账号。')
      return
    }

    await persistRemoteSettings('邮箱配置已保存。', {
      preserveModelApiKeys: true,
      preserveAdminPasswords: true,
      preserveRenderSecret: true,
      preserveMailPassword: false
    })
  }

  async function saveActiveSection() {
    if (activeSection.value === 'profile') {
      await saveProfileSection()
      return
    }

    if (activeSection.value === 'admin') {
      await saveAdminSection()
      return
    }

    if (activeSection.value === 'appearance') {
      saveAppearanceSection()
      return
    }

    if (activeSection.value === 'session') {
      await saveSessionSection()
      return
    }

    if (activeSection.value === 'hermes') {
      saveHermesSection()
      return
    }

    if (activeSection.value === 'llm') {
      await saveLlmSection()
      return
    }

    if (activeSection.value === 'logs') {
      await saveLogsSection()
      return
    }

    if (activeSection.value === 'systemLogs') {
      return
    }

    if (activeSection.value === 'cacheManagement') {
      return
    }

    if (activeSection.value === 'rendering') {
      await saveRenderingSection()
      return
    }

    await saveMailSection()
  }

  onMounted(() => {
    if (typeof document !== 'undefined') {
      document.addEventListener('pointerdown', handleDocumentPointerDown)
    }
    loadSettingsSnapshot()
  })

  watch(
    () => [route.name, route.query.section],
    () => {
      const nextSectionId = resolveInitialSectionId(route)
      if (activeSection.value !== nextSectionId) {
        activateSection(nextSectionId, { skipRouteSync: true })
      }
    }
  )

  onBeforeUnmount(() => {
    if (typeof document !== 'undefined') {
      document.removeEventListener('pointerdown', handleDocumentPointerDown)
    }
  })

  function triggerLogoUpload() {
    logoInputRef.value?.click()
  }

  function handleLogoUpload(event) {
    const file = event.target.files?.[0]
    if (!file) return

    if (!file.type.startsWith('image/')) {
      toast('请上传图片文件。')
      return
    }

    if (file.size > 2 * 1024 * 1024) {
      toast('图片大小不能超过 2MB。')
      return
    }

    const reader = new FileReader()
    reader.onload = (e) => {
      pageState.value.companyForm.logo = e.target.result
    }
    reader.readAsDataURL(file)
  }

  return {
    activeSection,
    activeSectionConfig,
    activeThemeSkin,
    activeThemeSkinId,
    archiveCycleOptions,
    activateSection,
    cacheClearFailed,
    cacheClearItems,
    cacheClearMessage,
    cacheClearing,
    clearAllCaches,
    clearRenderSecretMask,
    completedSectionCount,
    logLevels,
    logoInputRef,
    pageState,
    providerOptions,
    sessionRetentionOptions,
    sessionRetentionPickerOpen,
    sessionRetentionPickerRef,
    saveActiveSection,
    sectionStatus,
    sections,
    systemLogDetailMode,
    selectThemeSkin,
    selectSessionRetentionDays,
    themeSkinOptions,
    toggleSessionRetentionPicker,
    closeSessionRetentionPicker,
    toggleBoolean,
    toggleHermesFlag,
    toggleHermesMaster,
    toggleHermesTask,
    updateHermesTaskTime,
    triggerLogoUpload,
    handleLogoUpload
  }
}
