import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import DisabledPersonSelector from '../../src/components/DisabledPersonSelector';
import { disabilityClientManager } from '../../src/api/disabilityClient';
import type { DisabledPersonData } from '../../src/api/types';

// 完整的mock响应对象
const createMockResponse = (status: number, data?: any) => ({
  status,
  ok: status >= 200 && status < 300,
  body: null,
  bodyUsed: false,
  statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
  headers: new Headers(),
  url: '',
  redirected: false,
  type: 'basic' as ResponseType,
  json: async () => data || {},
  text: async () => '',
  blob: async () => new Blob(),
  arrayBuffer: async () => new ArrayBuffer(0),
  formData: async () => new FormData(),
  clone: function() { return this; }
});

// Mock API client
vi.mock('../../src/api/disabilityClient', () => {
  const mockDisabilityClient = {
    searchDisabledPersons: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
        data: [
          {
            id: 1,
            name: '张三',
            gender: '男',
            idCard: '110101199001011234',
            disabilityId: 'CJZ20240001',
            disabilityType: '视力残疾',
            disabilityLevel: '一级',
            idAddress: '北京市东城区',
            phone: '13800138000',
            province: '北京市',
            city: '北京市',
            district: '东城区',
            isInBlackList: 0,
            createTime: '2024-01-01T00:00:00Z',
            updateTime: '2024-01-01T00:00:00Z'
          },
          {
            id: 2,
            name: '李四',
            gender: '女',
            idCard: '110101199001011235',
            disabilityId: 'CJZ20240002',
            disabilityType: '听力残疾',
            disabilityLevel: '二级',
            idAddress: '上海市黄浦区',
            phone: '13800138001',
            province: '上海市',
            city: '上海市',
            district: '黄浦区',
            isInBlackList: 1, // 黑名单人员
            createTime: '2024-01-01T00:00:00Z',
            updateTime: '2024-01-01T00:00:00Z'
          }
        ],
        total: 2
      })))
    },
    getAllDisabledPersons: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
        data: [
          {
            id: 3,
            name: '王五',
            gender: '男',
            idCard: '110101199001011236',
            disabilityId: 'CJZ20240003',
            disabilityType: '肢体残疾',
            disabilityLevel: '三级',
            idAddress: '广州市天河区',
            phone: '13800138002',
            province: '广东省',
            city: '广州市',
            district: '天河区',
            isInBlackList: 0,
            createTime: '2024-01-01T00:00:00Z',
            updateTime: '2024-01-01T00:00:00Z'
          }
        ],
        total: 1
      })))
    }
  };

  const mockClientManager = {
    get: vi.fn(() => mockDisabilityClient),
    init: vi.fn(() => mockDisabilityClient),
    reset: vi.fn(),
    getInstance: vi.fn(() => mockClientManager)
  };

  return {
    disabilityClientManager: mockClientManager,
    disabilityClient: mockDisabilityClient
  };
});

// Mock AreaSelect组件
vi.mock('@d8d/area-management-ui', () => ({
  AreaSelect: ({ value, onChange, placeholder }: any) => (
    <div data-testid="area-select">
      <select
        value={value?.provinceId || ''}
        onChange={(e) => onChange({ provinceId: e.target.value ? Number(e.target.value) : undefined })}
        data-testid="area-select-input"
      >
        <option value="">{placeholder || '选择地区'}</option>
        <option value="1">北京市</option>
        <option value="2">上海市</option>
      </select>
    </div>
  )
}));

// Mock shared-ui-components
vi.mock('@d8d/shared-ui-components/components/ui/dialog', () => ({
  Dialog: ({ children, open, onOpenChange }: any) => open ? (
    <div data-testid="dialog">{children}</div>
  ) : null,
  DialogContent: ({ children, className }: any) => (
    <div data-testid="dialog-content" className={className}>{children}</div>
  ),
  DialogHeader: ({ children }: any) => (
    <div data-testid="dialog-header">{children}</div>
  ),
  DialogTitle: ({ children }: any) => (
    <h2 data-testid="dialog-title">{children}</h2>
  ),
  DialogFooter: ({ children, className }: any) => (
    <div data-testid="dialog-footer" className={className}>{children}</div>
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/button', () => ({
  Button: ({ children, onClick, disabled, variant, ...props }: any) => (
    <button
      onClick={onClick}
      disabled={disabled}
      data-testid={props['data-testid'] || 'button'}
      data-variant={variant}
      {...props}
    >
      {children}
    </button>
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/input', () => ({
  Input: ({ value, onChange, placeholder, ...props }: any) => (
    <input
      type="text"
      value={value}
      onChange={onChange}
      placeholder={placeholder}
      data-testid={props['data-testid'] || 'input'}
      {...props}
    />
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/select', () => ({
  Select: ({ children }: any) => (
    <div data-testid="select">
      {children}
    </div>
  ),
  SelectTrigger: ({ children }: any) => (
    <div data-testid="select-trigger">{children}</div>
  ),
  SelectValue: ({ placeholder }: any) => (
    <span data-testid="select-value">{placeholder}</span>
  ),
  SelectContent: ({ children }: any) => (
    <div data-testid="select-content">{children}</div>
  ),
  SelectItem: ({ children, value }: any) => (
    <option value={value} data-testid={`select-item-${value}`}>{children}</option>
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/label', () => ({
  Label: ({ children, htmlFor }: any) => (
    <label htmlFor={htmlFor} data-testid="label">{children}</label>
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/table', () => ({
  Table: ({ children, ...props }: any) => (
    <table data-testid={props['data-testid'] || 'table'}>{children}</table>
  ),
  TableHeader: ({ children }: any) => <thead data-testid="table-header">{children}</thead>,
  TableBody: ({ children }: any) => <tbody data-testid="table-body">{children}</tbody>,
  TableRow: ({ children, onClick, className, ...props }: any) => (
    <tr onClick={onClick} className={className} data-testid={props['data-testid'] || 'table-row'}>{children}</tr>
  ),
  TableHead: ({ children, className }: any) => <th className={className}>{children}</th>,
  TableCell: ({ children }: any) => <td>{children}</td>,
}));

vi.mock('@d8d/shared-ui-components/components/admin/DataTablePagination', () => ({
  DataTablePagination: ({ currentPage, pageSize, totalCount, onPageChange, ...props }: any) => (
    <div data-testid={props['data-testid'] || 'pagination'}>
      <button onClick={() => onPageChange(currentPage - 1, pageSize)} data-testid="prev-page">上一页</button>
      <span>第{currentPage}页，共{Math.ceil(totalCount / pageSize)}页</span>
      <button onClick={() => onPageChange(currentPage + 1, pageSize)} data-testid="next-page">下一页</button>
    </div>
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/checkbox', () => ({
  Checkbox: ({ checked, onCheckedChange, disabled, ...props }: any) => (
    <input
      type="checkbox"
      checked={checked}
      onChange={(e) => onCheckedChange && onCheckedChange(e.target.checked)}
      disabled={disabled}
      data-testid={props['data-testid'] || 'checkbox'}
      {...props}
    />
  )
}));

vi.mock('@d8d/shared-ui-components/components/ui/alert', () => ({
  Alert: ({ children, variant }: any) => (
    <div data-testid="alert" data-variant={variant}>{children}</div>
  ),
  AlertDescription: ({ children }: any) => (
    <div data-testid="alert-description">{children}</div>
  )
}));

vi.mock('lucide-react', () => ({
  AlertCircle: () => <div data-testid="alert-circle">⚠️</div>
}));

describe('DisabledPersonSelector', () => {
  let queryClient: QueryClient;
  let onOpenChange: ReturnType<typeof vi.fn>;
  let onSelect: ReturnType<typeof vi.fn>;

  beforeEach(() => {
    queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    });
    onOpenChange = vi.fn();
    onSelect = vi.fn();
    vi.clearAllMocks();
  });

  const renderComponent = (props = {}) => {
    return render(
      <QueryClientProvider client={queryClient}>
        <DisabledPersonSelector
          open={true}
          onOpenChange={onOpenChange}
          onSelect={onSelect}
          {...props}
        />
      </QueryClientProvider>
    );
  };

  it('应该渲染对话框和搜索区域', () => {
    renderComponent();

    expect(screen.getByTestId('dialog')).toBeInTheDocument();
    expect(screen.getByTestId('dialog-title')).toHaveTextContent('选择残疾人');

    // 检查搜索字段
    expect(screen.getByTestId('search-name-input')).toBeInTheDocument();
    expect(screen.getByTestId('area-select')).toBeInTheDocument();
    expect(screen.getByTestId('search-button')).toBeInTheDocument();
    expect(screen.getByTestId('reset-button')).toBeInTheDocument();
  });

  it('应该显示残疾人列表', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByTestId('data-table')).toBeInTheDocument();
    });

    // 检查表格数据
    expect(screen.getByText('张三')).toBeInTheDocument();
    expect(screen.getByText('男')).toBeInTheDocument();
    expect(screen.getByText('110101199001011234')).toBeInTheDocument();
  });

  it('应该处理搜索功能', async () => {
    renderComponent();

    // 输入搜索关键词
    const searchInput = screen.getByTestId('search-name-input');
    fireEvent.change(searchInput, { target: { value: '张三' } });

    // 点击搜索按钮
    const searchButton = screen.getByTestId('search-button');
    fireEvent.click(searchButton);

    // 验证搜索API被调用
    await waitFor(() => {
      expect(disabilityClientManager.get().searchDisabledPersons.$get).toHaveBeenCalledWith({
        query: {
          keyword: '张三',
          skip: 0,
          take: 10
        }
      });
    });
  });

  it('应该处理重置搜索', () => {
    renderComponent();

    // 输入搜索关键词
    const searchInput = screen.getByTestId('search-name-input');
    fireEvent.change(searchInput, { target: { value: '张三' } });

    // 点击重置按钮
    const resetButton = screen.getByTestId('reset-button');
    fireEvent.click(resetButton);

    // 验证搜索输入被清空
    expect(searchInput).toHaveValue('');
  });

  it('应该处理单选模式', async () => {
    renderComponent({ mode: 'single' });

    await waitFor(() => {
      expect(screen.getByTestId('data-table')).toBeInTheDocument();
    });

    // 点击表格行选择人员
    const firstRow = screen.getByTestId('table-row-0');
    fireEvent.click(firstRow);

    // 验证选择回调被调用
    expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({
      id: 1,
      name: '张三'
    }));
    expect(onOpenChange).toHaveBeenCalledWith(false);
  });

  it('应该处理多选模式', async () => {
    renderComponent({ mode: 'multiple' });

    await waitFor(() => {
      expect(screen.getByTestId('data-table')).toBeInTheDocument();
    });

    // 应该显示多选相关的UI
    expect(screen.getAllByTestId('checkbox')).toHaveLength(3); // 全选复选框 + 每行复选框

    // 点击确认批量选择按钮（初始时禁用）
    const confirmButton = screen.getByTestId('confirm-batch-button');
    expect(confirmButton).toBeDisabled();
  });

  it('应该处理黑名单人员确认', async () => {
    renderComponent({ mode: 'single' });

    await waitFor(() => {
      expect(screen.getByTestId('data-table')).toBeInTheDocument();
    });

    // 点击黑名单人员（李四）
    const blacklistRow = screen.getByTestId('table-row-1');
    fireEvent.click(blacklistRow);

    // 应该显示黑名单确认对话框
    await waitFor(() => {
      expect(screen.getByTestId('alert')).toBeInTheDocument();
      expect(screen.getByTestId('alert-description')).toHaveTextContent('您选择的人员在黑名单中，是否确认选择？');
    });

    // 点击确认选择
    const confirmButton = screen.getByTestId('confirm-blacklist-button');
    fireEvent.click(confirmButton);

    // 验证选择回调被调用
    expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({
      id: 2,
      name: '李四',
      isInBlackList: 1
    }));
    expect(onOpenChange).toHaveBeenCalledWith(false);
  });

  it('应该处理禁用的人员', async () => {
    renderComponent({
      mode: 'single',
      disabledIds: [1] // 禁用张三
    });

    await waitFor(() => {
      expect(screen.getByTestId('data-table')).toBeInTheDocument();
    });

    // 点击禁用的人员应该没有反应
    const disabledRow = screen.getByTestId('table-row-0');
    fireEvent.click(disabledRow);

    expect(onSelect).not.toHaveBeenCalled();
  });

  it('应该处理分页', async () => {
    renderComponent();

    await waitFor(() => {
      expect(screen.getByTestId('pagination')).toBeInTheDocument();
    });

    // 点击下一页
    const nextPageButton = screen.getByTestId('next-page');
    fireEvent.click(nextPageButton);

    // 验证API被调用（第2页）
    await waitFor(() => {
      expect(disabilityClientManager.get().getAllDisabledPersons.$get).toHaveBeenCalledWith({
        query: {
          skip: 10,
          take: 10
        }
      });
    });
  });

  it('应该处理对话框关闭', () => {
    renderComponent();

    // 点击取消按钮
    const cancelButton = screen.getByTestId('cancel-button');
    fireEvent.click(cancelButton);

    expect(onOpenChange).toHaveBeenCalledWith(false);
  });
});