import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@d8d/shared-ui-components/components/ui/dialog';
import { Button } from '@d8d/shared-ui-components/components/ui/button';
import { Input } from '@d8d/shared-ui-components/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@d8d/shared-ui-components/components/ui/select';
import { Label } from '@d8d/shared-ui-components/components/ui/label';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@d8d/shared-ui-components/components/ui/table';
import { DataTablePagination } from '@d8d/shared-ui-components/components/admin/DataTablePagination';
import { Checkbox } from '@d8d/shared-ui-components/components/ui/checkbox';
import { Alert, AlertDescription } from '@d8d/shared-ui-components/components/ui/alert';
import { AlertCircle } from 'lucide-react';
import { AreaSelect } from '@d8d/area-management-ui';
import { disabilityClientManager } from '../api/disabilityClient';
import type {
  DisabledPersonData,
  AreaSelection,
} from '../api/types';

// 黑名单状态常量
const BLACKLIST_STATUS = {
  IN_BLACKLIST: 1,
  NOT_IN_BLACKLIST: 0,
} as const;

// 默认分页配置
const DEFAULT_PAGINATION = {
  page: 1,
  pageSize: 10,
} as const;

// 输入验证最大长度
const MAX_LENGTH = {
  NAME: 50,
  DISABILITY_ID: 50,
  PHONE: 11,
} as const;

// 默认搜索参数
const createDefaultSearchParams = () => ({
  name: '',
  gender: '',
  disabilityId: '',
  phone: '',
  disabilityType: '',
  disabilityLevel: '',
  ...DEFAULT_PAGINATION,
});

// 残疾类型选项
const DISABILITY_TYPES = [
  '视力残疾',
  '听力残疾',
  '言语残疾',
  '肢体残疾',
  '智力残疾',
  '精神残疾',
  '多重残疾',
] as const;

// 残疾等级选项
const DISABILITY_LEVELS = ['一级', '二级', '三级', '四级'] as const;

// 表格列定义类型
type ColumnKey = 'name' | 'gender' | 'idCard' | 'disabilityId' | 'phone' | 'province' | 'city' | 'disabilityType' | 'disabilityLevel' | 'blacklist';

interface ColumnDef {
  key: ColumnKey;
  label: string;
}

/**
 * 身份证号脱敏处理
 * 只显示前6位和后4位，中间用****代替
 * @param idCard 身份证号
 * @returns 脱敏后的身份证号
 */
const maskIdCard = (idCard: string): string => {
  if (!idCard || idCard.length < 8) return idCard;
  return `${idCard.slice(0, 6)}****${idCard.slice(-4)}`;
};

// 搜索参数类型
interface SearchParams {
  name: string;
  gender: string;
  disabilityId: string;
  phone: string;
  disabilityType: string;
  disabilityLevel: string;
  page: number;
  pageSize: number;
}

interface DisabledPersonSelectorProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSelect: (person: DisabledPersonData | DisabledPersonData[]) => void;
  mode?: 'single' | 'multiple';
  disabledIds?: number[];
}

/**
 * 残疾人选择器组件
 *
 * 功能：
 * - 支持单选和多选模式
 * - 多字段组合搜索（姓名、性别、残疾证号、电话、残疾类型/等级、地区）
 * - 分页展示残疾人列表
 * - 黑名单人员二次确认
 * - 身份证号脱敏显示
 * - 响应式设计，支持移动端
 */
const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
  open,
  onOpenChange,
  onSelect,
  mode = 'single',
  disabledIds = [],
}) => {
  // 多字段搜索状态管理
  const [searchParams, setSearchParams] = useState<SearchParams>(createDefaultSearchParams);
  const [selectedPersons, setSelectedPersons] = useState<DisabledPersonData[]>([]);

  const [areaSelection, setAreaSelection] = useState<AreaSelection>({});
  // 用于搜索的地区名称
  const [searchAreaNames, setSearchAreaNames] = useState<{ province?: string; city?: string; district?: string }>({});
  const [showBlacklistConfirm, setShowBlacklistConfirm] = useState(false);
  const [pendingSelection, setPendingSelection] = useState<DisabledPersonData | DisabledPersonData[] | null>(null);

  // 搜索残疾人列表（添加错误处理）
  const { data, isLoading, error } = useQuery({
    queryKey: ['disabled-persons-search', searchParams, searchAreaNames],
    queryFn: async () => {
      // 组合多个搜索字段为keyword
      const searchFields = [
        searchParams.name,
        searchParams.gender,
        searchParams.disabilityId,
        searchParams.phone,
        searchParams.disabilityType,
        searchParams.disabilityLevel,
        searchAreaNames.province,
        searchAreaNames.city,
        searchAreaNames.district,
      ].filter(Boolean);

      const keyword = searchFields.join(' ').trim();

      const response = await disabilityClientManager.get().searchDisabledPersons.$get({
        query: {
          keyword: keyword || '',
          skip: ((searchParams.page || DEFAULT_PAGINATION.page) - 1) * (searchParams.pageSize || DEFAULT_PAGINATION.pageSize),
          take: searchParams.pageSize || DEFAULT_PAGINATION.pageSize,
        },
      });
      if (response.status !== 200) throw new Error('搜索残疾人失败');
      return await response.json();
    },
    enabled: open,
  });

  const personsData = data;
  const isLoadingData = isLoading;

  // 重置选择器状态（使用 useCallback 优化）
  useEffect(() => {
    if (!open) {
      setSearchParams(createDefaultSearchParams());
      setSelectedPersons([]);
      setAreaSelection({});
      setSearchAreaNames({});
      setShowBlacklistConfirm(false);
      setPendingSelection(null);
    }
  }, [open]);

  // 处理搜索（使用 useCallback 优化）
  const handleSearch = useCallback(() => {
    setSearchParams(prev => ({ ...prev, page: DEFAULT_PAGINATION.page }));
  }, []);

  // 处理重置搜索（使用 useCallback 优化）
  const handleResetSearch = useCallback(() => {
    setSearchParams(createDefaultSearchParams());
    setAreaSelection({});
    setSearchAreaNames({});
  }, []);

  // 处理选择人员（使用 useCallback 优化，使用函数式 setState 避免依赖 selectedPersons）
  const handleSelectPerson = useCallback((person: DisabledPersonData) => {
    if (disabledIds.includes(person.id)) {
      return; // 跳过禁用的人员
    }

    if (person.isInBlackList === BLACKLIST_STATUS.IN_BLACKLIST) {
      // 黑名单人员需要二次确认
      setPendingSelection(person);
      setShowBlacklistConfirm(true);
      return;
    }

    if (mode === 'single') {
      onSelect(person);
      onOpenChange(false);
    } else {
      // 使用函数式 setState，避免依赖 selectedPersons
      setSelectedPersons(prev => {
        const isSelected = prev.some(p => p.id === person.id);
        if (isSelected) {
          return prev.filter(p => p.id !== person.id);
        } else {
          return [...prev, person];
        }
      });
    }
  }, [disabledIds, mode, onSelect, onOpenChange]);

  // 处理批量选择（使用 useCallback 优化，使用函数式 setState 避免依赖 selectedPersons）
  const handleBatchSelect = useCallback(() => {
    // 使用函数式 setState 获取当前值，避免在依赖数组中包含 selectedPersons
    setSelectedPersons(currentPersons => {
      console.debug('[DisabledPersonSelector] handleBatchSelect 被调用, selectedPersons:', currentPersons.length);
      if (currentPersons.length === 0) {
        console.debug('[DisabledPersonSelector] 没有选中人员，返回');
        return currentPersons;
      }

      // 检查是否有黑名单人员
      const blacklistPersons = currentPersons.filter(p => p.isInBlackList === BLACKLIST_STATUS.IN_BLACKLIST);
      if (blacklistPersons.length > 0) {
        console.debug('[DisabledPersonSelector] 检测到黑名单人员');
        setPendingSelection(currentPersons);
        setShowBlacklistConfirm(true);
        return currentPersons;
      }

      console.debug('[DisabledPersonSelector] 调用 onSelect, 人员数量:', currentPersons.length);
      onSelect(currentPersons);
      onOpenChange(false);
      return currentPersons;
    });
  }, [onSelect, onOpenChange]);

  // 确认选择黑名单人员（使用 useCallback 优化）
  const handleConfirmBlacklistSelection = useCallback(() => {
    if (pendingSelection) {
      onSelect(pendingSelection);
      onOpenChange(false);
    }
    setShowBlacklistConfirm(false);
    setPendingSelection(null);
  }, [onSelect, onOpenChange, pendingSelection]);

  // 取消选择黑名单人员（使用 useCallback 优化）
  const handleCancelBlacklistSelection = useCallback(() => {
    setShowBlacklistConfirm(false);
    setPendingSelection(null);
  }, []);

  // 处理分页变化（使用 useCallback 优化）
  const handlePageChange = useCallback((page: number, pageSize: number) => {
    setSearchParams(prev => ({ ...prev, page, pageSize }));
  }, []);

  // 表格列定义（使用 useMemo 优化）
  const columns: ColumnDef[] = useMemo(() => [
    { key: 'name', label: '姓名' },
    { key: 'gender', label: '性别' },
    { key: 'idCard', label: '身份证号' },
    { key: 'disabilityId', label: '残疾证号' },
    { key: 'phone', label: '联系电话' },
    { key: 'province', label: '省份' },
    { key: 'city', label: '城市' },
    { key: 'disabilityType', label: '残疾类型' },
    { key: 'disabilityLevel', label: '残疾等级' },
    { key: 'blacklist', label: '黑名单' },
  ], []);

  return (
    <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent
          className="max-w-6xl max-h-[90vh] overflow-y-auto w-[95vw] sm:w-full"
          data-testid="disabled-person-selector-dialog"
        >
          <DialogHeader>
            <DialogTitle>选择残疾人</DialogTitle>
          </DialogHeader>

          {/* 搜索区域 - 响应式设计 */}
          <div className="space-y-4 p-4 border rounded-lg">
            {/* 第一行：基本信息搜索 - 响应式网格 */}
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
              <div className="space-y-2">
                <Label htmlFor="name">姓名</Label>
                <Input
                  id="name"
                  placeholder="输入姓名"
                  maxLength={MAX_LENGTH.NAME}
                  value={searchParams.name || ''}
                  onChange={(e) => setSearchParams(prev => ({ ...prev, name: e.target.value }))}
                  data-testid="search-name-input"
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="gender">性别</Label>
                <Select
                  value={searchParams.gender || ''}
                  onValueChange={(value) => {
                    setSearchParams(prev => ({ ...prev, gender: value }));
                  }}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="选择性别" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="男">男</SelectItem>
                    <SelectItem value="女">女</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label htmlFor="disabilityId">残疾证号</Label>
                <Input
                  id="disabilityId"
                  placeholder="输入残疾证号"
                  maxLength={MAX_LENGTH.DISABILITY_ID}
                  value={searchParams.disabilityId || ''}
                  onChange={(e) => setSearchParams(prev => ({ ...prev, disabilityId: e.target.value }))}
                  data-testid="search-disability-id-input"
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="phone">联系电话</Label>
                <Input
                  id="phone"
                  placeholder="输入联系电话"
                  maxLength={MAX_LENGTH.PHONE}
                  value={searchParams.phone || ''}
                  onChange={(e) => setSearchParams(prev => ({ ...prev, phone: e.target.value }))}
                  data-testid="search-phone-input"
                />
              </div>
            </div>

            {/* 第二行：区域选择器单独一行 */}
            <div className="space-y-2">
              <Label>省份/城市/区县</Label>
              <AreaSelect
                value={areaSelection}
                onChange={(value) => {
                  // 转换类型以确保类型兼容
                  setAreaSelection({
                    provinceId: typeof value.provinceId === 'number' ? value.provinceId : undefined,
                    cityId: typeof value.cityId === 'number' ? value.cityId : undefined,
                    districtId: typeof value.districtId === 'number' ? value.districtId : undefined,
                  });
                  // 同时更新用于搜索的地区名称
                  setSearchAreaNames({
                    province: value.provinceId?.toString(),
                    city: value.cityId?.toString(),
                    district: value.districtId?.toString(),
                  });
                }}
                data-testid="area-select"
              />
            </div>

            {/* 第三行：其他筛选条件和操作按钮 - 响应式网格 */}
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
              <div className="space-y-2">
                <Label htmlFor="disabilityType">残疾类型</Label>
                <Select
                  value={searchParams.disabilityType || ''}
                  onValueChange={(value) => {
                    setSearchParams(prev => ({ ...prev, disabilityType: value }));
                  }}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="选择残疾类型" />
                  </SelectTrigger>
                  <SelectContent>
                    {DISABILITY_TYPES.map(type => (
                      <SelectItem key={type} value={type}>{type}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label htmlFor="disabilityLevel">残疾等级</Label>
                <Select
                  value={searchParams.disabilityLevel || ''}
                  onValueChange={(value) => {
                    setSearchParams(prev => ({ ...prev, disabilityLevel: value }));
                  }}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="选择残疾等级" />
                  </SelectTrigger>
                  <SelectContent>
                    {DISABILITY_LEVELS.map(level => (
                      <SelectItem key={level} value={level}>{level}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              {/* 在移动端隐藏空列 */}
              <div className="hidden lg:block"></div>

              <div className="flex items-end space-x-2 sm:col-span-2 lg:col-span-1">
                <Button onClick={handleSearch} data-testid="search-button" className="flex-1 sm:flex-none">
                  搜索
                </Button>
                <Button variant="outline" onClick={handleResetSearch} data-testid="reset-button" className="flex-1 sm:flex-none">
                  重置
                </Button>
              </div>
            </div>
          </div>

          {/* 表格区域 */}
          {isLoadingData ? (
            <div className="flex items-center justify-center h-64">
              <div className="text-center">加载中...</div>
            </div>
          ) : error ? (
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>
                加载残疾人数据失败，请稍后重试
              </AlertDescription>
            </Alert>
          ) : personsData?.data && personsData.data.length > 0 ? (
            <>
              {/* 移动端提示 */}
              <div className="lg:hidden mb-2 text-sm text-muted-foreground">
                <p>提示：表格可以左右滑动查看所有列</p>
              </div>

              {/* 表格容器 - 支持水平和垂直滚动 */}
              <div className="border rounded-md overflow-auto max-h-[60vh]">
                <Table data-testid="disabled-persons-table" className="min-w-full">
                  <TableHeader>
                    <TableRow>
                      {mode === 'multiple' && (
                        <TableHead className="w-12 sticky left-0 bg-background z-10">
                          <Checkbox
                            checked={selectedPersons.length === personsData.data.length}
                            onCheckedChange={(checked) => {
                              if (checked) {
                                const selectablePersons = personsData.data.filter(
                                  (person: DisabledPersonData) => !disabledIds.includes(person.id)
                                );
                                setSelectedPersons(selectablePersons);
                              } else {
                                setSelectedPersons([]);
                              }
                            }}
                            aria-label="全选"
                            data-testid="select-all-checkbox"
                          />
                        </TableHead>
                      )}
                      {columns.map((column, index) => (
                        <TableHead
                          key={column.key}
                          className={`
                            ${index === 0 ? 'sticky left-0 bg-background z-10' : ''}
                            ${['province', 'city', 'disabilityType', 'disabilityLevel', 'blacklist'].includes(column.key) ? 'hidden lg:table-cell' : ''}
                          `}
                        >
                          {column.label}
                        </TableHead>
                      ))}
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {personsData.data.map((person: DisabledPersonData) => (
                      <TableRow
                        key={person.id}
                        onClick={() => mode === 'single' && handleSelectPerson(person)}
                        className={mode === 'single' ? 'cursor-pointer hover:bg-muted' : ''}
                        data-testid={`table-row-${person.id}`}
                      >
                        {mode === 'multiple' && (
                          <TableCell className="sticky left-0 bg-background z-10">
                            <Checkbox
                              checked={selectedPersons.some(p => p.id === person.id)}
                              onCheckedChange={(checked) => {
                                if (checked) {
                                  setSelectedPersons([...selectedPersons, person]);
                                } else {
                                  setSelectedPersons(selectedPersons.filter(p => p.id !== person.id));
                                }
                              }}
                              disabled={disabledIds.includes(person.id)}
                              aria-label="选择"
                              data-testid={`person-checkbox-${person.id}`}
                            />
                          </TableCell>
                        )}
                        <TableCell className="sticky left-0 bg-background z-10">{person.name}</TableCell>
                        <TableCell>{person.gender}</TableCell>
                        <TableCell>{maskIdCard(person.idCard)}</TableCell>
                        <TableCell>{person.disabilityId}</TableCell>
                        <TableCell>{person.phone}</TableCell>
                        <TableCell className="hidden lg:table-cell">{person.province}</TableCell>
                        <TableCell className="hidden lg:table-cell">{person.city}</TableCell>
                        <TableCell className="hidden lg:table-cell">{person.disabilityType}</TableCell>
                        <TableCell className="hidden lg:table-cell">{person.disabilityLevel}</TableCell>
                        <TableCell className="hidden lg:table-cell">{person.isInBlackList === BLACKLIST_STATUS.IN_BLACKLIST ? '是' : '否'}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>
              <DataTablePagination
                currentPage={searchParams.page || 1}
                pageSize={searchParams.pageSize || 10}
                totalCount={personsData.total || 0}
                onPageChange={handlePageChange}
                data-testid="pagination"
              />
            </>
          ) : (
            <div className="flex items-center justify-center h-64">
              <div className="text-center">暂无数据</div>
            </div>
          )}

          {/* 底部操作区域 */}
          <DialogFooter className="flex justify-between">
            <div className="text-sm text-muted-foreground">
              {mode === 'multiple' && (
                <span>已选择 {selectedPersons.length} 人</span>
              )}
            </div>
            <div className="space-x-2">
              <Button variant="outline" type="button" onClick={() => onOpenChange(false)} data-testid="cancel-button">
                取消
              </Button>
              {mode === 'multiple' && (
                <Button
                  type="button"
                  onClick={handleBatchSelect}
                  disabled={selectedPersons.length === 0}
                  data-testid="confirm-batch-button"
                >
                  确认选择 ({selectedPersons.length})
                </Button>
              )}
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 黑名单确认对话框 */}
      <Dialog open={showBlacklistConfirm} onOpenChange={setShowBlacklistConfirm}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>确认选择黑名单人员</DialogTitle>
          </DialogHeader>
          <Alert variant="destructive">
            <AlertCircle className="h-4 w-4" />
            <AlertDescription>
              您选择的人员在黑名单中，是否确认选择？
            </AlertDescription>
          </Alert>
          <DialogFooter>
            <Button variant="outline" onClick={handleCancelBlacklistSelection} data-testid="cancel-blacklist-button">
              取消
            </Button>
            <Button onClick={handleConfirmBlacklistSelection} data-testid="confirm-blacklist-button">
              确认选择
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
};

export default DisabledPersonSelector;