<script setup lang="ts">
import { Icon } from '@iconify/vue'
import * as echarts from 'echarts'
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'

import { BasicPage } from '@/components/global-layout'
import { BASE_URL } from '@/services/api'

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

interface DashboardStats {
  totalApplications: number
  totalCards: number
  totalUsers: number
  monthlyRevenue: number
}

interface Activity {
  id: number
  title: string
  description: string
  icon: string
  createdAt: Date
}

interface Ticket {
  id: number
  title: string
  status: string
  priority: string
  createdAt: Date
}

interface Province {
  name: string
  count: number
}

const loading = ref(true)
const currentUser = ref<any>(null)
const stats = ref<DashboardStats>({
  totalApplications: 0,
  totalCards: 0,
  totalUsers: 0,
  monthlyRevenue: 0,
})

const provinces = ref<Province[]>([])
const chinaProvinces = ref<Province[]>([])
const onlineTrendData = ref<number[]>([])
const recentActivities = ref<Activity[]>([])
const recentTickets = ref<Ticket[]>([])

const mapChart = ref<HTMLElement | null>(null)
const activityChart = ref<HTMLCanvasElement | null>(null)
let chartInstance: any = null
let activityChartInstance: any = null
const currentMapType = ref<'china'>('china')

const domesticUsers = computed(() => {
  if (!chinaProvinces.value || chinaProvinces.value.length === 0)
    return 0
  return chinaProvinces.value.reduce((sum, province) => sum + (province.count || 0), 0)
})

const overseasUsers = computed(() => {
  if (!provinces.value || provinces.value.length === 0)
    return 0
  return provinces.value.reduce((sum, country) => {
    if (country.name !== 'China')
      return sum + (country.count || 0)
    return sum
  }, 0)
})

const totalUsers = computed(() => {
  if (stats.value?.totalUsers && stats.value.totalUsers > 0) {
    return stats.value.totalUsers
  }
  return (domesticUsers.value || 0) + (overseasUsers.value || 0)
})

function formatDate(date: Date) {
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).format(date)
}

function formatNumber(num: number) {
  return (num || 0).toLocaleString()
}

function getTicketStatusColor(status: string) {
  const colors: Record<string, string> = {
    open: 'bg-yellow-500/10 text-yellow-500',
    processing: 'bg-blue-500/10 text-blue-500',
    resolved: 'bg-green-500/10 text-green-500',
    closed: 'bg-gray-500/10 text-gray-500',
  }
  return colors[status] || 'bg-gray-500/10 text-gray-500'
}

function getTicketStatusText(status: string) {
  const texts: Record<string, string> = {
    open: t('developer.ticketStatusOpen'),
    processing: t('developer.ticketStatusProcessing'),
    resolved: t('developer.ticketStatusResolved'),
    closed: t('developer.ticketStatusClosed'),
  }
  return texts[status] || status
}

function getTicketPriorityColor(priority: string) {
  const colors: Record<string, string> = {
    low: 'text-gray-500',
    normal: 'text-blue-500',
    high: 'text-orange-500',
    urgent: 'text-red-500',
  }
  return colors[priority] || 'text-gray-500'
}

function getTicketPriorityText(priority: string) {
  const texts: Record<string, string> = {
    low: t('developer.priorityLow'),
    normal: t('developer.priorityNormal'),
    high: t('developer.priorityHigh'),
    urgent: t('developer.priorityUrgent'),
  }
  return texts[priority] || priority
}

function goToTicket(ticketId: number) {
  router.push(`/developer/tickets/${ticketId}`)
}

function goToTickets() {
  router.push('/developer/tickets')
}

async function fetchDashboard() {
  loading.value = true
  try {
    const token = localStorage.getItem('token')
    if (!token) {
      console.error('No token found')
      return
    }

    const response = await fetch(`${BASE_URL}/dev/dashboard`, {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const data = await response.json()

    if (data.code === 200 && data.data) {
      if (data.data.stats) {
        stats.value = {
          totalApplications: data.data.stats.totalApplications || 0,
          totalCards: data.data.stats.totalCards || 0,
          totalUsers: data.data.stats.totalUsers || 0,
          monthlyRevenue: data.data.stats.monthlyRevenue || 0,
        }
      }

      if (data.data.userDistribution) {
        if (data.data.userDistribution.provinces && Array.isArray(data.data.userDistribution.provinces)) {
          chinaProvinces.value = data.data.userDistribution.provinces.map((p: any) => ({
            name: p.name,
            count: p.count || 0,
          }))
        }
        if (data.data.userDistribution.overseas && Array.isArray(data.data.userDistribution.overseas)) {
          provinces.value = data.data.userDistribution.overseas.map((p: any) => ({
            name: p.name,
            count: p.count || 0,
          }))
        }
      }

      if (data.data.onlineTrend && Array.isArray(data.data.onlineTrend)) {
        onlineTrendData.value = data.data.onlineTrend.map((t: any) => t.value || t.count || 0)
      }

      if (data.data.recentActivities && Array.isArray(data.data.recentActivities)) {
        recentActivities.value = data.data.recentActivities.map((log: any) => {
          let icon = 'lucide:activity'
          let title = log.action || t('developer.operation')
          let description = log.details || log.resource || t('developer.noDescription')

          if (log.log_type === 'operation') {
            icon = 'lucide:plus-circle'
            title = t('developer.operationRecord')
          }
          else if (log.log_type === 'verification') {
            icon = 'lucide:check-circle'
            title = t('developer.cardVerification')
            description = `${t('developer.verification')}${log.status === 'success' ? t('developer.success') : t('developer.failed')}`
          }
          else if (log.log_type === 'exception') {
            icon = 'lucide:alert-circle'
            title = t('developer.exceptionRecord')
          }

          return {
            id: log.id,
            title,
            description,
            icon,
            createdAt: new Date(log.created_at),
          }
        })
      }

      if (data.data.recentTickets && Array.isArray(data.data.recentTickets)) {
        recentTickets.value = data.data.recentTickets.map((t: any) => ({
          id: t.id,
          title: t.title,
          status: t.status,
          priority: t.priority,
          createdAt: new Date(t.created_at),
        }))
      }
    }
    else {
      console.error('API returned error:', data)
    }
  }
  catch (error) {
    console.error(t('developer.fetchDashboardError'), error)
  }
  finally {
    loading.value = false
  }
}

function fetchCurrentUser() {
  const userStr = localStorage.getItem('user')
  if (userStr) {
    currentUser.value = JSON.parse(userStr)
  }
}

async function initMapChart() {
  if (!mapChart.value)
    return

  try {
    const chinaResponse = await fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json')

    if (!chinaResponse.ok) {
      throw new Error('Failed to load China map data')
    }

    const chinaData = await chinaResponse.json()

    echarts.registerMap('china', chinaData)

    chartInstance = echarts.init(mapChart.value)

    updateMapOption()

    window.addEventListener('resize', () => {
      chartInstance?.resize()
    })
  }
  catch (error) {
    console.error(t('developer.initMapError'), error)
  }
}

function updateMapOption() {
  if (!chartInstance)
    return

  const isChinaMap = currentMapType.value === 'china'
  const data = isChinaMap ? chinaProvinces.value : provinces.value

  const option = {
    tooltip: {
      trigger: 'item',
      backgroundColor: 'rgba(15, 23, 42, 0.95)',
      borderColor: '#334155',
      borderWidth: 1,
      padding: 12,
      formatter: (params: any) => {
        if (params.data && params.data.count > 0) {
          return `<div style="padding: 8px;">
            <div style="font-weight: bold; margin-bottom: 4px; color: #f8fafc;">${params.name}</div>
            <div style="color: #cbd5e1;">${t('developer.userCount')}: ${params.data.count}</div>
          </div>`
        }
        return `<div style="padding: 8px;">
          <div style="font-weight: bold; margin-bottom: 4px; color: #f8fafc;">${params.name}</div>
          <div style="color: #cbd5e1;">${t('developer.noUserData')}</div>
        </div>`
      },
    },
    visualMap: {
      show: false,
      min: 0,
      max: Math.max(...data.map((d: any) => d.count || 0), 1),
      inRange: {
        color: ['#e0f2fe', '#3b82f6'],
      },
    },
    geo: {
      map: isChinaMap ? 'china' : 'world',
      roam: false,
      zoom: isChinaMap ? 1.2 : 1.1,
      center: isChinaMap ? [104.195, 35.861] : undefined,
      label: {
        show: false,
      },
      emphasis: {
        label: {
          show: true,
          color: '#f8fafc',
        },
        itemStyle: {
          areaColor: '#3b82f6',
          borderColor: '#1d4ed8',
          borderWidth: 2,
        },
      },
      itemStyle: {
        areaColor: 'rgba(226, 232, 240, 0.3)',
        borderColor: '#e2e8f0',
        borderWidth: 1,
      },
    },
    series: [
      {
        name: t('developer.userDistribution'),
        type: 'map',
        geoIndex: 0,
        data,
      },
    ],
  }

  chartInstance.setOption(option)
}

function initActivityChart() {
  if (!activityChart.value)
    return

  try {
    import('chart.js/auto').then(({ default: Chart }) => {
      const ctx = activityChart.value?.getContext('2d')
      if (!ctx)
        return

      const labels = Array.from({ length: 30 }, (_, i) => {
        const date = new Date()
        date.setDate(date.getDate() - (29 - i))
        return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' })
      })

      const data = onlineTrendData.value.length > 0
        ? onlineTrendData.value
        : Array.from({ length: 30 }).fill(0)

      if (activityChartInstance) {
        activityChartInstance.destroy()
      }

      activityChartInstance = new Chart(ctx, {
        type: 'line',
        data: {
          labels,
          datasets: [
            {
              label: t('developer.verificationCount'),
              data,
              borderColor: '#3b82f6',
              backgroundColor: 'rgba(59, 130, 246, 0.1)',
              fill: true,
              tension: 0.4,
              pointRadius: 0,
              pointHoverRadius: 6,
              pointHoverBackgroundColor: '#3b82f6',
              pointHoverBorderColor: '#fff',
              pointHoverBorderWidth: 2,
            },
          ],
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          plugins: {
            legend: {
              display: false,
            },
            tooltip: {
              backgroundColor: 'rgba(15, 23, 42, 0.95)',
              titleColor: '#f8fafc',
              bodyColor: '#cbd5e1',
              borderColor: '#334155',
              borderWidth: 1,
              padding: 12,
              displayColors: false,
              callbacks: {
                label: (context: any) => `${context.parsed.y} ${t('developer.online')}`,
              },
            },
          },
          scales: {
            x: {
              grid: {
                display: false,
              },
              ticks: {
                color: '#94a3b8',
                font: {
                  size: 11,
                },
              },
            },
            y: {
              grid: {
                color: '#334155',
              },
              ticks: {
                color: '#94a3b8',
                font: {
                  size: 11,
                },
              },
              beginAtZero: true,
            },
          },
          interaction: {
            intersect: false,
            mode: 'index',
          },
        },
      })
    })
  }
  catch (error) {
    console.error(t('developer.initActivityChartError'), error)
  }
}

onMounted(async () => {
  fetchCurrentUser()
  await fetchDashboard()
  await nextTick()

  initMapChart()
  initActivityChart()
})

onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  if (activityChartInstance) {
    activityChartInstance.destroy()
    activityChartInstance = null
  }
})
</script>

<template>
  <BasicPage
    :title="t('developer.dashboard')"
    :description="`${t('developer.welcomeBack')}, ${currentUser?.username || t('developer.developer')}`"
  >
    <div v-if="loading" class="flex items-center justify-center py-12">
      <div class="text-center">
        <Icon icon="lucide:loader-2" class="size-8 animate-spin mx-auto text-muted-foreground" />
        <p class="mt-4 text-muted-foreground">
          {{ t('developer.loading') }}...
        </p>
      </div>
    </div>

    <div v-else class="space-y-4">
      <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('developer.totalApplications') }}
            </UiCardTitle>
            <Icon icon="lucide:layout-grid" class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ formatNumber(stats.totalApplications) }}
            </div>
            <p class="text-xs text-muted-foreground">
              +12.5% {{ t('developer.lastMonth') }}
            </p>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('developer.totalCards') }}
            </UiCardTitle>
            <Icon icon="lucide:key" class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ formatNumber(stats.totalCards) }}
            </div>
            <p class="text-xs text-muted-foreground">
              +8.2% {{ t('developer.lastMonth') }}
            </p>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('developer.totalUsers') }}
            </UiCardTitle>
            <Icon icon="lucide:users" class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ formatNumber(totalUsers) }}
            </div>
            <p class="text-xs text-muted-foreground">
              +15.3% {{ t('developer.lastMonth') }}
            </p>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('developer.monthlyRevenue') }}
            </UiCardTitle>
            <Icon icon="lucide:dollar-sign" class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              ¥{{ formatNumber(stats.monthlyRevenue) }}
            </div>
            <p class="text-xs text-muted-foreground">
              +23.1% {{ t('developer.lastMonth') }}
            </p>
          </UiCardContent>
        </UiCard>
      </div>

      <div class="grid gap-4 lg:grid-cols-2">
        <UiCard>
          <UiCardHeader>
            <div class="flex items-center justify-between">
              <div>
                <UiCardTitle>{{ t('developer.userDistribution') }}</UiCardTitle>
                <UiCardDescription>{{ t('developer.userDistributionDesc') }}</UiCardDescription>
              </div>
              <div class="flex items-center gap-4 text-sm">
                <div class="flex items-center gap-2">
                  <div class="size-3 rounded-full bg-blue-500" />
                  <span class="text-muted-foreground">{{ t('developer.domesticUsers') }}: {{ formatNumber(domesticUsers) }}</span>
                </div>
                <div class="flex items-center gap-2">
                  <div class="size-3 rounded-full bg-green-500" />
                  <span class="text-muted-foreground">{{ t('developer.overseasUsers') }}: {{ formatNumber(overseasUsers) }}</span>
                </div>
              </div>
            </div>
          </UiCardHeader>
          <UiCardContent>
            <div class="relative h-[350px] rounded-lg overflow-hidden bg-card">
              <div ref="mapChart" class="w-full h-full" />
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader>
            <UiCardTitle>{{ t('developer.onlineTrend') }}</UiCardTitle>
            <UiCardDescription>{{ t('developer.onlineTrendDesc') }}</UiCardDescription>
          </UiCardHeader>
          <UiCardContent class="pl-2">
            <div class="relative h-[350px]">
              <canvas ref="activityChart" />
            </div>
          </UiCardContent>
        </UiCard>
      </div>

      <UiCard>
        <UiCardHeader>
          <div class="flex items-center justify-between">
            <div>
              <UiCardTitle>{{ t('developer.recentTickets') }}</UiCardTitle>
              <UiCardDescription>{{ t('developer.recentTicketsDesc') }}</UiCardDescription>
            </div>
            <UiButton variant="ghost" size="sm" @click="goToTickets">
              {{ t('developer.viewAll') }}
              <Icon icon="lucide:arrow-right" class="ml-1 size-4" />
            </UiButton>
          </div>
        </UiCardHeader>
        <UiCardContent>
          <div v-if="recentTickets.length > 0" class="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
            <div
              v-for="ticket in recentTickets.slice(0, 5)"
              :key="ticket.id"
              class="flex items-start gap-3 p-3 rounded-lg border hover:bg-muted/50 cursor-pointer transition-colors"
              @click="goToTicket(ticket.id)"
            >
              <div class="flex-shrink-0">
                <div class="size-8 rounded-full bg-primary/10 flex items-center justify-center">
                  <Icon icon="lucide:ticket" class="size-4 text-primary" />
                </div>
              </div>
              <div class="flex-1 min-w-0">
                <p class="text-sm font-medium truncate">
                  {{ ticket.title }}
                </p>
                <div class="flex items-center gap-2 mt-1">
                  <UiBadge :class="getTicketStatusColor(ticket.status)" class="text-[10px] flex-shrink-0">
                    {{ getTicketStatusText(ticket.status) }}
                  </UiBadge>
                  <span :class="`text-xs ${getTicketPriorityColor(ticket.priority)}`">
                    {{ getTicketPriorityText(ticket.priority) }}
                  </span>
                </div>
                <span class="text-xs text-muted-foreground">{{ formatDate(ticket.createdAt) }}</span>
              </div>
            </div>
          </div>
          <div v-else class="text-center py-8 text-muted-foreground">
            <Icon icon="lucide:ticket" class="mx-auto size-10 text-muted-foreground mb-2" />
            <p class="text-sm">
              {{ t('developer.noTickets') }}
            </p>
          </div>
        </UiCardContent>
      </UiCard>

      <UiCard>
        <UiCardHeader>
          <UiCardTitle>{{ t('developer.recentActivities') }}</UiCardTitle>
          <UiCardDescription>{{ t('developer.recentActivitiesDesc') }}</UiCardDescription>
        </UiCardHeader>
        <UiCardContent>
          <div v-if="recentActivities.length > 0" class="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
            <div
              v-for="activity in recentActivities.slice(0, 8)"
              :key="activity.id"
              class="flex items-start gap-3 p-3 rounded-lg border hover:bg-muted/50 transition-colors"
            >
              <div class="flex-shrink-0">
                <div class="size-7 rounded-full bg-primary/10 flex items-center justify-center">
                  <Icon :icon="activity.icon" class="size-3.5 text-primary" />
                </div>
              </div>
              <div class="flex-1 min-w-0">
                <p class="text-sm font-medium">
                  {{ activity.title }}
                </p>
                <p class="text-xs text-muted-foreground truncate">
                  {{ activity.description }}
                </p>
                <p class="text-xs text-muted-foreground mt-0.5">
                  {{ formatDate(activity.createdAt) }}
                </p>
              </div>
            </div>
          </div>
          <div v-else class="text-center py-8 text-muted-foreground">
            <Icon icon="lucide:activity" class="mx-auto size-10 text-muted-foreground mb-2" />
            <p class="text-sm">
              {{ t('developer.noActivities') }}
            </p>
          </div>
        </UiCardContent>
      </UiCard>
    </div>
  </BasicPage>
</template>
