import { useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Plus, Trash2 } from 'lucide-react'
import { toast } from 'sonner'
import {
  formatAdminText,
  formatBlacklistKindLabel,
  formatSourceLabel,
} from '@/lib/admin-labels'
import { api, type ApiResponse } from '@/lib/api'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { ReasonDialog } from './reason-dialog'
import {
  FilterBar,
  formatDate,
  GovernanceShell,
  GovernanceTable,
  type PageData,
  Pagination,
  useUrlFilters,
} from './shared'

interface SenderBlock {
  id: number
  kind: string
  value: string
  reason: string
  source: string
  active: boolean
  expires_at?: string
  created_at: string
}

interface IpBlock {
  id: number
  ip: string
  reason: string
  source: string
  active: boolean
  expires_at?: string
  created_at: string
}

export function BlacklistsPage() {
  const queryClient = useQueryClient()
  const { filters, update } = useUrlFilters({
    page: '1',
    page_size: '20',
    q: '',
    tab: 'senders',
    active: 'true',
  })
  const [selected, setSelected] = useState<Array<string | number>>([])
  const [removeOpen, setRemoveOpen] = useState(false)
  const [addOpen, setAddOpen] = useState(false)
  const [kind, setKind] = useState('address')
  const [value, setValue] = useState('')
  const [reason, setReason] = useState('')
  const endpoint =
    filters.tab === 'ips'
      ? '/admin/blacklists/ips'
      : '/admin/blacklists/senders'
  const query = useQuery({
    queryKey: ['admin', 'blacklists', endpoint, filters],
    queryFn: async () => {
      const response = await api.get<
        ApiResponse<PageData<SenderBlock | IpBlock>>
      >(endpoint, { params: filters })
      return response.data.data
    },
  })
  const add = useMutation({
    mutationFn: async () => {
      await api.post(endpoint, {
        ...(filters.tab === 'senders' ? { kind, value } : { ip: value }),
        reason,
      })
    },
    onSuccess: async () => {
      setAddOpen(false)
      setValue('')
      setReason('')
      await queryClient.invalidateQueries({ queryKey: ['admin', 'blacklists'] })
      toast.success('黑名单已生效')
    },
    onError: () => toast.error('新增黑名单失败'),
  })
  const remove = useMutation({
    mutationFn: async (operationReason: string) => {
      await api.post(`${endpoint}/bulk-actions`, {
        ids: selected.map(Number),
        action: 'remove',
        reason: operationReason,
      })
    },
    onSuccess: async () => {
      setRemoveOpen(false)
      setSelected([])
      await queryClient.invalidateQueries({ queryKey: ['admin', 'blacklists'] })
      toast.success('黑名单已解除')
    },
    onError: () => toast.error('解除黑名单失败'),
  })
  const data = query.data

  return (
    <GovernanceShell
      title='黑名单'
      description='治理发件地址、域名和来源 IP，区分人工、自动与过期记录。'
      actions={
        <Button onClick={() => setAddOpen(true)}>
          <Plus />
          新增封禁
        </Button>
      }
    >
      <Tabs
        value={filters.tab}
        onValueChange={(tab) => {
          setSelected([])
          update('tab', tab)
        }}
      >
        <TabsList>
          <TabsTrigger value='senders'>发件人 / 域</TabsTrigger>
          <TabsTrigger value='ips'>来源 IP</TabsTrigger>
        </TabsList>
      </Tabs>
      <FilterBar
        value={filters.q}
        placeholder={
          filters.tab === 'ips' ? '搜索 IP 或原因' : '搜索地址、域或原因'
        }
        onChange={(search) => update('q', search)}
        onRefresh={() => query.refetch()}
        refreshing={query.isFetching}
      >
        {selected.length > 0 && (
          <Button variant='destructive' onClick={() => setRemoveOpen(true)}>
            <Trash2 />
            解除 {selected.length} 项
          </Button>
        )}
      </FilterBar>
      <GovernanceTable
        data={
          (data?.items ?? []) as Array<(SenderBlock | IpBlock) & { id: number }>
        }
        selected={selected}
        onSelectedChange={setSelected}
        loading={query.isPending}
        columns={[
          {
            key: 'value',
            label: filters.tab === 'ips' ? 'IP' : '封禁值',
            mobile: true,
            render: (item) => (
              <div>
                <div className='font-medium'>
                  {'ip' in item ? item.ip : item.value}
                </div>
                {'kind' in item && (
                  <div className='text-xs text-muted-foreground'>
                    {formatBlacklistKindLabel(item.kind)}
                  </div>
                )}
              </div>
            ),
          },
          {
            key: 'reason',
            label: '原因',
            mobile: true,
            render: (item) => (
              <div className='max-w-80'>{formatAdminText(item.reason)}</div>
            ),
          },
          {
            key: 'source',
            label: '来源',
            render: (item) => (
              <Badge variant='outline'>{formatSourceLabel(item.source)}</Badge>
            ),
          },
          {
            key: 'status',
            label: '状态',
            render: (item) => (
              <Badge variant={item.active ? 'outline' : 'secondary'}>
                {item.active ? '生效中' : '已过期'}
              </Badge>
            ),
          },
          {
            key: 'expires',
            label: '到期时间',
            render: (item) =>
              item.expires_at ? formatDate(item.expires_at) : '永久',
          },
          {
            key: 'created',
            label: '创建时间',
            render: (item) => formatDate(item.created_at),
          },
        ]}
      />
      <Pagination
        page={data?.page ?? Number(filters.page)}
        pageSize={data?.page_size ?? 20}
        total={data?.total ?? 0}
        totalPages={data?.total_pages ?? 0}
        onPage={(page) => update('page', String(page))}
      />
      <Dialog open={addOpen} onOpenChange={setAddOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>新增封禁</DialogTitle>
          </DialogHeader>
          <div className='space-y-4'>
            {filters.tab === 'senders' && (
              <div className='space-y-2'>
                <Label>类型</Label>
                <Select value={kind} onValueChange={setKind}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value='address'>完整地址</SelectItem>
                    <SelectItem value='domain'>发件域</SelectItem>
                    <SelectItem value='pattern'>模式</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            )}
            <div className='space-y-2'>
              <Label htmlFor='block-value'>
                {filters.tab === 'ips' ? 'IP / CIDR' : '地址或域'}
              </Label>
              <Input
                id='block-value'
                value={value}
                onChange={(event) => setValue(event.target.value)}
              />
            </div>
            <div className='space-y-2'>
              <Label htmlFor='block-reason'>原因</Label>
              <Input
                id='block-reason'
                value={reason}
                maxLength={200}
                onChange={(event) => setReason(event.target.value)}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant='outline' onClick={() => setAddOpen(false)}>
              取消
            </Button>
            <Button
              disabled={!value.trim() || !reason.trim() || add.isPending}
              onClick={() => add.mutate()}
            >
              确认封禁
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <ReasonDialog
        open={removeOpen}
        title='解除所选黑名单'
        description={`将解除 ${selected.length} 项封禁，SMTP 流程将立即采用新状态。`}
        confirmLabel='确认解除'
        pending={remove.isPending}
        onOpenChange={setRemoveOpen}
        onConfirm={(operationReason) => remove.mutate(operationReason)}
      />
    </GovernanceShell>
  )
}
