import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
import { useForm, FormProvider } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { AreaSelectForm } from '../../src/components/AreaSelectForm';
import { Button } from '@d8d/shared-ui-components/components/ui/button';
import { Form } from '@d8d/shared-ui-components/components/ui/form';

// 测试用的schema
const TestSchema = z.object({
  province: z.string().min(1, '省份不能为空'),
  city: z.string().min(1, '城市不能为空'),
  district: z.string().optional(),
});

type TestFormData = z.infer<typeof TestSchema>;

// Mock AreaSelect 组件
vi.mock('../../src/components/AreaSelect', () => ({
  AreaSelect: vi.fn(({ value, onChange, disabled, required }) => {
    return (
      <div data-testid="area-select">
        <select
          data-testid="province-select"
          value={value?.provinceId || ''}
          onChange={(e) => {
            const newValue = {
              ...value,
              provinceId: e.target.value ? Number(e.target.value) : undefined,
            };
            onChange(newValue);
          }}
          disabled={disabled}
          // 移除 required 属性，让 react-hook-form 处理验证
        >
          <option value="">选择省份</option>
          <option value="1">北京市</option>
          <option value="2">上海市</option>
        </select>
        <select
          data-testid="city-select"
          value={value?.cityId || ''}
          onChange={(e) => {
            const newValue = {
              ...value,
              cityId: e.target.value ? Number(e.target.value) : undefined,
            };
            onChange(newValue);
          }}
          disabled={disabled}
          // 移除 required 属性，让 react-hook-form 处理验证
        >
          <option value="">选择城市</option>
          <option value="3">北京市</option>
          <option value="4">上海市</option>
        </select>
        <select
          data-testid="district-select"
          value={value?.districtId || ''}
          onChange={(e) => {
            const newValue = {
              ...value,
              districtId: e.target.value ? Number(e.target.value) : undefined,
            };
            onChange(newValue);
          }}
          disabled={disabled}
        >
          <option value="">选择区县</option>
          <option value="5">东城区</option>
          <option value="6">黄浦区</option>
        </select>
      </div>
    );
  }),
}));

// 测试组件
const TestForm = () => {
  const form = useForm<TestFormData>({
    resolver: zodResolver(TestSchema),
    defaultValues: {
      province: '',
      city: '',
      district: '',
    },
    mode: 'onSubmit', // 使用onSubmit模式，这是默认值
  });

  const onSubmit = vi.fn();

  return (
    <FormProvider {...form}>
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)}>
          <AreaSelectForm<TestFormData>
            provinceName="province"
            cityName="city"
            districtName="district"
            label="地区选择"
            required={true}
            control={form.control}
          />
          <Button type="submit" data-testid="submit-button">
            提交
          </Button>
        </form>
      </Form>
    </FormProvider>
  );
};

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

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

    expect(screen.getByText('地区选择')).toBeInTheDocument();
    // 检查是否包含必填标记（星号）
    const label = screen.getByText('地区选择');
    expect(label.parentElement).toContainHTML('*');
    expect(screen.getByTestId('area-select')).toBeInTheDocument();
  });

  it('应该显示省份和城市的验证错误当表单提交时', async () => {
    let formRef: any;
    const TestFormWithRef = () => {
      const form = useForm<TestFormData>({
        resolver: zodResolver(TestSchema),
        defaultValues: {
          province: '',
          city: '',
          district: '',
        },
        mode: 'onSubmit',
      });

      formRef = form;

      const onSubmit = vi.fn();

      return (
        <FormProvider {...form}>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)}>
              <AreaSelectForm<TestFormData>
                provinceName="province"
                cityName="city"
                districtName="district"
                label="地区选择"
                required={true}
                control={form.control}
              />
              <Button type="submit" data-testid="submit-button">
                提交
              </Button>
            </form>
          </Form>
        </FormProvider>
      );
    };

    render(<TestFormWithRef />);

    // 初始状态不应该有验证错误
    expect(screen.queryByText('省份不能为空')).not.toBeInTheDocument();
    expect(screen.queryByText('城市不能为空')).not.toBeInTheDocument();

    // 提交表单（不选择任何省份和城市）
    const submitButton = screen.getByTestId('submit-button');
    await act(async () => {
      fireEvent.click(submitButton);
    });

    // 等待一下，让验证完成
    await new Promise(resolve => setTimeout(resolve, 100));

    // 等待验证错误显示
    await waitFor(() => {
      expect(screen.getByText('省份不能为空')).toBeInTheDocument();
      expect(screen.getByText('城市不能为空')).toBeInTheDocument();
    }, { timeout: 3000 });
  });

  it('应该正确更新表单字段值当选择省份和城市时', async () => {
    render(<TestForm />);

    // 选择省份
    const provinceSelect = screen.getByTestId('province-select');
    fireEvent.change(provinceSelect, { target: { value: '1' } });

    // 选择城市
    const citySelect = screen.getByTestId('city-select');
    fireEvent.change(citySelect, { target: { value: '3' } });

    // 提交表单
    const submitButton = screen.getByTestId('submit-button');
    fireEvent.click(submitButton);

    // 不应该有验证错误
    await waitFor(() => {
      expect(screen.queryByText('省份不能为空')).not.toBeInTheDocument();
      expect(screen.queryByText('城市不能为空')).not.toBeInTheDocument();
    });
  });

  it('应该显示验证错误当只选择省份不选择城市时', async () => {
    render(<TestForm />);

    // 只选择省份
    const provinceSelect = screen.getByTestId('province-select');
    fireEvent.change(provinceSelect, { target: { value: '1' } });

    // 提交表单
    const submitButton = screen.getByTestId('submit-button');
    fireEvent.click(submitButton);

    // 应该只有城市验证错误
    await waitFor(() => {
      expect(screen.queryByText('省份不能为空')).not.toBeInTheDocument();
      expect(screen.getByText('城市不能为空')).toBeInTheDocument();
    });
  });

  it('应该显示验证错误当只选择城市不选择省份时', async () => {
    render(<TestForm />);

    // 只选择城市
    const citySelect = screen.getByTestId('city-select');
    fireEvent.change(citySelect, { target: { value: '3' } });

    // 提交表单
    const submitButton = screen.getByTestId('submit-button');
    fireEvent.click(submitButton);

    // 应该只有省份验证错误
    await waitFor(() => {
      expect(screen.getByText('省份不能为空')).toBeInTheDocument();
      expect(screen.queryByText('城市不能为空')).not.toBeInTheDocument();
    });
  });

  it('应该正确处理区县字段（可选）', async () => {
    render(<TestForm />);

    // 选择省份和城市
    const provinceSelect = screen.getByTestId('province-select');
    const citySelect = screen.getByTestId('city-select');
    fireEvent.change(provinceSelect, { target: { value: '1' } });
    fireEvent.change(citySelect, { target: { value: '3' } });

    // 选择区县（可选）
    const districtSelect = screen.getByTestId('district-select');
    fireEvent.change(districtSelect, { target: { value: '5' } });

    // 提交表单
    const submitButton = screen.getByTestId('submit-button');
    fireEvent.click(submitButton);

    // 不应该有验证错误
    await waitFor(() => {
      expect(screen.queryByText('省份不能为空')).not.toBeInTheDocument();
      expect(screen.queryByText('城市不能为空')).not.toBeInTheDocument();
    });
  });

  it('应该支持禁用状态', () => {
    const DisabledTestForm = () => {
      const form = useForm<TestFormData>({
        resolver: zodResolver(TestSchema),
        defaultValues: {
          province: '',
          city: '',
          district: '',
        },
      });

      return (
        <FormProvider {...form}>
          <Form {...form}>
            <AreaSelectForm<TestFormData>
              provinceName="province"
              cityName="city"
              districtName="district"
              label="地区选择"
              required={true}
              disabled={true}
              control={form.control}
            />
          </Form>
        </FormProvider>
      );
    };

    render(<DisabledTestForm />);

    const provinceSelect = screen.getByTestId('province-select');
    const citySelect = screen.getByTestId('city-select');
    const districtSelect = screen.getByTestId('district-select');

    expect(provinceSelect).toBeDisabled();
    expect(citySelect).toBeDisabled();
    expect(districtSelect).toBeDisabled();
  });
});