import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { AreaSelect } from '../../src/components/areas/composite/AreaSelect';

// Mock API 调用 - 注意：新的组件使用相对路径导入api
vi.mock('../../src/api/areaClient', () => ({
  areaClientManager: {
    get: vi.fn(() => ({
      index: {
        $get: vi.fn(async ({ query }) => {
          const filters = JSON.parse(query.filters);

          if (filters.level === 1) {
            // 省份数据
            return {
              status: 200,
              json: async () => ({
                data: [
                  { id: 1, name: '北京市', level: 1, parentId: null },
                  { id: 2, name: '上海市', level: 1, parentId: null }
                ]
              })
            };
          } else if (filters.level === 2 && filters.parentId === 1) {
            // 北京市的城市数据
            return {
              status: 200,
              json: async () => ({
                data: [
                  { id: 3, name: '北京市', level: 2, parentId: 1 }
                ]
              })
            };
          } else if (filters.level === 2 && filters.parentId === 2) {
            // 上海市的城市数据
            return {
              status: 200,
              json: async () => ({
                data: [
                  { id: 4, name: '上海市', level: 2, parentId: 2 }
                ]
              })
            };
          } else if (filters.level === 3 && filters.parentId === 3) {
            // 北京市的区县数据
            return {
              status: 200,
              json: async () => ({
                data: [
                  { id: 5, name: '东城区', level: 3, parentId: 3 },
                  { id: 6, name: '西城区', level: 3, parentId: 3 }
                ]
              })
            };
          } else if (filters.level === 3 && filters.parentId === 4) {
            // 上海市的区县数据
            return {
              status: 200,
              json: async () => ({
                data: [
                  { id: 7, name: '黄浦区', level: 3, parentId: 4 },
                  { id: 8, name: '徐汇区', level: 3, parentId: 4 }
                ]
              })
            };
          }

          return {
            status: 200,
            json: async () => ({ data: [] })
          };
        })
      }
    }))
  }
}));

// 创建测试用的 QueryClient
const createTestQueryClient = () => new QueryClient({
  defaultOptions: {
    queries: {
      retry: false,
    },
  },
});

// 测试组件包装器
const TestWrapper = ({ children }: { children: React.ReactNode }) => {
  return (
    <QueryClientProvider client={createTestQueryClient()}>
      {children}
    </QueryClientProvider>
  );
};

describe('AreaSelect 集成测试', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('应该正确渲染 AreaSelect 组件', async () => {
    render(
      <TestWrapper>
        <AreaSelect />
      </TestWrapper>
    );

    // 等待省份数据加载 - AreaSelect 显示的是"选择所在省份"
    await waitFor(() => {
      expect(screen.getByText('选择所在省份')).toBeInTheDocument();
    });

    expect(screen.getByText('省份')).toBeInTheDocument();
    expect(screen.getByText('城市')).toBeInTheDocument();
    expect(screen.getByText('区县')).toBeInTheDocument();
  });

  it('应该显示必填标记当 required=true 时', async () => {
    render(
      <TestWrapper>
        <AreaSelect required={true} />
      </TestWrapper>
    );

    // 等待省份数据加载 - AreaSelect 显示的是"选择所在省份"
    await waitFor(() => {
      expect(screen.getByText('选择所在省份')).toBeInTheDocument();
    });

    // 检查省份标签是否包含星号
    const provinceLabel = screen.getByText('省份');
    expect(provinceLabel.innerHTML).toContain('*');

    // 城市和区县不应该显示星号（初始状态）
    const cityLabel = screen.getByText('城市');
    expect(cityLabel.innerHTML).not.toContain('*');

    const districtLabel = screen.getByText('区县');
    expect(districtLabel.innerHTML).not.toContain('*');
  });

  it('应该正确处理省份选择并加载城市数据', async () => {
    const user = userEvent.setup();
    const handleChange = vi.fn();

    render(
      <TestWrapper>
        <AreaSelect onChange={handleChange} />
      </TestWrapper>
    );

    // 使用test ID查找省份选择框
    const provinceSelect = screen.getByTestId('area-select-province');
    // 等待省份数据加载并启用
    await waitFor(() => {
      expect(provinceSelect).toBeInTheDocument();
      expect(provinceSelect).not.toHaveAttribute('disabled');
    });

    await user.click(provinceSelect);

    // 选择北京市 - 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const hiddenSelect = screen.getByTestId('area-select-province').parentElement?.querySelector('select[aria-hidden="true"]');
    if (hiddenSelect) {
      await user.selectOptions(hiddenSelect, '1');
      // 触发change事件
      fireEvent.change(hiddenSelect, { target: { value: '1' } });
    }

    // 验证onChange被调用
    expect(handleChange).toHaveBeenCalledWith({
      provinceId: 1,
      cityId: undefined,
      districtId: undefined
    });

    // 验证城市选择框应该被启用（因为选择了省份）
    const citySelect = screen.getByTestId('area-select-city');
    expect(citySelect).toBeInTheDocument();
  });

  it('应该正确处理城市选择并加载区县数据', async () => {
    const user = userEvent.setup();
    const handleChange = vi.fn();

    render(
      <TestWrapper>
        <AreaSelect onChange={handleChange} />
      </TestWrapper>
    );

    // 先选择省份（北京市）
    const provinceSelect = screen.getByTestId('area-select-province');
    // 等待省份数据加载并启用
    await waitFor(() => {
      expect(provinceSelect).toBeInTheDocument();
      expect(provinceSelect).not.toHaveAttribute('disabled');
    });

    await user.click(provinceSelect);
    await waitFor(() => {
      expect(screen.getByText('北京市')).toBeInTheDocument();
    });
    await user.click(screen.getByText('北京市'));

    // 等待城市数据加载并启用
    const citySelect = screen.getByTestId('area-select-city');
    await waitFor(() => {
      expect(citySelect).toBeInTheDocument();
      expect(citySelect).not.toHaveAttribute('disabled');
    }, { timeout: 2000 });

    // 点击城市选择框
    await user.click(citySelect);

    // 选择北京市（城市）- 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const cityHiddenSelect = screen.getByTestId('area-select-city').parentElement?.querySelector('select[aria-hidden="true"]');
    if (cityHiddenSelect) {
      await user.selectOptions(cityHiddenSelect, '3');
    }

    // 验证onChange被调用
    expect(handleChange).toHaveBeenCalledWith({
      provinceId: 1,
      cityId: 3,
      districtId: undefined
    });

    // 验证区县选择框应该被启用（因为选择了城市）
    const districtSelect = screen.getByTestId('area-select-district');
    expect(districtSelect).toBeInTheDocument();
  });

  it('应该正确处理区县选择', async () => {
    const user = userEvent.setup();
    const handleChange = vi.fn();

    render(
      <TestWrapper>
        <AreaSelect onChange={handleChange} />
      </TestWrapper>
    );

    // 先选择省份（北京市）
    const provinceSelect = screen.getByTestId('area-select-province');
    // 等待省份数据加载并启用
    await waitFor(() => {
      expect(provinceSelect).toBeInTheDocument();
      expect(provinceSelect).not.toHaveAttribute('disabled');
    });

    await user.click(provinceSelect);

    // 选择北京市 - 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const provinceHiddenSelect = screen.getByTestId('area-select-province').parentElement?.querySelector('select[aria-hidden="true"]');
    if (provinceHiddenSelect) {
      await user.selectOptions(provinceHiddenSelect, '1');
    }

    // 等待城市数据加载并启用
    const citySelect = screen.getByTestId('area-select-city');
    await waitFor(() => {
      expect(citySelect).toBeInTheDocument();
      expect(citySelect).not.toHaveAttribute('disabled');
    }, { timeout: 2000 });

    await user.click(citySelect);

    // 选择北京市（城市）- 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const cityHiddenSelect = screen.getByTestId('area-select-city').parentElement?.querySelector('select[aria-hidden="true"]');
    if (cityHiddenSelect) {
      await user.selectOptions(cityHiddenSelect, '3');
    }

    // 等待区县数据加载并启用
    const districtSelect = screen.getByTestId('area-select-district');
    await waitFor(() => {
      expect(districtSelect).toBeInTheDocument();
      expect(districtSelect).not.toHaveAttribute('disabled');
    }, { timeout: 2000 });

    // 点击区县选择框
    await user.click(districtSelect);

    // 选择东城区 - 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const districtHiddenSelect = screen.getByTestId('area-select-district').parentElement?.querySelector('select[aria-hidden="true"]');
    if (districtHiddenSelect) {
      await user.selectOptions(districtHiddenSelect, '5');
    }

    // 验证onChange被调用
    expect(handleChange).toHaveBeenCalledWith({
      provinceId: 1,
      cityId: 3,
      districtId: 5
    });
  });

  it('应该支持禁用状态', async () => {
    render(
      <TestWrapper>
        <AreaSelect disabled={true} />
      </TestWrapper>
    );

    // 等待省份数据加载 - AreaSelect 显示的是"选择所在省份"
    await waitFor(() => {
      expect(screen.getByText('选择所在省份')).toBeInTheDocument();
    });

    // 检查组件渲染正常
    expect(screen.getByText('省份')).toBeInTheDocument();
    expect(screen.getByText('城市')).toBeInTheDocument();
    expect(screen.getByText('区县')).toBeInTheDocument();
  });

  it('应该正确处理初始值', async () => {
    const initialValue = {
      provinceId: 1,
      cityId: 3,
      districtId: 5
    };

    render(
      <TestWrapper>
        <AreaSelect value={initialValue} />
      </TestWrapper>
    );

    // 等待省份数据加载 - AreaSelect 显示的是"选择所在省份"
    await waitFor(() => {
      expect(screen.getByText('选择所在省份')).toBeInTheDocument();
    });

    // 组件应该能正常渲染，初始值会在组件内部处理
    expect(screen.getByText('省份')).toBeInTheDocument();
    expect(screen.getByText('城市')).toBeInTheDocument();
    expect(screen.getByText('区县')).toBeInTheDocument();
  });

  it('当选择新省份时应该清空城市和区县选择', async () => {
    const user = userEvent.setup();
    const handleChange = vi.fn();

    render(
      <TestWrapper>
        <AreaSelect onChange={handleChange} />
      </TestWrapper>
    );

    // 先选择省份（北京市）
    const provinceSelect = screen.getByTestId('area-select-province');
    // 等待省份数据加载并启用
    await waitFor(() => {
      expect(provinceSelect).toBeInTheDocument();
      expect(provinceSelect).not.toHaveAttribute('disabled');
    });

    await user.click(provinceSelect);

    // 选择北京市 - 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const provinceHiddenSelect = screen.getByTestId('area-select-province').parentElement?.querySelector('select[aria-hidden="true"]');
    if (provinceHiddenSelect) {
      await user.selectOptions(provinceHiddenSelect, '1');
    }

    // 等待城市数据加载并启用
    const citySelect = screen.getByTestId('area-select-city');
    await waitFor(() => {
      expect(citySelect).toBeInTheDocument();
      expect(citySelect).not.toHaveAttribute('disabled');
    }, { timeout: 2000 });

    await user.click(citySelect);

    // 选择北京市（城市）- 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const cityHiddenSelect = screen.getByTestId('area-select-city').parentElement?.querySelector('select[aria-hidden="true"]');
    if (cityHiddenSelect) {
      await user.selectOptions(cityHiddenSelect, '3');
    }

    // 等待区县数据加载并启用
    const districtSelect = screen.getByTestId('area-select-district');
    await waitFor(() => {
      expect(districtSelect).toBeInTheDocument();
      expect(districtSelect).not.toHaveAttribute('disabled');
    }, { timeout: 2000 });

    await user.click(districtSelect);

    // 选择东城区 - 尝试直接设置隐藏的select元素的值
    // 查找隐藏的select元素
    const districtHiddenSelect = screen.getByTestId('area-select-district').parentElement?.querySelector('select[aria-hidden="true"]');
    if (districtHiddenSelect) {
      await user.selectOptions(districtHiddenSelect, '5');
    }

    // 验证已经选择了完整的省市区
    expect(handleChange).toHaveBeenLastCalledWith({
      provinceId: 1,
      cityId: 3,
      districtId: 5
    });

    // 现在选择新的省份（上海市）
    await user.click(screen.getByTestId('area-select-province')); // 重新打开省份选择
    await waitFor(() => {
      expect(screen.getByText('上海市')).toBeInTheDocument();
    });
    await user.click(screen.getByText('上海市'));

    // 验证onChange被调用，城市和区县被清空
    expect(handleChange).toHaveBeenLastCalledWith({
      provinceId: 2,
      cityId: undefined,
      districtId: undefined
    });

    // 验证城市选择框应该显示"选择城市"（被清空）
    expect(screen.getByTestId('area-select-city')).toBeInTheDocument();
    // 验证区县选择框应该显示"选择区县"（被清空）
    expect(screen.getByTestId('area-select-district')).toBeInTheDocument();
  });
});