<script setup lang="ts">
import { Ban, CheckCircle, Key, Plus, Webhook as WebhookIcon } from 'lucide-vue-next'
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { toast } from 'vue-sonner'

import type { APIKey, Webhook } from '@/pages/admin/extension/data/schema'

import ConfirmDialog from '@/components/confirm-dialog.vue'
import DateRangeFilter from '@/components/data-table/date-range-filter.vue'
import SingleFilter from '@/components/data-table/single-filter.vue'
import { BasicPage } from '@/components/global-layout'
import APIKeyDataTable from '@/pages/admin/extension/components/apikey-data-table.vue'
import WebhookDataTable from '@/pages/admin/extension/components/webhook-data-table.vue'
import api from '@/services/api'

const { t } = useI18n()

interface Application {
  id: number
  name: string
}

const router = useRouter()

const loading = ref(true)
const webhooks = ref<Webhook[]>([])
const apiKeys = ref<APIKey[]>([])
const webhookTableRef = ref()
const apiKeyTableRef = ref()
const applications = ref<Application[]>([])

const appFilter = ref<string>('')
const statusFilter = ref<string>('')
const startDate = ref<string>('')
const endDate = ref<string>('')
const webhookSearchFilter = ref<string>('')
const apiKeySearchFilter = ref<string>('')
const currentTab = ref<string>('webhooks')

const deleteDialogOpen = ref(false)
const deleteTarget = ref<Webhook | APIKey | null>(null)
const deleteType = ref<'webhook' | 'apikey'>('webhook')
const batchDeleteDialogOpen = ref(false)
const batchDeleteIds = ref<(string | number)[]>([])
const regenerateDialogOpen = ref(false)
const regenerateTarget = ref<APIKey | null>(null)

const filteredWebhooks = computed(() => {
  let result = webhooks.value

  if (appFilter.value) {
    result = result.filter(webhook => String(webhook.application_id) === appFilter.value)
  }

  if (statusFilter.value) {
    result = result.filter(webhook => webhook.status === statusFilter.value)
  }

  if (startDate.value) {
    const fromDateTime = startDate.value.includes('T')
      ? startDate.value.replace('T', ' ')
      : `${startDate.value} 00:00`
    result = result.filter(webhook => webhook.created_at >= fromDateTime)
  }

  if (endDate.value) {
    const toDateTime = endDate.value.includes('T')
      ? endDate.value.replace('T', ' ')
      : `${endDate.value} 23:59`
    result = result.filter(webhook => webhook.created_at <= toDateTime)
  }

  if (webhookSearchFilter.value) {
    const search = webhookSearchFilter.value.toLowerCase()
    result = result.filter(webhook =>
      webhook.name?.toLowerCase().includes(search)
      || webhook.url?.toLowerCase().includes(search)
      || webhook.application_name?.toLowerCase().includes(search),
    )
  }

  return result
})

const filteredAPIKeys = computed(() => {
  let result = apiKeys.value

  if (appFilter.value) {
    result = result.filter(apiKey => String(apiKey.application_id) === appFilter.value)
  }

  if (statusFilter.value) {
    result = result.filter(apiKey => apiKey.status === statusFilter.value)
  }

  if (startDate.value) {
    const fromDateTime = startDate.value.includes('T')
      ? startDate.value.replace('T', ' ')
      : `${startDate.value} 00:00`
    result = result.filter(apiKey => apiKey.created_at >= fromDateTime)
  }

  if (endDate.value) {
    const toDateTime = endDate.value.includes('T')
      ? endDate.value.replace('T', ' ')
      : `${endDate.value} 23:59`
    result = result.filter(apiKey => apiKey.created_at <= toDateTime)
  }

  if (apiKeySearchFilter.value) {
    const search = apiKeySearchFilter.value.toLowerCase()
    result = result.filter(apiKey =>
      apiKey.name?.toLowerCase().includes(search)
      || apiKey.access_key?.toLowerCase().includes(search)
      || apiKey.application_name?.toLowerCase().includes(search),
    )
  }

  return result
})

const activeWebhookCount = computed(() => filteredWebhooks.value.filter(webhook => webhook.status === 'active').length)
const inactiveWebhookCount = computed(() => filteredWebhooks.value.filter(webhook => webhook.status === 'inactive').length)
const activeAPIKeyCount = computed(() => filteredAPIKeys.value.filter(apiKey => apiKey.status === 'active').length)
const inactiveAPIKeyCount = computed(() => filteredAPIKeys.value.filter(apiKey => apiKey.status === 'inactive').length)

const applicationOptions = computed(() => {
  return applications.value.map(app => ({
    label: app.name,
    value: String(app.id),
  }))
})

const statusOptions = computed(() => [
  { label: t('admin.extension.enabled'), value: 'active' },
  { label: t('admin.extension.disabled'), value: 'inactive' },
])

async function fetchApplications() {
  try {
    const data = await api.get<{ applications: Application[] }>('/dev/applications')
    applications.value = data?.applications || []
  }
  catch (error) {
    console.error('获取应用列表失败:', error)
  }
}

async function fetchWebhooks() {
  loading.value = true
  try {
    const data = await api.get<Webhook[]>('/dev/extension/webhooks')
    webhooks.value = Array.isArray(data) ? data : []
  }
  catch (error) {
    console.error('获取Webhook列表失败:', error)
    webhooks.value = []
  }
  finally {
    loading.value = false
  }
}

async function fetchAPIKeys() {
  loading.value = true
  try {
    const data = await api.get<APIKey[]>('/dev/extension/api-keys')
    apiKeys.value = Array.isArray(data) ? data : []
  }
  catch (error) {
    console.error('获取API密钥列表失败:', error)
    apiKeys.value = []
  }
  finally {
    loading.value = false
  }
}

function goToCreateWebhook() {
  router.push('/admin/extension/webhooks/create')
}

function goToCreateAPIKey() {
  router.push('/admin/extension/api-keys/create')
}

async function toggleWebhookStatus(webhook: Webhook) {
  try {
    const newStatus = webhook.status === 'active' ? 'inactive' : 'active'
    await api.put(`/dev/extension/webhooks/${webhook.id}/status`, { status: newStatus })
    toast.success(t('admin.extension.webhooks.statusUpdateSuccess'))
    fetchWebhooks()
  }
  catch (error: any) {
    console.error('切换Webhook状态失败:', error)
    toast.error(error.message || t('admin.extension.webhooks.statusUpdateFailed'))
  }
}

async function toggleAPIKeyStatus(apiKey: APIKey) {
  try {
    const newStatus = apiKey.status === 'active' ? 'inactive' : 'active'
    await api.put(`/dev/extension/api-keys/${apiKey.id}/status`, { status: newStatus })
    toast.success(t('admin.extension.apiKeys.statusUpdateSuccess'))
    fetchAPIKeys()
  }
  catch (error: any) {
    console.error('切换API密钥状态失败:', error)
    toast.error(error.message || t('admin.extension.apiKeys.statusUpdateFailed'))
  }
}

async function testWebhook(webhook: Webhook) {
  try {
    await api.post(`/dev/extension/webhooks/${webhook.id}/test`, {})
    toast.success(t('admin.extension.webhooks.testSuccess'))
  }
  catch (error: any) {
    console.error('测试Webhook失败:', error)
    toast.error(error.message || t('admin.extension.webhooks.testFailed'))
  }
}

function confirmRegenerateAPIKey(apiKey: APIKey) {
  regenerateTarget.value = apiKey
  regenerateDialogOpen.value = true
}

async function handleRegenerateAPIKey() {
  if (!regenerateTarget.value)
    return

  try {
    await api.post(`/dev/extension/api-keys/${regenerateTarget.value.id}/regenerate`, {})
    toast.success(t('admin.extension.apiKeys.regenerateSuccess'))
    fetchAPIKeys()
  }
  catch (error: any) {
    console.error('重新生成API密钥失败:', error)
    toast.error(error.message || t('admin.extension.apiKeys.regenerateFailed'))
  }
  finally {
    regenerateTarget.value = null
  }
}

function confirmDeleteWebhook(webhook: Webhook) {
  deleteTarget.value = webhook
  deleteType.value = 'webhook'
  deleteDialogOpen.value = true
}

function confirmDeleteAPIKey(apiKey: APIKey) {
  deleteTarget.value = apiKey
  deleteType.value = 'apikey'
  deleteDialogOpen.value = true
}

async function handleDelete() {
  if (!deleteTarget.value)
    return

  try {
    if (deleteType.value === 'webhook') {
      await api.delete(`/dev/extension/webhooks/${deleteTarget.value.id}`)
      toast.success(t('admin.extension.webhooks.deleteSuccess'))
      fetchWebhooks()
    }
    else {
      await api.delete(`/dev/extension/api-keys/${deleteTarget.value.id}`)
      toast.success(t('admin.extension.apiKeys.deleteSuccess'))
      fetchAPIKeys()
    }
  }
  catch (error: any) {
    console.error('删除失败:', error)
    toast.error(error.message || t('admin.extension.deleteFailed'))
  }
  finally {
    deleteTarget.value = null
  }
}

function confirmBatchDelete(type: 'webhook' | 'apikey', ids: (string | number)[]) {
  deleteType.value = type
  batchDeleteIds.value = ids
  batchDeleteDialogOpen.value = true
}

async function handleBatchDelete() {
  try {
    if (deleteType.value === 'webhook') {
      await api.delete('/dev/extension/webhooks/batch', { ids: batchDeleteIds.value } as any)
      toast.success(t('admin.extension.webhooks.deleteSuccess'))
      fetchWebhooks()
    }
    else {
      await api.delete('/dev/extension/api-keys/batch', { ids: batchDeleteIds.value } as any)
      toast.success(t('admin.extension.apiKeys.deleteSuccess'))
      fetchAPIKeys()
    }
  }
  catch (error: any) {
    console.error('批量删除失败:', error)
    toast.error(error.message || t('admin.extension.deleteFailed'))
  }
  finally {
    batchDeleteIds.value = []
  }
}

async function batchToggleWebhookStatus(ids: (string | number)[], status: string) {
  try {
    await api.put('/dev/extension/webhooks/batch/status', { ids, status })
    toast.success(t('admin.extension.webhooks.batchUpdateSuccess'))
    fetchWebhooks()
  }
  catch (error: any) {
    console.error('批量更新Webhook状态失败:', error)
    toast.error(error.message || t('admin.extension.webhooks.batchUpdateFailed'))
  }
}

async function batchToggleAPIKeyStatus(ids: (string | number)[], status: string) {
  try {
    await api.put('/dev/extension/api-keys/batch/status', { ids, status })
    toast.success(t('admin.extension.apiKeys.batchUpdateSuccess'))
    fetchAPIKeys()
  }
  catch (error: any) {
    console.error('批量更新API密钥状态失败:', error)
    toast.error(error.message || t('admin.extension.apiKeys.batchUpdateFailed'))
  }
}

onMounted(() => {
  fetchApplications()
  fetchWebhooks()
  fetchAPIKeys()
})
</script>

<template>
  <BasicPage
    :title="t('admin.extension.title')"
    :description="t('admin.extension.description')"
    sticky
  >
    <template #actions>
      <UiButton v-if="currentTab === 'webhooks'" @click="goToCreateWebhook">
        <Plus class="mr-2 h-4 w-4" />
        {{ t('admin.extension.webhooks.createBtn') }}
      </UiButton>
      <UiButton v-else @click="goToCreateAPIKey">
        <Plus class="mr-2 h-4 w-4" />
        {{ t('admin.extension.apiKeys.createBtn') }}
      </UiButton>
    </template>

    <div class="space-y-6">
      <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('admin.extension.totalWebhooks') }}
            </UiCardTitle>
            <WebhookIcon class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ filteredWebhooks.length }}
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('admin.extension.totalAPIKeys') }}
            </UiCardTitle>
            <Key class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ filteredAPIKeys.length }}
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('admin.extension.enabled') }}
            </UiCardTitle>
            <CheckCircle class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ activeWebhookCount + activeAPIKeyCount }}
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('admin.extension.disabled') }}
            </UiCardTitle>
            <Ban class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ inactiveWebhookCount + inactiveAPIKeyCount }}
            </div>
          </UiCardContent>
        </UiCard>
      </div>

      <UiTabs v-model="currentTab" default-value="webhooks" class="w-full">
        <UiTabsList class="grid w-full grid-cols-2">
          <UiTabsTrigger value="webhooks">
            <WebhookIcon class="h-4 w-4 mr-2" />
            {{ t('admin.extension.webhooks.title') }}
          </UiTabsTrigger>
          <UiTabsTrigger value="apikeys">
            <Key class="h-4 w-4 mr-2" />
            {{ t('admin.extension.apiKeys.title') }}
          </UiTabsTrigger>
        </UiTabsList>

        <UiTabsContent value="webhooks" class="space-y-4">
          <UiCard>
            <UiCardContent class="p-6">
              <WebhookDataTable
                ref="webhookTableRef"
                :loading
                :data="filteredWebhooks"
                :on-toggle-status="toggleWebhookStatus"
                :on-test="testWebhook"
                :on-delete="confirmDeleteWebhook"
                :search-filter="webhookSearchFilter"
                @refresh="fetchWebhooks"
                @batch-enable="batchToggleWebhookStatus(webhookTableRef?.table?.getSelectedRowModel().rows.filter((r: any) => r.original.status === 'inactive').map((r: any) => r.original.id) || [], 'active')"
                @batch-disable="batchToggleWebhookStatus(webhookTableRef?.table?.getSelectedRowModel().rows.filter((r: any) => r.original.status === 'active').map((r: any) => r.original.id) || [], 'inactive')"
                @batch-delete="confirmBatchDelete('webhook', webhookTableRef?.table?.getSelectedRowModel().rows.map((r: any) => r.original.id) || [])"
                @update:search-filter="webhookSearchFilter = $event"
              >
                <template #filters>
                  <SingleFilter
                    v-model="appFilter"
                    :title="t('admin.extension.application')"
                    :options="applicationOptions"
                  />
                  <SingleFilter
                    v-model="statusFilter"
                    :title="t('admin.extension.status')"
                    :options="statusOptions"
                  />
                  <DateRangeFilter
                    v-model:start-model-value="startDate"
                    v-model:end-model-value="endDate"
                  />
                </template>
              </WebhookDataTable>
            </UiCardContent>
          </UiCard>
        </UiTabsContent>

        <UiTabsContent value="apikeys" class="space-y-4">
          <UiCard>
            <UiCardContent class="p-6">
              <APIKeyDataTable
                ref="apiKeyTableRef"
                :loading
                :data="filteredAPIKeys"
                :on-toggle-status="toggleAPIKeyStatus"
                :on-regenerate="confirmRegenerateAPIKey"
                :on-delete="confirmDeleteAPIKey"
                :search-filter="apiKeySearchFilter"
                @refresh="fetchAPIKeys"
                @batch-enable="batchToggleAPIKeyStatus(apiKeyTableRef?.table?.getSelectedRowModel().rows.filter((r: any) => r.original.status === 'inactive').map((r: any) => r.original.id) || [], 'active')"
                @batch-disable="batchToggleAPIKeyStatus(apiKeyTableRef?.table?.getSelectedRowModel().rows.filter((r: any) => r.original.status === 'active').map((r: any) => r.original.id) || [], 'inactive')"
                @batch-delete="confirmBatchDelete('apikey', apiKeyTableRef?.table?.getSelectedRowModel().rows.map((r: any) => r.original.id) || [])"
                @update:search-filter="apiKeySearchFilter = $event"
              >
                <template #filters>
                  <SingleFilter
                    v-model="appFilter"
                    :title="t('admin.extension.application')"
                    :options="applicationOptions"
                  />
                  <SingleFilter
                    v-model="statusFilter"
                    :title="t('admin.extension.status')"
                    :options="statusOptions"
                  />
                  <DateRangeFilter
                    v-model:start-model-value="startDate"
                    v-model:end-model-value="endDate"
                  />
                </template>
              </APIKeyDataTable>
            </UiCardContent>
          </UiCard>
        </UiTabsContent>
      </UiTabs>
    </div>

    <ConfirmDialog
      v-model:open="deleteDialogOpen"
      destructive
      :confirm-button-text="t('admin.extension.delete')"
      :cancel-button-text="t('admin.extension.cancel')"
      @confirm="handleDelete"
    >
      <template #title>
        {{ deleteType === 'webhook' ? t('admin.extension.webhooks.deleteWebhook') : t('admin.extension.apiKeys.deleteAPIKey') }}
      </template>
      <template #description>
        {{ deleteType === 'webhook'
          ? t('admin.extension.webhooks.deleteConfirm', { webhookName: (deleteTarget as Webhook)?.name })
          : t('admin.extension.apiKeys.deleteConfirm', { apiKeyName: (deleteTarget as APIKey)?.name })
        }}
      </template>
    </ConfirmDialog>

    <ConfirmDialog
      v-model:open="batchDeleteDialogOpen"
      destructive
      :confirm-button-text="t('admin.extension.delete')"
      :cancel-button-text="t('admin.extension.cancel')"
      @confirm="handleBatchDelete"
    >
      <template #title>
        {{ deleteType === 'webhook' ? t('admin.extension.webhooks.batchDelete') : t('admin.extension.apiKeys.batchDelete') }}
      </template>
      <template #description>
        {{ deleteType === 'webhook'
          ? t('admin.extension.webhooks.batchDeleteConfirm', { count: batchDeleteIds.length })
          : t('admin.extension.apiKeys.batchDeleteConfirm', { count: batchDeleteIds.length })
        }}
      </template>
    </ConfirmDialog>
    <ConfirmDialog
      v-model:open="regenerateDialogOpen"
      :confirm-button-text="t('admin.extension.apiKeys.regenerate')"
      :cancel-button-text="t('admin.extension.cancel')"
      @confirm="handleRegenerateAPIKey"
    >
      <template #title>
        {{ t('admin.extension.apiKeys.regenerate') }}
      </template>
      <template #description>
        {{ t('admin.extension.apiKeys.regenerateConfirm') }}
      </template>
    </ConfirmDialog>
  </BasicPage>
</template>
