<script setup lang="ts">
import { Ban, CheckCircle, Clock, Plus, Users } 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 { Agent } from './data/schema'

import ConfirmDialog from '@/components/confirm-dialog.vue'
import SingleFilter from '@/components/data-table/single-filter.vue'
import { BasicPage } from '@/components/global-layout'
import DataTable from './components/data-table.vue'
import api from '@/services/api'

const { t } = useI18n()
const router = useRouter()

const loading = ref(true)
const agents = ref<Agent[]>([])
const tableRef = ref<InstanceType<typeof DataTable> | null>(null)
const searchFilter = ref('')
const statusFilter = ref<string>('')
const viewMode = ref<'tree' | 'list'>('tree')

const deleteDialogOpen = ref(false)
const deleteTarget = ref<Agent | null>(null)
const batchDeleteDialogOpen = ref(false)
const batchDeleteIds = ref<number[]>([])

const filteredAgents = computed(() => {
  let result = agents.value
  
  if (statusFilter.value) {
    const filterByStatus = (items: Agent[]): Agent[] => {
      return items.reduce((acc: Agent[], item) => {
        const matches = item.status === statusFilter.value
        const filteredChildren = item.children ? filterByStatus(item.children) : []
        
        if (matches || filteredChildren.length > 0) {
          acc.push({
            ...item,
            children: filteredChildren.length > 0 ? filteredChildren : item.children,
          })
        }
        return acc
      }, [])
    }
    result = filterByStatus(result)
  }
  
  if (searchFilter.value) {
    const search = searchFilter.value.toLowerCase()
    const filterTree = (items: Agent[]): Agent[] => {
      return items.reduce((acc: Agent[], item) => {
        const matchesSearch = 
          item.username?.toLowerCase().includes(search) ||
          item.email?.toLowerCase().includes(search) ||
          item.parent_agent_name?.toLowerCase().includes(search)
        
        const filteredChildren = item.children ? filterTree(item.children) : []
        
        if (matchesSearch || filteredChildren.length > 0) {
          acc.push({
            ...item,
            children: filteredChildren.length > 0 ? filteredChildren : item.children,
          })
        }
        
        return acc
      }, [])
    }
    result = filterTree(result)
  }
  
  return result
})

const totalAgents = computed(() => {
  const countNodes = (items: Agent[]): number => {
    return items.reduce((acc, item) => {
      return acc + 1 + (item.children ? countNodes(item.children) : 0)
    }, 0)
  }
  return countNodes(agents.value)
})

const activeCount = computed(() => {
  const countByStatus = (items: Agent[], status: string): number => {
    return items.reduce((acc, item) => {
      const self = item.status === status ? 1 : 0
      const children = item.children ? countByStatus(item.children, status) : 0
      return acc + self + children
    }, 0)
  }
  return countByStatus(agents.value, 'active')
})

const inactiveCount = computed(() => {
  const countByStatus = (items: Agent[], status: string): number => {
    return items.reduce((acc, item) => {
      const self = item.status === status ? 1 : 0
      const children = item.children ? countByStatus(item.children, status) : 0
      return acc + self + children
    }, 0)
  }
  return countByStatus(agents.value, 'inactive')
})

const bannedCount = computed(() => {
  const countByStatus = (items: Agent[], status: string): number => {
    return items.reduce((acc, item) => {
      const self = item.status === status ? 1 : 0
      const children = item.children ? countByStatus(item.children, status) : 0
      return acc + self + children
    }, 0)
  }
  return countByStatus(agents.value, 'banned')
})

const statusOptions = computed(() => [
  { label: t('admin.agents.status.active'), value: 'active' },
  { label: t('admin.agents.status.inactive'), value: 'inactive' },
  { label: t('admin.agents.status.banned'), value: 'banned' },
])

async function fetchAgents() {
  loading.value = true
  try {
    const endpoint = viewMode.value === 'tree' ? '/dev/agents/tree' : '/dev/agents'
    const data = await api.get<{ tree?: Agent[], agents?: Agent[], total: number }>(endpoint)
    if (viewMode.value === 'tree') {
      agents.value = data?.tree || []
    } else {
      agents.value = data?.agents || []
    }
  } catch (error) {
    console.error('获取代理列表失败:', error)
    agents.value = []
  } finally {
    loading.value = false
  }
}

function goToCreate() {
  router.push('/admin/agents/create')
}

function toggleViewMode() {
  viewMode.value = viewMode.value === 'tree' ? 'list' : 'tree'
  fetchAgents()
}

function handleEdit(agent: Agent) {
  router.push(`/admin/agents/${agent.id}/edit`)
}

async function handleToggleStatus(agent: Agent) {
  try {
    const newStatus = agent.status === 'banned' ? 'active' : 'banned'
    await api.put(`/dev/agents/${agent.id}/status`, { status: newStatus })
    toast.success(t('admin.agents.statusUpdateSuccess'))
    fetchAgents()
  } catch (error: any) {
    console.error('切换代理状态失败:', error)
    toast.error(error.message || t('admin.agents.statusUpdateFailed'))
  }
}

function confirmDelete(agent: Agent) {
  deleteTarget.value = agent
  deleteDialogOpen.value = true
}

async function handleDelete() {
  if (!deleteTarget.value) return
  
  try {
    await api.delete(`/dev/agents/${deleteTarget.value.id}`)
    toast.success(t('admin.agents.deleteSuccess'))
    fetchAgents()
  } catch (error: any) {
    console.error('删除代理失败:', error)
    toast.error(error.message || t('admin.agents.deleteFailed'))
  } finally {
    deleteTarget.value = null
  }
}

function confirmBatchDelete(ids: number[]) {
  batchDeleteIds.value = ids
  batchDeleteDialogOpen.value = true
}

async function handleBatchDelete() {
  try {
    await api.delete('/dev/agents/batch', { agent_ids: batchDeleteIds.value } as any)
    toast.success(t('admin.agents.batchDeleteSuccess'))
    fetchAgents()
  } catch (error: any) {
    console.error('批量删除失败:', error)
    toast.error(error.message || t('admin.agents.batchDeleteFailed'))
  } finally {
    batchDeleteIds.value = []
  }
}

async function batchToggleStatus(ids: number[], status: string) {
  try {
    await api.post('/dev/agents/batch/status', { agent_ids: ids, status })
    toast.success(t('admin.agents.batchUpdateSuccess'))
    fetchAgents()
  } catch (error: any) {
    console.error('批量更新状态失败:', error)
    toast.error(error.message || t('admin.agents.batchUpdateFailed'))
  }
}

onMounted(() => {
  fetchAgents()
})
</script>

<template>
  <BasicPage
    :title="t('admin.agents.title')"
    :description="t('admin.agents.description')"
    sticky
  >
    <template #actions>
      <UiButton @click="goToCreate">
        <Plus class="mr-2 h-4 w-4" />
        {{ t('admin.agents.addAgent') }}
      </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.agents.totalAgents') }}
            </UiCardTitle>
            <Users class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ totalAgents }}
            </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.agents.status.active') }}
            </UiCardTitle>
            <CheckCircle class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ activeCount }}
            </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.agents.status.inactive') }}
            </UiCardTitle>
            <Clock class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ inactiveCount }}
            </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.agents.status.banned') }}
            </UiCardTitle>
            <Ban class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ bannedCount }}
            </div>
          </UiCardContent>
        </UiCard>
      </div>

      <UiCard>
        <UiCardContent class="p-6">
          <DataTable
            ref="tableRef"
            :loading="loading"
            :data="filteredAgents"
            :search-filter="searchFilter"
            :view-mode="viewMode"
            :on-toggle-status="handleToggleStatus"
            :on-edit="handleEdit"
            :on-delete="confirmDelete"
            @refresh="fetchAgents"
            @toggle-view="toggleViewMode"
            @update:search-filter="searchFilter = $event"
            @batch-unban="batchToggleStatus(tableRef?.table?.getSelectedRowModel().rows.filter((r: any) => r.original.status === 'banned').map((r: any) => r.original.id) || [], 'active')"
            @batch-ban="batchToggleStatus(tableRef?.table?.getSelectedRowModel().rows.filter((r: any) => r.original.status !== 'banned').map((r: any) => r.original.id) || [], 'banned')"
            @batch-delete="confirmBatchDelete(tableRef?.table?.getSelectedRowModel().rows.map((r: any) => r.original.id) || [])"
          >
            <template #filters>
              <SingleFilter
                v-model="statusFilter"
                :title="t('admin.agents.columns.status')"
                :options="statusOptions"
              />
            </template>
          </DataTable>
        </UiCardContent>
      </UiCard>
    </div>

    <ConfirmDialog
      v-model:open="deleteDialogOpen"
      destructive
      :confirm-button-text="t('common.delete')"
      :cancel-button-text="t('common.cancel')"
      @confirm="handleDelete"
    >
      <template #title>
        {{ t('admin.agents.deleteAgent') }}
      </template>
      <template #description>
        {{ t('admin.agents.deleteAgentConfirm', { username: deleteTarget?.username }) }}
      </template>
    </ConfirmDialog>

    <ConfirmDialog
      v-model:open="batchDeleteDialogOpen"
      destructive
      :confirm-button-text="t('common.delete')"
      :cancel-button-text="t('common.cancel')"
      @confirm="handleBatchDelete"
    >
      <template #title>
        {{ t('admin.agents.batchDeleteAgents') }}
      </template>
      <template #description>
        {{ t('admin.agents.batchDeleteConfirm', { count: batchDeleteIds.length }) }}
      </template>
    </ConfirmDialog>
  </BasicPage>
</template>
