import { useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Coins, ShieldBan } from 'lucide-react'
import { toast } from 'sonner'
import { formatStatusLabel } 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,
  DialogDescription,
  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 { ReasonDialog } from '@/features/governance/reason-dialog'
import {
  FilterBar,
  formatDate,
  GovernanceShell,
  GovernanceTable,
  type PageData,
  Pagination,
  useUrlFilters,
} from '@/features/governance/shared'

interface AdminUser {
  id: string
  email: string
  role: 'user' | 'admin'
  status: 'active' | 'suspended' | 'banned'
  is_current: boolean
  mailbox_count: number
  email_count: number
  credit_balance: number
  credit_total_granted: number
  credit_total_consumed: number
  created_at: string
}

type UserAction = 'activate' | 'suspend' | 'ban'

export function Users() {
  const queryClient = useQueryClient()
  const { filters, update } = useUrlFilters({
    page: '1',
    page_size: '20',
    q: '',
    role: 'all',
    status: 'all',
  })
  const [selected, setSelected] = useState<Array<string | number>>([])
  const [bulkAction, setBulkAction] = useState<UserAction | null>(null)
  const [creditUser, setCreditUser] = useState<AdminUser | null>(null)
  const [creditDelta, setCreditDelta] = useState('')
  const [creditReason, setCreditReason] = useState('')
  const params = {
    ...filters,
    role: filters.role === 'all' ? undefined : filters.role,
    status: filters.status === 'all' ? undefined : filters.status,
  }
  const users = useQuery({
    queryKey: ['admin', 'users', params],
    queryFn: async () => {
      const response = await api.get<ApiResponse<PageData<AdminUser>>>(
        '/admin/users',
        { params }
      )
      return response.data.data
    },
  })
  const updateRole = useMutation({
    mutationFn: async ({ id, role }: { id: string; role: string }) => {
      await api.patch(`/admin/users/${id}`, { role })
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] })
      toast.success('角色已更新')
    },
  })
  const bulk = useMutation({
    mutationFn: async (reason: string) => {
      await api.post('/admin/users/bulk-actions', {
        ids: selected.map(String),
        action: bulkAction,
        reason,
      })
    },
    onSuccess: async () => {
      setBulkAction(null)
      setSelected([])
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] })
      toast.success('用户状态处置已完成')
    },
    onError: () => toast.error('部分或全部用户处置失败'),
  })
  const adjustCredit = useMutation({
    mutationFn: async () => {
      if (!creditUser) return
      await api.post('/admin/credits/adjust', {
        user_id: creditUser.id,
        delta: Number.parseInt(creditDelta, 10),
        reason: creditReason,
      })
    },
    onSuccess: async () => {
      setCreditUser(null)
      setCreditDelta('')
      setCreditReason('')
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] })
      toast.success('积分已调整')
    },
    onError: () => toast.error('积分调整失败'),
  })
  const data = users.data
  const parsedDelta = Number.parseInt(creditDelta, 10)

  return (
    <GovernanceShell
      title='用户管理'
      description='检索账号资源、积分与状态；当前管理员不可修改自身角色或状态。'
    >
      <FilterBar
        value={filters.q}
        placeholder='搜索邮箱或用户 ID'
        onChange={(value) => update('q', value)}
        onRefresh={() => users.refetch()}
        refreshing={users.isFetching}
      >
        <Select
          value={filters.role}
          onValueChange={(value) => update('role', value)}
        >
          <SelectTrigger className='w-full md:w-32'>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value='all'>全部角色</SelectItem>
            <SelectItem value='admin'>管理员</SelectItem>
            <SelectItem value='user'>普通用户</SelectItem>
          </SelectContent>
        </Select>
        <Select
          value={filters.status}
          onValueChange={(value) => update('status', value)}
        >
          <SelectTrigger className='w-full md:w-32'>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value='all'>全部状态</SelectItem>
            <SelectItem value='active'>正常</SelectItem>
            <SelectItem value='suspended'>暂停</SelectItem>
            <SelectItem value='banned'>封禁</SelectItem>
          </SelectContent>
        </Select>
        {selected.length > 0 && (
          <div className='flex gap-2'>
            <Button variant='outline' onClick={() => setBulkAction('activate')}>
              恢复
            </Button>
            <Button variant='outline' onClick={() => setBulkAction('suspend')}>
              <ShieldBan />
              暂停
            </Button>
            <Button variant='destructive' onClick={() => setBulkAction('ban')}>
              <ShieldBan />
              封禁
            </Button>
          </div>
        )}
      </FilterBar>
      <GovernanceTable
        data={data?.items ?? []}
        selected={selected}
        onSelectedChange={(ids) =>
          setSelected(
            ids.filter(
              (id) => !data?.items.find((user) => user.id === id)?.is_current
            )
          )
        }
        loading={users.isPending}
        columns={[
          {
            key: 'user',
            label: '用户',
            mobile: true,
            render: (user) => (
              <div className='max-w-72'>
                <div className='flex items-center gap-2'>
                  <span className='truncate font-medium'>{user.email}</span>
                  {user.is_current && (
                    <Badge variant='secondary'>当前账号</Badge>
                  )}
                </div>
                <div className='truncate text-xs text-muted-foreground'>
                  {user.id}
                </div>
              </div>
            ),
          },
          {
            key: 'role',
            label: '角色',
            mobile: true,
            render: (user) => (
              <Select
                value={user.role}
                disabled={user.is_current || updateRole.isPending}
                onValueChange={(role) =>
                  updateRole.mutate({ id: user.id, role })
                }
              >
                <SelectTrigger
                  className='w-28'
                  onClick={(event) => event.stopPropagation()}
                >
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value='user'>普通用户</SelectItem>
                  <SelectItem value='admin'>管理员</SelectItem>
                </SelectContent>
              </Select>
            ),
          },
          {
            key: 'status',
            label: '状态',
            render: (user) => (
              <Badge variant='outline'>{formatStatusLabel(user.status)}</Badge>
            ),
          },
          {
            key: 'resources',
            label: '资源',
            render: (user) =>
              `${user.mailbox_count} 邮箱 / ${user.email_count} 邮件`,
          },
          {
            key: 'credits',
            label: '积分',
            render: (user) => (
              <div>
                <div className='font-medium'>{user.credit_balance}</div>
                <div className='text-xs text-muted-foreground'>
                  +{user.credit_total_granted} / -{user.credit_total_consumed}
                </div>
              </div>
            ),
          },
          {
            key: 'created',
            label: '注册时间',
            render: (user) => formatDate(user.created_at),
          },
          {
            key: 'actions',
            label: '',
            className: 'text-right',
            render: (user) => (
              <Button
                size='icon'
                variant='ghost'
                title='调整积分'
                onClick={() => setCreditUser(user)}
              >
                <Coins />
              </Button>
            ),
          },
        ]}
      />
      <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))}
      />
      <ReasonDialog
        open={bulkAction !== null}
        title={
          bulkAction === 'activate'
            ? '恢复所选用户'
            : bulkAction === 'ban'
              ? '封禁所选用户'
              : '暂停所选用户'
        }
        description={`将对 ${selected.length} 个用户执行状态变更；当前登录账号会被后端拒绝。`}
        confirmLabel='确认执行'
        pending={bulk.isPending}
        onOpenChange={(open) => !open && setBulkAction(null)}
        onConfirm={(reason) => bulk.mutate(reason)}
      />
      <Dialog
        open={creditUser !== null}
        onOpenChange={(open) => !open && setCreditUser(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>调整用户积分</DialogTitle>
            <DialogDescription>{creditUser?.email}</DialogDescription>
          </DialogHeader>
          <div className='space-y-4'>
            <div className='space-y-2'>
              <Label htmlFor='credit-delta'>变化值</Label>
              <Input
                id='credit-delta'
                type='number'
                value={creditDelta}
                placeholder='正数增加，负数扣减'
                onChange={(event) => setCreditDelta(event.target.value)}
              />
            </div>
            <div className='space-y-2'>
              <Label htmlFor='credit-reason'>调整原因</Label>
              <Input
                id='credit-reason'
                maxLength={200}
                value={creditReason}
                onChange={(event) => setCreditReason(event.target.value)}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant='outline' onClick={() => setCreditUser(null)}>
              取消
            </Button>
            <Button
              disabled={
                !Number.isFinite(parsedDelta) ||
                parsedDelta === 0 ||
                !creditReason.trim() ||
                adjustCredit.isPending
              }
              onClick={() => adjustCredit.mutate()}
            >
              确认调整
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </GovernanceShell>
  )
}
