import { computed, ref } from 'vue'

import { showError, showSuccess } from '@/lib/feedback'
import {
  runAdminScheduledJob,
  saveAdminNotificationConfig,
  saveAdminScheduledJobsConfig,
  testAdminNotification,
} from '@/services/admin'
import type {
  AdminNotificationConfig,
  AdminNotificationTestResult,
  AdminScheduledJobRuntimeState,
  AdminScheduledJobsConfig,
  AdminScheduledJobsResponse,
} from '@/types/admin'

import type { EditableNotificationRecipient, EditableScheduledJob } from './types'

export function useAdminNotificationPlatform() {
  const notificationFilePath = ref('')
  const notificationForm = ref({
    enabled: true,
    barkEnabled: true,
    barkServerUrl: 'https://api.day.app',
    testTitle: '订单系统测试通知',
    testBody: '这是一条 Bark 内部通知测试。',
    testUrl: '',
  })
  const notificationRecipients = ref<EditableNotificationRecipient[]>([])
  const notificationSaving = ref(false)
  const notificationTesting = ref(false)
  const notificationResultError = ref('')
  const notificationTestResult = ref<AdminNotificationTestResult | null>(null)
  const scheduledJobsFilePath = ref('')
  const scheduledJobsForm = ref({
    enabled: true,
  })
  const scheduledJobs = ref<EditableScheduledJob[]>([])
  const scheduledJobRuntime = ref<AdminScheduledJobRuntimeState[]>([])
  const scheduledJobsSaving = ref(false)
  const scheduledJobRunningId = ref('')

  const notificationStats = computed(() => {
    const enabledRecipients = notificationRecipients.value.filter(
      (item) => item.enabled && item.deviceKey.trim(),
    )

    return {
      configuredRecipientCount: notificationRecipients.value.length,
      enabledRecipientCount: enabledRecipients.length,
      barkReady:
        notificationForm.value.enabled &&
        notificationForm.value.barkEnabled &&
        enabledRecipients.length > 0,
      lastSuccessCount: notificationTestResult.value?.successCount || 0,
      lastFailedCount: notificationTestResult.value?.failedCount || 0,
      scheduledJobEnabledCount: scheduledJobs.value.filter((item) => item.enabled).length,
    }
  })

  function hydrateNotificationConfig(data: { filePath: string; source: AdminNotificationConfig }) {
    notificationFilePath.value = data.filePath
    notificationForm.value.enabled = data.source.enabled !== false
    notificationForm.value.barkEnabled = data.source.channels.bark.enabled !== false
    notificationForm.value.barkServerUrl =
      data.source.channels.bark.serverUrl || 'https://api.day.app'
    notificationRecipients.value = data.source.channels.bark.recipients.map((item) => ({
      id: item.id || crypto.randomUUID(),
      name: item.name,
      deviceKey: item.deviceKey,
      enabled: item.enabled !== false,
    }))
  }

  function hydrateScheduledJobsConfig(data: AdminScheduledJobsResponse) {
    scheduledJobsFilePath.value = data.filePath
    scheduledJobsForm.value.enabled = data.source.enabled !== false
    scheduledJobs.value = data.source.jobs.map((item) => ({
      id: item.id,
      type: item.type,
      enabled: item.enabled === true,
      intervalSeconds: Number(item.intervalSeconds || 300),
      intervalSecondsAmount: resolveTimeValue(Number(item.intervalSeconds || 300)).amount,
      intervalSecondsUnit: resolveTimeValue(Number(item.intervalSeconds || 300)).unit,
      cooldownSeconds: Number(item.cooldownSeconds || 1800),
      cooldownSecondsAmount: resolveTimeValue(Number(item.cooldownSeconds || 1800)).amount,
      cooldownSecondsUnit: resolveTimeValue(Number(item.cooldownSeconds || 1800)).unit,
      assetThreshold: Number(item.config?.assetThreshold || 500),
    }))
    scheduledJobRuntime.value = data.runtime || []
  }

  function addNotificationRecipient() {
    notificationRecipients.value.unshift({
      id: crypto.randomUUID(),
      name: '',
      deviceKey: '',
      enabled: true,
    })
  }

  function removeNotificationRecipient(id: string) {
    notificationRecipients.value = notificationRecipients.value.filter((item) => item.id !== id)
  }

  function buildNotificationConfigPayload(): AdminNotificationConfig {
    return {
      enabled: notificationForm.value.enabled,
      channels: {
        bark: {
          enabled: notificationForm.value.barkEnabled,
          serverUrl: notificationForm.value.barkServerUrl.trim() || 'https://api.day.app',
          recipients: notificationRecipients.value.map((item) => ({
            id: item.id,
            name: item.name.trim(),
            deviceKey: item.deviceKey.trim(),
            deviceKeyMasked: '',
            enabled: item.enabled,
          })),
        },
      },
    }
  }

  function buildScheduledJobsConfigPayload(): AdminScheduledJobsConfig {
    return {
      enabled: scheduledJobsForm.value.enabled,
      jobs: scheduledJobs.value.map((item) => ({
        id: item.id,
        type: item.type,
        enabled: item.enabled,
        intervalSeconds: Number(item.intervalSeconds || 300),
        cooldownSeconds: Number(item.cooldownSeconds || 1800),
        config: {
          assetThreshold: Number(item.assetThreshold || 500),
        },
      })),
    }
  }

  async function handleNotificationSaveConfig() {
    notificationSaving.value = true
    notificationResultError.value = ''

    try {
      const response = await saveAdminNotificationConfig(buildNotificationConfigPayload())
      notificationFilePath.value = response.data.filePath
      hydrateNotificationConfig(response.data)
      showSuccess('内部通知配置已保存')
    } catch (error) {
      notificationResultError.value =
        error instanceof Error ? error.message : '内部通知配置保存失败'
      showError(notificationResultError.value)
    } finally {
      notificationSaving.value = false
    }
  }

  async function handleNotificationTest() {
    notificationTesting.value = true
    notificationResultError.value = ''
    notificationTestResult.value = null

    try {
      const saved = await saveAdminNotificationConfig(buildNotificationConfigPayload())
      notificationFilePath.value = saved.data.filePath
      hydrateNotificationConfig(saved.data)

      const response = await testAdminNotification({
        title: notificationForm.value.testTitle.trim(),
        body: notificationForm.value.testBody.trim(),
        url: notificationForm.value.testUrl.trim(),
      })
      notificationTestResult.value = response.data
      if (response.data.successCount > 0) {
        showSuccess(`内部通知测试完成，成功 ${response.data.successCount} 个`)
      } else {
        showError('内部通知测试未成功发送，请检查 Bark 配置')
      }
    } catch (error) {
      notificationResultError.value = error instanceof Error ? error.message : '内部通知测试失败'
      showError(notificationResultError.value)
    } finally {
      notificationTesting.value = false
    }
  }

  async function handleScheduledJobsSaveConfig() {
    scheduledJobsSaving.value = true
    notificationResultError.value = ''

    try {
      const response = await saveAdminScheduledJobsConfig(buildScheduledJobsConfigPayload())
      hydrateScheduledJobsConfig(response.data)
      showSuccess('监控任务配置已保存')
    } catch (error) {
      notificationResultError.value =
        error instanceof Error ? error.message : '监控任务配置保存失败'
      showError(notificationResultError.value)
    } finally {
      scheduledJobsSaving.value = false
    }
  }

  async function handleScheduledJobRunNow(jobId: string) {
    scheduledJobRunningId.value = jobId
    notificationResultError.value = ''

    try {
      const saved = await saveAdminScheduledJobsConfig(buildScheduledJobsConfigPayload())
      hydrateScheduledJobsConfig(saved.data)
      const response = await runAdminScheduledJob(jobId)
      scheduledJobRuntime.value = response.data.runtime || []
      const message = String(response.data.result?.message || '监控任务已执行')
      showSuccess(message)
    } catch (error) {
      notificationResultError.value = error instanceof Error ? error.message : '监控任务执行失败'
      showError(notificationResultError.value)
    } finally {
      scheduledJobRunningId.value = ''
    }
  }

  function getScheduledJobRuntime(jobId: string) {
    return scheduledJobRuntime.value.find((item) => item.id === jobId) || null
  }

  function resolveTimeValue(seconds: number) {
    const normalized = Math.max(0, Number(seconds || 0))
    if (normalized >= 3600 && normalized % 3600 === 0) {
      return { amount: normalized / 3600, unit: 3600 }
    }

    if (normalized >= 60 && normalized % 60 === 0) {
      return { amount: normalized / 60, unit: 60 }
    }

    return { amount: normalized || 1, unit: 1 }
  }

  return {
    notificationFilePath,
    notificationForm,
    notificationRecipients,
    notificationSaving,
    notificationTesting,
    notificationResultError,
    notificationTestResult,
    scheduledJobsFilePath,
    scheduledJobsForm,
    scheduledJobs,
    scheduledJobRuntime,
    scheduledJobsSaving,
    scheduledJobRunningId,
    notificationStats,
    hydrateNotificationConfig,
    hydrateScheduledJobsConfig,
    addNotificationRecipient,
    removeNotificationRecipient,
    handleNotificationSaveConfig,
    handleNotificationTest,
    handleScheduledJobsSaveConfig,
    handleScheduledJobRunNow,
    getScheduledJobRuntime,
  }
}
