import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { vi } from 'vitest';
import AttendanceModal from '../../src/components/AttendanceModal';

// Mock xlsx
vi.mock('xlsx', () => ({
  __esModule: true,
  default: {
    utils: {
      book_new: vi.fn(() => ({})),
      aoa_to_sheet: vi.fn(() => ({})),
      book_append_sheet: vi.fn(),
    },
    writeFile: vi.fn(),
  },
  utils: {
    book_new: vi.fn(() => ({})),
    aoa_to_sheet: vi.fn(() => ({})),
    book_append_sheet: vi.fn(),
  },
  writeFile: vi.fn(),
}));

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

describe('AttendanceModal', () => {
  const mockOrderPersons = [
    {
      personId: 1,
      personName: '张三',
      disabilityId: 'D001',
      disabilityType: '肢体残疾',
    },
    {
      personId: 2,
      personName: '李四',
      disabilityId: 'D002',
      disabilityType: '视力残疾',
    },
  ];

  const defaultProps = {
    open: true,
    onOpenChange: vi.fn(),
    orderId: 123,
    orderName: '测试订单',
    orderPersons: mockOrderPersons,
  };

  beforeEach(() => {
    vi.clearAllMocks();
  });

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

    expect(screen.getByTestId('attendance-modal')).toBeInTheDocument();
    expect(screen.getByTestId('attendance-modal-title')).toHaveTextContent('出勤表导出');
    expect(screen.getByText(/为订单"测试订单"生成月度出勤Excel表/)).toBeInTheDocument();
    expect(screen.getByTestId('attendance-month-select')).toBeInTheDocument();
    expect(screen.getByTestId('attendance-days-select')).toBeInTheDocument();
    expect(screen.getByTestId('attendance-generate-button')).toBeInTheDocument();
    expect(screen.getByTestId('attendance-cancel-button')).toBeInTheDocument();
  });

  it('应该显示订单信息', () => {
    render(<AttendanceModal {...defaultProps} />);

    expect(screen.getByText('订单名称:')).toBeInTheDocument();
    expect(screen.getByText('测试订单')).toBeInTheDocument();
    expect(screen.getByText('订单ID:')).toBeInTheDocument();
    expect(screen.getByText('123')).toBeInTheDocument();
    expect(screen.getByText('人员数量:')).toBeInTheDocument();
    expect(screen.getByText('2人')).toBeInTheDocument();
  });

  it('应该显示月份选择器', () => {
    render(<AttendanceModal {...defaultProps} />);

    const monthSelect = screen.getByTestId('attendance-month-select');
    expect(monthSelect).toBeInTheDocument();
    expect(screen.getByText('选择月份')).toBeInTheDocument();
  });

  it('应该显示出勤天数选择器', () => {
    render(<AttendanceModal {...defaultProps} />);

    const daysSelect = screen.getByTestId('attendance-days-select');
    expect(daysSelect).toBeInTheDocument();
    expect(screen.getByText('出勤天数')).toBeInTheDocument();
  });

  it('应该显示出勤表预览信息', () => {
    render(<AttendanceModal {...defaultProps} />);

    expect(screen.getByText('表格结构:')).toBeInTheDocument();
    expect(screen.getByText(/列: 姓名、残疾证号、残疾类型、1-20日、出勤天数、缺勤天数、备注/)).toBeInTheDocument();
    expect(screen.getByText(/行: 2名人员/)).toBeInTheDocument();
    expect(screen.getByText(/出勤标记: √ \(出勤\), 空白 \(缺勤\)/)).toBeInTheDocument();
    expect(screen.getByText(/文件格式: Excel \(\.xlsx\)/)).toBeInTheDocument();
  });

  it('应该在没有人员时禁用生成按钮', () => {
    const propsWithoutPersons = {
      ...defaultProps,
      orderPersons: [],
    };

    render(<AttendanceModal {...propsWithoutPersons} />);

    const generateButton = screen.getByTestId('attendance-generate-button');
    expect(generateButton).toBeDisabled();
  });

  it('应该在有人员时启用生成按钮', () => {
    render(<AttendanceModal {...defaultProps} />);

    const generateButton = screen.getByTestId('attendance-generate-button');
    expect(generateButton).toBeEnabled();
  });

  it('应该点击取消按钮关闭模态框', async () => {
    const user = userEvent.setup();
    const onOpenChange = vi.fn();
    render(<AttendanceModal {...defaultProps} onOpenChange={onOpenChange} />);

    const cancelButton = screen.getByTestId('attendance-cancel-button');
    await user.click(cancelButton);

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

  it('应该在没有人员时显示警告并阻止生成', async () => {
    const user = userEvent.setup();
    const propsWithoutPersons = {
      ...defaultProps,
      orderPersons: [],
    };

    const { toast } = await import('sonner');
    render(<AttendanceModal {...propsWithoutPersons} />);

    const form = screen.getByRole('form');
    fireEvent.submit(form);

    await waitFor(() => {
      expect(toast.warning).toHaveBeenCalledWith('订单中没有人员，无法生成出勤表');
    });
  });

  it('应该显示生成按钮', () => {
    render(<AttendanceModal {...defaultProps} />);

    const generateButton = screen.getByTestId('attendance-generate-button');
    expect(generateButton).toBeInTheDocument();
    expect(generateButton).toHaveTextContent('生成出勤表');
  });

  it('应该显示取消按钮', () => {
    render(<AttendanceModal {...defaultProps} />);

    const cancelButton = screen.getByTestId('attendance-cancel-button');
    expect(cancelButton).toBeInTheDocument();
    expect(cancelButton).toHaveTextContent('取消');
  });
});