import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { PhotoUploadField } from '../../src/components/PhotoUploadField';
import { toast } from 'sonner';

// Mock toast
vi.mock('sonner', () => ({
  toast: {
    warning: vi.fn(),
    success: vi.fn(),
    error: vi.fn(),
  },
}));

// Mock FileSelector
vi.mock('@d8d/file-management-ui/components', () => ({
  FileSelector: ({ value, onChange, accept, filterType, placeholder, showPreview, previewSize }: any) => (
    <div data-testid="file-selector">
      <button
        data-testid="file-selector-button"
        onClick={() => onChange?.(123)}
      >
        {placeholder || '选择文件'}
      </button>
      <div data-testid="file-selector-accept">{accept}</div>
      <div data-testid="file-selector-filter-type">{filterType}</div>
      <div data-testid="file-selector-preview">{showPreview ? 'show' : 'hide'}</div>
      <div data-testid="file-selector-preview-size">{previewSize}</div>
    </div>
  ),
}));

describe('PhotoUploadField', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  const defaultProps = {
    value: [],
    onChange: vi.fn(),
    photoTypes: ['身份证照片', '残疾证照片', '个人照片', '其他照片'],
  };

  it('应该正确渲染组件', () => {
    render(<PhotoUploadField {...defaultProps} />);

    expect(screen.getByText('照片上传')).toBeInTheDocument();
    expect(screen.getByTestId('add-photo-button')).toBeInTheDocument();
    expect(screen.getByText('暂无照片')).toBeInTheDocument();
    expect(screen.getByText('点击"添加照片"按钮上传照片')).toBeInTheDocument();
  });

  it('应该添加照片', () => {
    render(<PhotoUploadField {...defaultProps} />);

    const addButton = screen.getByTestId('add-photo-button');
    fireEvent.click(addButton);

    expect(defaultProps.onChange).toHaveBeenCalledWith([
      expect.objectContaining({
        photoType: '身份证照片',
        fileId: null,
        canDownload: 0,
      })
    ]);
  });

  it('应该添加多张照片（无限制）', () => {
    render(<PhotoUploadField {...defaultProps} />);

    const addButton = screen.getByTestId('add-photo-button');

    // 添加5张照片（原来限制是5张）
    for (let i = 0; i < 5; i++) {
      fireEvent.click(addButton);
    }

    // 应该可以添加超过5张照片
    fireEvent.click(addButton);

    expect(defaultProps.onChange).toHaveBeenCalledTimes(6);
  });

  it('应该支持自定义最大照片数量', async () => {
    render(<PhotoUploadField {...defaultProps} maxPhotos={3} />);

    const addButton = screen.getByTestId('add-photo-button');

    // 添加3张照片
    for (let i = 0; i < 3; i++) {
      fireEvent.click(addButton);
    }

    // 第3张照片添加后，按钮应该被禁用
    expect(addButton).toBeDisabled();

    // 尝试添加第4张照片（按钮被禁用，不会触发事件）
    fireEvent.click(addButton);

    // toast.warning不应该被调用，因为按钮被禁用
    expect(toast.warning).not.toHaveBeenCalled();
  });

  it('应该移除照片', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
        tempId: 'temp-1',
      },
      {
        photoType: '残疾证照片',
        fileId: 456,
        canDownload: 0,
        tempId: 'temp-2',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    // 找到并点击第一个删除按钮
    const firstDeleteButton = screen.getByTestId('remove-photo-button-0');
    fireEvent.click(firstDeleteButton);

    expect(defaultProps.onChange).toHaveBeenCalledWith([
      expect.objectContaining({
        photoType: '残疾证照片',
        fileId: 456,
        canDownload: 0,
      })
    ]);
  });

  it('应该更新照片类型', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    // 找到选择器并更改值
    const selectTrigger = screen.getByText('身份证照片');
    fireEvent.click(selectTrigger);

    // 选择新类型
    const newTypeOption = screen.getByText('残疾证照片');
    fireEvent.click(newTypeOption);

    expect(defaultProps.onChange).toHaveBeenCalledWith([
      expect.objectContaining({
        photoType: '残疾证照片',
        fileId: 123,
        canDownload: 1,
      })
    ]);
  });

  it('应该更新文件ID', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: null,
        canDownload: 1,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    // 点击文件选择器按钮
    const fileSelectorButton = screen.getByTestId('file-selector-button');
    fireEvent.click(fileSelectorButton);

    expect(defaultProps.onChange).toHaveBeenCalledWith([
      expect.objectContaining({
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
      })
    ]);
  });

  it('应该更新下载权限', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 0,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    // 找到开关并切换
    const switchElement = screen.getByRole('switch');
    fireEvent.click(switchElement);

    expect(defaultProps.onChange).toHaveBeenCalledWith([
      expect.objectContaining({
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
      })
    ]);
  });

  it('应该显示正确的文件格式和大小限制提示', () => {
    render(<PhotoUploadField {...defaultProps} />);

    // 检查文本是否存在，使用包含匹配
    expect(screen.getByText(/支持的照片格式：JPG、JPEG、PNG、GIF、BMP、WebP等常见图片格式/)).toBeInTheDocument();
    expect(screen.getByText(/文件大小限制：无限制（建议不超过500MB）/)).toBeInTheDocument();
  });

  it('应该使用正确的文件选择器配置', () => {
    render(<PhotoUploadField {...defaultProps} />);

    // 添加一张照片以显示文件选择器
    const addButton = screen.getByTestId('add-photo-button');
    fireEvent.click(addButton);

    expect(screen.getByTestId('file-selector-accept')).toHaveTextContent('image/*,.jpg,.jpeg,.png,.gif,.bmp,.webp');
    expect(screen.getByTestId('file-selector-filter-type')).toHaveTextContent('all');
    expect(screen.getByTestId('file-selector-preview')).toHaveTextContent('show');
    expect(screen.getByTestId('file-selector-preview-size')).toHaveTextContent('medium');
  });

  it('应该显示照片类型标签（无星号）', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    // 检查照片类型标签没有星号
    const photoTypeLabel = screen.getByText('照片类型');
    expect(photoTypeLabel).toBeInTheDocument();
    expect(photoTypeLabel.innerHTML).not.toContain('*');
  });

  it('应该显示照片文件标签（无星号）', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    // 检查照片文件标签没有星号
    const photoFileLabel = screen.getByText('照片文件');
    expect(photoFileLabel).toBeInTheDocument();
    expect(photoFileLabel.innerHTML).not.toContain('*');
  });

  it('应该显示添加更多照片按钮（无数量限制时）', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} />);

    expect(screen.getByText('添加更多照片')).toBeInTheDocument();
  });

  it('应该显示添加更多照片按钮（有数量限制时）', () => {
    const initialValue = [
      {
        photoType: '身份证照片',
        fileId: 123,
        canDownload: 1,
        tempId: 'temp-1',
      },
    ];

    render(<PhotoUploadField {...defaultProps} value={initialValue} maxPhotos={5} />);

    expect(screen.getByText('添加更多照片（1/5）')).toBeInTheDocument();
  });
});