import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { vi } from 'vitest';
import { toast } from 'sonner';
import { BatchSpecCreator } from '../../src/components/BatchSpecCreator';

// Mock the goodsClientManager
vi.mock('../../src/api/goodsClient', () => ({
  goodsClientManager: {
    get: vi.fn(() => ({
      index: {
        $post: vi.fn(() => Promise.resolve({
          status: 201,
          json: () => Promise.resolve({ id: 100, name: '父商品 - 规格1' })
        }))
      }
    }))
  }
}));

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

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      retry: false,
    },
    mutations: {
      retry: false,
    },
  },
});

const Wrapper = ({ children }: { children: React.ReactNode }) => (
  <QueryClientProvider client={queryClient}>
    {children}
  </QueryClientProvider>
);

describe('BatchSpecCreator', () => {
  const defaultProps = {
    parentGoodsId: 1,
    parentGoodsName: '父商品',
    onSuccess: vi.fn(),
    onCancel: vi.fn()
  };

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

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

    expect(screen.getByText('批量创建子商品规格')).toBeInTheDocument();
    expect(screen.getByText('为父商品 "父商品" 批量创建多个子商品规格')).toBeInTheDocument();
    expect(screen.getByText('父商品信息')).toBeInTheDocument();
    expect(screen.getByText('规格列表')).toBeInTheDocument();
    expect(screen.getByDisplayValue('1')).toBeInTheDocument(); // 父商品ID
    expect(screen.getByDisplayValue('父商品')).toBeInTheDocument(); // 父商品名称
  });

  it('应该显示初始的2个规格行', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    expect(nameInputs).toHaveLength(2);

    const priceInputs = screen.getAllByPlaceholderText('0.00');
    expect(priceInputs).toHaveLength(4); // 2个规格 * 2个价格字段

    const stockInputs = screen.getAllByPlaceholderText('0');
    expect(stockInputs).toHaveLength(2);
  });

  it('应该添加新的规格行', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    const addButton = screen.getByText('添加规格');
    fireEvent.click(addButton);

    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    expect(nameInputs).toHaveLength(3);
  });

  it('应该删除规格行', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    const deleteButtons = screen.getAllByRole('button', { name: '' });
    fireEvent.click(deleteButtons[0]); // 删除第一个规格

    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    expect(nameInputs).toHaveLength(1);
  });

  it('不能删除最后一个规格行', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    // 先删除一个
    const deleteButtons = screen.getAllByRole('button', { name: '' });
    fireEvent.click(deleteButtons[0]);

    // 尝试删除最后一个
    const remainingDeleteButton = screen.getByRole('button', { name: '' });
    fireEvent.click(remainingDeleteButton);

    // 应该仍然有一个规格
    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    expect(nameInputs).toHaveLength(1);
    expect(toast.error).toHaveBeenCalledWith('至少需要保留一个规格');
  });

  it('应该更新规格字段', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    const nameInput = screen.getAllByPlaceholderText('例如：红色、64GB、大号')[0];
    fireEvent.change(nameInput, { target: { value: '红色' } });
    expect(nameInput).toHaveValue('红色');

    const priceInput = screen.getAllByPlaceholderText('0.00')[0];
    fireEvent.change(priceInput, { target: { value: '99.99' } });
    expect(priceInput).toHaveValue(99.99);

    const stockInput = screen.getAllByPlaceholderText('0')[0];
    fireEvent.change(stockInput, { target: { value: '50' } });
    expect(stockInput).toHaveValue(50);
  });

  it('应该验证规格名称不能为空', async () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    const submitButton = screen.getByText('创建 2 个子商品');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith('规格 1 的名称不能为空');
    });
  });

  it('应该验证规格名称不能重复', async () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    // 设置两个规格为相同的名称
    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    fireEvent.change(nameInputs[0], { target: { value: '红色' } });
    fireEvent.change(nameInputs[1], { target: { value: '红色' } });

    // 设置价格和库存
    const priceInputs = screen.getAllByPlaceholderText('0.00');
    fireEvent.change(priceInputs[0], { target: { value: '100' } });
    fireEvent.change(priceInputs[2], { target: { value: '200' } });

    const stockInputs = screen.getAllByPlaceholderText('0');
    fireEvent.change(stockInputs[0], { target: { value: '10' } });
    fireEvent.change(stockInputs[1], { target: { value: '20' } });

    const submitButton = screen.getByText('创建 2 个子商品');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith('规格名称不能重复');
    });
  });

  it('应该验证价格不能为负数', async () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    // 设置规格名称
    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    fireEvent.change(nameInputs[0], { target: { value: '红色' } });

    // 设置负价格
    const priceInputs = screen.getAllByPlaceholderText('0.00');
    fireEvent.change(priceInputs[0], { target: { value: '-100' } });

    const submitButton = screen.getByText('创建 2 个子商品');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith('规格 红色 的价格不能为负数');
    });
  });

  it('应该成功提交表单', async () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    // 设置第一个规格
    const nameInputs = screen.getAllByPlaceholderText('例如：红色、64GB、大号');
    fireEvent.change(nameInputs[0], { target: { value: '红色' } });
    fireEvent.change(nameInputs[1], { target: { value: '蓝色' } });

    // 设置价格
    const priceInputs = screen.getAllByPlaceholderText('0.00');
    fireEvent.change(priceInputs[0], { target: { value: '100' } });
    fireEvent.change(priceInputs[2], { target: { value: '200' } });

    // 设置库存
    const stockInputs = screen.getAllByPlaceholderText('0');
    fireEvent.change(stockInputs[0], { target: { value: '10' } });
    fireEvent.change(stockInputs[1], { target: { value: '20' } });

    const submitButton = screen.getByText('创建 2 个子商品');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(toast.success).toHaveBeenCalledWith('批量创建子商品成功');
      expect(defaultProps.onSuccess).toHaveBeenCalled();
    });
  });

  it('应该处理取消操作', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} />
      </Wrapper>
    );

    const cancelButton = screen.getByText('取消');
    fireEvent.click(cancelButton);

    expect(defaultProps.onCancel).toHaveBeenCalled();
  });

  it('应该显示租户信息', () => {
    render(
      <Wrapper>
        <BatchSpecCreator {...defaultProps} tenantId={123} />
      </Wrapper>
    );

    expect(screen.getByText('• 所有子商品将自动关联到父商品（spuId = 1）')).toBeInTheDocument();
  });
});