import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Link } from '@tanstack/react-router'
import {
  Ban,
  Clock3,
  Database,
  HardDrive,
  Inbox,
  Mail,
  RefreshCw,
  ShieldAlert,
  Users,
} from 'lucide-react'
import {
  CartesianGrid,
  Legend,
  Line,
  LineChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts'
import {
  formatAdminText,
  formatAuditActionLabel,
  formatAuditEventLabel,
  formatSecurityResultLabel,
  formatStatusLabel,
  formatTargetTypeLabel,
} from '@/lib/admin-labels'
import { api, type ApiResponse } from '@/lib/api'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { ConfigDrawer } from '@/components/config-drawer'
import { Header } from '@/components/layout/header'
import { Main } from '@/components/layout/main'
import { ProfileDropdown } from '@/components/profile-dropdown'
import { ThemeSwitch } from '@/components/theme-switch'
import {
  formatBytes,
  formatCompactNumber,
  formatDate,
} from '@/features/governance/shared'

interface OverviewData {
  range: string
  generated_at: string
  metrics: {
    total_users: number
    today_users: number
    active_mailboxes: number
    expiring_mailboxes: number
    today_emails: number
    total_emails: number
    quarantined: number
    today_quarantine_rate: number
    storage_bytes: number
    active_blocks: number
  }
  trend: Array<{
    label: string
    received: number
    quarantined: number
    rejected: number
  }>
  security: Record<string, Record<string, number>>
  health: Array<{
    name: string
    status: string
    detail?: string
    last_success_at?: string
  }>
  risk_queue: Array<{
    kind: string
    id: number
    title: string
    detail: string
    created_at: string
  }>
  top: Record<string, Array<{ name: string; count: number }>>
  recent_actions: Array<{
    id: number
    event_type: string
    action: string
    operator_id?: string
    target_type?: string
    target_id?: string
    reason?: string
    created_at: string
  }>
}

const ranges = ['24h', '7d', '30d'] as const

function Distribution({
  title,
  values,
}: {
  title: string
  values: Record<string, number>
}) {
  const total = Object.values(values).reduce((sum, value) => sum + value, 0)
  return (
    <div className='space-y-2'>
      <div className='flex items-center justify-between text-sm'>
        <span className='font-medium'>{title}</span>
        <span className='text-muted-foreground'>
          {formatCompactNumber(total)}
        </span>
      </div>
      <div className='flex h-2 overflow-hidden rounded-sm bg-muted'>
        {Object.entries(values).map(([key, value], index) => (
          <div
            key={key}
            title={`${formatSecurityResultLabel(key)}：${value}`}
            className={cn(
              index % 4 === 0 && 'bg-emerald-500',
              index % 4 === 1 && 'bg-amber-500',
              index % 4 === 2 && 'bg-red-500',
              index % 4 === 3 && 'bg-sky-500'
            )}
            style={{ width: `${total ? (value / total) * 100 : 0}%` }}
          />
        ))}
      </div>
      <div className='flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground'>
        {Object.entries(values).map(([key, value]) => (
          <span key={key}>
            {formatSecurityResultLabel(key)} {formatCompactNumber(value)}
          </span>
        ))}
      </div>
    </div>
  )
}

function TopList({
  title,
  items,
}: {
  title: string
  items: Array<{ name: string; count: number }>
}) {
  const max = Math.max(...items.map((item) => item.count), 1)
  return (
    <div className='min-w-0 space-y-3'>
      <h3 className='text-sm font-semibold'>{title}</h3>
      {items.map((item) => (
        <div key={item.name} className='space-y-1'>
          <div className='flex items-center justify-between gap-3 text-xs'>
            <span className='truncate'>{item.name}</span>
            <span className='font-medium'>
              {formatCompactNumber(item.count)}
            </span>
          </div>
          <div className='h-1 bg-muted'>
            <div
              className='h-full bg-sky-500'
              style={{ width: `${(item.count / max) * 100}%` }}
            />
          </div>
        </div>
      ))}
      {items.length === 0 && (
        <p className='text-sm text-muted-foreground'>暂无数据</p>
      )}
    </div>
  )
}

export function Dashboard() {
  const [range, setRange] = useState<(typeof ranges)[number]>('7d')
  const overview = useQuery({
    queryKey: ['admin', 'overview', range],
    queryFn: async () => {
      const response = await api.get<ApiResponse<OverviewData>>(
        '/admin/overview',
        { params: { range } }
      )
      return response.data.data
    },
    refetchInterval: 60_000,
  })
  const data = overview.data
  const metrics = data?.metrics
  const cards = [
    {
      label: '总用户',
      value: formatCompactNumber(metrics?.total_users ?? 0),
      detail: `今日新增 ${formatCompactNumber(metrics?.today_users ?? 0)}`,
      icon: Users,
      to: '/users',
    },
    {
      label: '活跃邮箱',
      value: formatCompactNumber(metrics?.active_mailboxes ?? 0),
      detail: `24 小时内到期 ${formatCompactNumber(metrics?.expiring_mailboxes ?? 0)}`,
      icon: Inbox,
      to: '/mailboxes',
    },
    {
      label: '今日邮件',
      value: formatCompactNumber(metrics?.today_emails ?? 0),
      detail: `累计 ${formatCompactNumber(metrics?.total_emails ?? 0)}`,
      icon: Mail,
      to: '/emails',
    },
    {
      label: '待处理隔离',
      value: formatCompactNumber(metrics?.quarantined ?? 0),
      detail: `今日隔离率 ${((metrics?.today_quarantine_rate ?? 0) * 100).toFixed(1)}%`,
      icon: ShieldAlert,
      to: '/quarantine',
    },
    {
      label: '邮件存储量',
      value: formatBytes(metrics?.storage_bytes ?? 0),
      detail: '正文与附件合计',
      icon: HardDrive,
      to: '/emails',
    },
    {
      label: '生效封禁',
      value: formatCompactNumber(metrics?.active_blocks ?? 0),
      detail: '发件人、域与来源 IP',
      icon: Ban,
      to: '/blacklists',
    },
  ] as const

  return (
    <>
      <Header>
        <div className='ms-auto flex items-center gap-3'>
          <ThemeSwitch />
          <ConfigDrawer />
          <ProfileDropdown />
        </div>
      </Header>
      <Main className='flex flex-1 flex-col gap-6'>
        <div className='flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between'>
          <div>
            <h1 className='text-2xl font-semibold'>运行概览</h1>
            <p className='mt-1 text-sm text-muted-foreground'>
              邮件接收、安全处置和关键依赖的实时状态。
            </p>
          </div>
          <div className='flex flex-wrap items-center gap-2'>
            <div className='flex rounded-md border p-1'>
              {ranges.map((value) => (
                <Button
                  key={value}
                  size='sm'
                  variant={range === value ? 'secondary' : 'ghost'}
                  onClick={() => setRange(value)}
                >
                  {value === '24h'
                    ? '24 小时'
                    : value === '7d'
                      ? '7 天'
                      : '30 天'}
                </Button>
              ))}
            </div>
            <Button
              size='icon'
              variant='outline'
              title='手动刷新'
              onClick={() => overview.refetch()}
            >
              <RefreshCw
                className={cn(overview.isFetching && 'animate-spin')}
              />
            </Button>
          </div>
        </div>

        <div className='grid gap-3 sm:grid-cols-2 xl:grid-cols-6'>
          {cards.map(({ label, value, detail, icon: Icon, to }) => (
            <Link key={label} to={to}>
              <Card className='h-full rounded-md transition-colors hover:bg-muted/30'>
                <CardHeader className='flex-row items-center justify-between pb-2'>
                  <CardTitle className='text-sm font-medium'>{label}</CardTitle>
                  <Icon className='size-4 text-muted-foreground' />
                </CardHeader>
                <CardContent>
                  <div className='text-2xl font-semibold'>{value}</div>
                  <p className='mt-1 text-xs text-muted-foreground'>{detail}</p>
                </CardContent>
              </Card>
            </Link>
          ))}
        </div>

        <section className='grid gap-6 border-y py-6 xl:grid-cols-[minmax(0,2fr)_minmax(300px,1fr)]'>
          <div className='min-w-0'>
            <div className='mb-4'>
              <h2 className='font-semibold'>邮件趋势</h2>
              <p className='text-sm text-muted-foreground'>
                正常接收、隔离与 SMTP 拒绝事件
              </p>
            </div>
            <div className='h-72'>
              <ResponsiveContainer width='100%' height='100%'>
                <LineChart data={data?.trend ?? []}>
                  <CartesianGrid strokeDasharray='3 3' vertical={false} />
                  <XAxis dataKey='label' tickLine={false} axisLine={false} />
                  <YAxis
                    allowDecimals={false}
                    tickLine={false}
                    axisLine={false}
                    tickFormatter={formatCompactNumber}
                  />
                  <Tooltip
                    formatter={(value) =>
                      formatCompactNumber(Number(value ?? 0))
                    }
                  />
                  <Legend />
                  <Line
                    type='monotone'
                    dataKey='received'
                    name='正常接收'
                    stroke='#10b981'
                    strokeWidth={2}
                  />
                  <Line
                    type='monotone'
                    dataKey='quarantined'
                    name='隔离'
                    stroke='#f59e0b'
                    strokeWidth={2}
                  />
                  <Line
                    type='monotone'
                    dataKey='rejected'
                    name='SMTP 拒绝'
                    stroke='#ef4444'
                    strokeWidth={2}
                  />
                </LineChart>
              </ResponsiveContainer>
            </div>
          </div>
          <div className='space-y-5 border-t pt-5 xl:border-t-0 xl:border-l xl:pt-0 xl:pl-6'>
            <div>
              <h2 className='font-semibold'>安全结果分布</h2>
              <p className='text-sm text-muted-foreground'>
                当前时间范围内的认证与风险
              </p>
            </div>
            {Object.entries(data?.security ?? {}).map(([name, values]) => (
              <Distribution
                key={name}
                title={name.toUpperCase()}
                values={values}
              />
            ))}
          </div>
        </section>

        <section className='grid gap-6 xl:grid-cols-[minmax(0,1.35fr)_minmax(0,1fr)]'>
          <div className='min-w-0 space-y-4'>
            <div>
              <h2 className='font-semibold'>运行健康</h2>
              <p className='text-sm text-muted-foreground'>
                禁用、启动中与故障状态分别展示
              </p>
            </div>
            <div className='divide-y border-y'>
              {data?.health.map((item) => (
                <div
                  key={item.name}
                  className='flex items-center justify-between gap-4 py-3'
                >
                  <div className='flex items-center gap-3'>
                    <Database className='size-4 text-muted-foreground' />
                    <div>
                      <div className='text-sm font-medium'>{item.name}</div>
                      <div className='text-xs text-muted-foreground'>
                        {item.detail ||
                          (item.last_success_at
                            ? `最近成功 ${formatDate(item.last_success_at)}`
                            : '-')}
                      </div>
                    </div>
                  </div>
                  <Badge
                    variant={
                      item.status === 'fault'
                        ? 'destructive'
                        : item.status === 'disabled'
                          ? 'secondary'
                          : 'outline'
                    }
                  >
                    {formatStatusLabel(item.status)}
                  </Badge>
                </div>
              ))}
            </div>
          </div>
          <div className='min-w-0 space-y-4'>
            <div>
              <h2 className='font-semibold'>风险队列</h2>
              <p className='text-sm text-muted-foreground'>
                最近需要后台处理的邮件
              </p>
            </div>
            <div className='divide-y border-y'>
              {data?.risk_queue.map((item) => (
                <Link
                  key={item.id}
                  to='/quarantine'
                  className='block py-3 hover:bg-muted/30'
                >
                  <div className='flex items-start justify-between gap-3'>
                    <div className='min-w-0'>
                      <div className='truncate text-sm font-medium'>
                        {item.title}
                      </div>
                      <div className='truncate text-xs text-muted-foreground'>
                        {item.detail}
                      </div>
                    </div>
                    <span className='shrink-0 text-xs text-muted-foreground'>
                      {formatDate(item.created_at)}
                    </span>
                  </div>
                </Link>
              ))}
              {data?.risk_queue.length === 0 && (
                <p className='py-6 text-center text-sm text-muted-foreground'>
                  当前没有待处理风险
                </p>
              )}
            </div>
          </div>
        </section>

        <section className='grid gap-6 border-y py-6 md:grid-cols-3'>
          <TopList title='收件量最高邮箱' items={data?.top.recipients ?? []} />
          <TopList title='发件域' items={data?.top.sender_domains ?? []} />
          <TopList title='来源 IP' items={data?.top.source_ips ?? []} />
        </section>

        <section className='space-y-4'>
          <div className='flex items-end justify-between'>
            <div>
              <h2 className='font-semibold'>最近管理员操作</h2>
              <p className='text-sm text-muted-foreground'>
                治理动作和受控访问记录
              </p>
            </div>
            <Link
              to='/audit-logs'
              className='text-sm text-primary hover:underline'
            >
              查看全部
            </Link>
          </div>
          <div className='divide-y border-y'>
            {data?.recent_actions.map((item) => (
              <div
                key={item.id}
                className='grid gap-1 py-3 text-sm md:grid-cols-[180px_1fr_220px]'
              >
                <span className='font-medium'>
                  {formatAuditEventLabel(item.event_type)}
                </span>
                <span className='text-muted-foreground'>
                  {formatAuditActionLabel(item.action)} ·{' '}
                  {formatTargetTypeLabel(item.target_type)}{' '}
                  {item.target_id || ''}
                  {item.reason ? ` · ${formatAdminText(item.reason)}` : ''}
                </span>
                <span className='flex items-center gap-1 text-xs text-muted-foreground md:justify-end'>
                  <Clock3 className='size-3' />
                  {formatDate(item.created_at)}
                </span>
              </div>
            ))}
          </div>
        </section>
        <p className='text-right text-xs text-muted-foreground'>
          数据生成时间 {formatDate(data?.generated_at)} · 每 60 秒自动刷新
        </p>
      </Main>
    </>
  )
}
