import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor, within } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { Hono } from 'hono';
import { GoodsManagement } from '../../src/components/GoodsManagement';
import { goodsClient, goodsClientManager } from '../../src/api/goodsClient';

// 完整的mock响应对象
const createMockResponse = (status: number, data?: any) => ({
  status,
  ok: status >= 200 && status < 300,
  body: null,
  bodyUsed: false,
  statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
  headers: new Headers(),
  url: '',
  redirected: false,
  type: 'basic' as ResponseType,
  json: async () => data || {},
  text: async () => '',
  blob: async () => new Blob(),
  arrayBuffer: async () => new ArrayBuffer(0),
  formData: async () => new FormData(),
  clone: function() { return this; }
});

// 创建模拟的rpcClient函数（根据API模拟规范）
// 符合测试策略文档的API模拟规范：统一模拟@d8d/shared-ui-components/utils/hc中的rpcClient函数
const mockRpcClient = vi.hoisted(() => vi.fn((aptBaseUrl: string) => {
  // 根据页面组件实际调用的RPC路径定义模拟端点
  // 符合规范：支持Hono风格的$get、$post、$put、$delete方法
  return {
    index: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200))),
      $post: vi.fn(() => Promise.resolve(createMockResponse(201))),
    },
    ':id': {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, { id: 1, spuId: 0, tenantId: 1 }))),
      $put: vi.fn(() => Promise.resolve(createMockResponse(200))),
      $delete: vi.fn(() => Promise.resolve(createMockResponse(204))), // 商品删除API，支持子商品删除
      // 故事006.002新增的父子商品管理API
      children: {
        $get: vi.fn(() => Promise.resolve(createMockResponse(200, { data: [], total: 0 }))),
      },
      'set-as-parent': {
        $post: vi.fn(() => Promise.resolve(createMockResponse(200))),
      },
      parent: {
        $delete: vi.fn(() => Promise.resolve(createMockResponse(200))),
      },
    },
    // 故事006.002新增的批量创建API
    batchCreateChildren: {
      $post: vi.fn(() => Promise.resolve(createMockResponse(200))),
    },
  };
}));

// 模拟共享UI组件包中的rpcClient函数（统一模拟点）
// 核心API模拟规范：统一拦截所有API调用，支持跨UI包集成测试
vi.mock('@d8d/shared-ui-components/utils/hc', () => ({
  rpcClient: mockRpcClient
}));

// Mock API client（保持向后兼容性，但实际使用上面的统一模拟）
// 符合API模拟规范：统一模拟rpcClient函数，客户端管理器使用模拟的rpcClient
vi.mock('../../src/api/goodsClient', () => {
  // 获取模拟的客户端实例（通过mockRpcClient创建）
  // 符合测试策略文档的规范：直接通过模拟的rpcClient函数创建客户端
  const mockClient = mockRpcClient('/');

  const mockGoodsClientManager = {
    get: vi.fn(() => mockClient),
  };

  return {
    goodsClientManager: mockGoodsClientManager,
    goodsClient: mockClient,
  };
});

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

// Mock 文件选择器组件
vi.mock('@d8d/file-management-ui-mt', () => ({
  FileSelector: ({ value, onChange, placeholder }: any) => (
    <button
      data-testid="file-selector"
      onClick={() => onChange?.(value || 1)}
    >
      {placeholder || '选择文件'}
    </button>
  ),
}));

// Mock 商品分类级联选择器
vi.mock('@d8d/goods-category-management-ui-mt/components', () => ({
  GoodsCategoryCascadeSelector: ({ required }: any) => (
    <div data-testid="goods-category-cascade-selector">
      商品分类选择器 {required && <span>*</span>}
    </div>
  ),
}));

// Mock 供应商选择器
vi.mock('@d8d/supplier-management-ui-mt/components', () => ({
  SupplierSelector: ({ value, onChange }: any) => (
    <select
      data-testid="supplier-selector"
      value={value || ''}
      onChange={(e) => onChange?.(e.target.value ? Number(e.target.value) : null)}
    >
      <option value="">选择供应商</option>
      <option value="1">供应商1</option>
      <option value="2">供应商2</option>
    </select>
  ),
}));

// Mock 商户选择器
vi.mock('@d8d/merchant-management-ui-mt/components', () => ({
  MerchantSelector: ({ value, onChange }: any) => (
    <select
      data-testid="merchant-selector"
      value={value || ''}
      onChange={(e) => onChange?.(e.target.value ? Number(e.target.value) : null)}
    >
      <option value="">选择商户</option>
      <option value="1">商户1</option>
      <option value="2">商户2</option>
    </select>
  ),
}));

// 注意：我们不mock GoodsParentChildPanel、ChildGoodsList和BatchSpecCreatorInline组件
// 让它们使用真实的实现，只模拟API请求

const createTestQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  });

const renderWithProviders = (component: React.ReactElement) => {
  const queryClient = createTestQueryClient();
  return render(
    <QueryClientProvider client={queryClient}>
      {component as any}
    </QueryClientProvider>
  );
};

describe('商品管理集成测试', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('应该完成完整的商品CRUD流程', async () => {
    const mockGoods = {
      data: [
        {
          id: 1,
          name: '测试商品',
          price: 99.99,
          costPrice: 50.00,
          categoryId1: 1,
          categoryId2: 2,
          categoryId3: 3,
          goodsType: 1,
          supplierId: 1,
          merchantId: 1,
          imageFileId: 1,
          slideImageIds: [1, 2],
          detail: '商品详情',
          instructions: '商品简介',
          sort: 0,
          state: 1,
          stock: 100,
          lowestBuy: 1,
          salesNum: 50,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
          createdBy: 1,
          updatedBy: 1,
          category1: { id: 1, name: '一级分类' },
          category2: { id: 2, name: '二级分类' },
          category3: { id: 3, name: '三级分类' },
          supplier: { id: 1, name: '供应商1' },
          merchant: { id: 1, name: '商户1', username: 'merchant1' },
          imageFile: { id: 1, fullUrl: 'http://example.com/image.jpg' },
          slideImages: [
            { id: 1, fullUrl: 'http://example.com/slide1.jpg' },
            { id: 2, fullUrl: 'http://example.com/slide2.jpg' }
          ],
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 10,
      },
    };

    const { toast } = await import('sonner');

    // Mock initial goods list
    (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

    renderWithProviders(<GoodsManagement />);

    // Wait for initial data to load
    await waitFor(() => {
      expect(screen.getByText('测试商品')).toBeInTheDocument();
    });

    // Test create goods
    const createButton = screen.getByText('创建商品');
    fireEvent.click(createButton);

    // Fill create form
    const nameInput = screen.getByTestId('goods-name-input');
    const priceInput = screen.getByTestId('goods-price-input');
    const costPriceInput = screen.getByTestId('goods-cost-price-input');
    const stockInput = screen.getByTestId('goods-stock-input');

    fireEvent.change(nameInput, { target: { value: '新商品' } });
    fireEvent.change(priceInput, { target: { value: '199.99' } });
    fireEvent.change(costPriceInput, { target: { value: '100.00' } });
    fireEvent.change(stockInput, { target: { value: '50' } });

    // Select supplier and merchant
    const supplierSelect = screen.getByTestId('supplier-selector');
    const merchantSelect = screen.getByTestId('merchant-selector');
    fireEvent.change(supplierSelect, { target: { value: '1' } });
    fireEvent.change(merchantSelect, { target: { value: '1' } });

    // Select file
    const fileSelectors = screen.getAllByTestId('file-selector');
    // 只有2个文件选择器：主图和轮播图
    fireEvent.click(fileSelectors[0]); // 主图
    fireEvent.click(fileSelectors[1]); // 轮播图

    // Mock successful creation
    (goodsClientManager.get().index.$post as any).mockResolvedValue(createMockResponse(201, { id: 2, name: '新商品' }));

    const submitButton = screen.getByText('创建');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(goodsClientManager.get().index.$post).toHaveBeenCalled();
      expect(toast.success).toHaveBeenCalledWith('商品创建成功');
    });

    // Test edit goods
    const editButtons = screen.getAllByTestId('edit-goods-button');
    fireEvent.click(editButtons[0]);

    // Verify edit form is populated
    await waitFor(() => {
      expect(screen.getByDisplayValue('测试商品')).toBeInTheDocument();
    });

    // Update goods
    const updateNameInput = screen.getByDisplayValue('测试商品');
    fireEvent.change(updateNameInput, { target: { value: '更新后的商品' } });

    // Mock successful update
    (goodsClientManager.get()[':id']['$put'] as any).mockResolvedValue(createMockResponse(200));

    const updateButton = screen.getByText('更新');
    fireEvent.click(updateButton);

    await waitFor(() => {
      expect(goodsClientManager.get()[':id']['$put']).toHaveBeenCalled();
      expect(toast.success).toHaveBeenCalledWith('商品更新成功');
    });

    // Test delete goods
    const deleteButtons = screen.getAllByTestId('delete-goods-button');
    fireEvent.click(deleteButtons[0]);

    // Confirm deletion
    expect(screen.getByText('确认删除')).toBeInTheDocument();

    // Mock successful deletion
    (goodsClientManager.get()[':id']['$delete'] as any).mockResolvedValue({
      status: 204,
    });

    const confirmDeleteButton = screen.getByText('删除');
    fireEvent.click(confirmDeleteButton);

    await waitFor(() => {
      expect(goodsClientManager.get()[':id']['$delete']).toHaveBeenCalled();
      expect(toast.success).toHaveBeenCalledWith('商品删除成功');
    });
  });

  it('应该优雅处理API错误', async () => {
    const { goodsClient } = await import('../../src/api/goodsClient');

    // Mock API error
    (goodsClientManager.get().index.$get as any).mockRejectedValue(new Error('API Error'));

    // Render component and verify it doesn't crash
    renderWithProviders(<GoodsManagement />);

    // Verify component renders without crashing
    await waitFor(() => {
      expect(screen.getByText('商品管理')).toBeInTheDocument();
    });
  });

  it('应该处理搜索功能', async () => {
    const { goodsClient } = await import('../../src/api/goodsClient');
    const mockGoods = {
      data: [],
      pagination: { total: 0, page: 1, pageSize: 10 },
    };

    (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

    renderWithProviders(<GoodsManagement />);

    // Test search
    const searchInput = screen.getByPlaceholderText('搜索商品名称...');
    fireEvent.change(searchInput, { target: { value: '搜索关键词' } });

    // Submit search
    const searchButton = screen.getByText('搜索');
    fireEvent.click(searchButton);

    await waitFor(() => {
      expect(goodsClientManager.get().index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: '搜索关键词',
          filters: '{"spuId": 0}',
        },
      });
    });
  });

  it('应该显示商品列表和分页信息', async () => {
    const mockGoods = {
      data: [
        {
          id: 1,
          name: '商品1',
          price: 100.00,
          costPrice: 50.00,
          categoryId1: 1,
          categoryId2: 2,
          categoryId3: 3,
          goodsType: 1,
          supplierId: 1,
          merchantId: 1,
          imageFileId: 1,
          slideImageIds: [],
          detail: '',
          instructions: '',
          sort: 0,
          state: 1,
          stock: 100,
          lowestBuy: 1,
          salesNum: 10,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
          createdBy: 1,
          updatedBy: 1,
          category1: { id: 1, name: '分类1' },
          category2: { id: 2, name: '分类2' },
          category3: { id: 3, name: '分类3' },
          supplier: { id: 1, name: '供应商1' },
          merchant: { id: 1, name: '商户1', username: 'merchant1' },
          imageFile: { id: 1, fullUrl: 'http://example.com/image.jpg' },
          slideImages: [],
        },
      ],
      pagination: {
        total: 25,
        page: 1,
        pageSize: 10,
      },
    };

    (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

    renderWithProviders(<GoodsManagement />);

    // Wait for data to load
    await waitFor(() => {
      expect(screen.getByText('商品1')).toBeInTheDocument();
    });

    // Verify pagination info
    expect(screen.getByText('共 25 条记录，第 1 / 3 页')).toBeInTheDocument();

    // Verify table columns
    expect(screen.getByText('商品图片')).toBeInTheDocument();
    expect(screen.getByText('商品名称')).toBeInTheDocument();
    expect(screen.getByText('价格')).toBeInTheDocument();
    expect(screen.getByText('库存')).toBeInTheDocument();
    expect(screen.getByText('销量')).toBeInTheDocument();
    expect(screen.getByText('供应商')).toBeInTheDocument();
    expect(screen.getByText('商户')).toBeInTheDocument();
    expect(screen.getByText('状态')).toBeInTheDocument();
    expect(screen.getByText('创建时间')).toBeInTheDocument();
  });

  describe('商品筛选器功能测试 (故事006.015)', () => {
    it('应该默认只显示父商品', async () => {
      const mockGoods = {
        data: [
          {
            id: 1,
            name: '父商品1',
            price: 100.00,
            spuId: 0,
            spuName: null,
            childGoodsIds: [2, 3],
            stock: 100,
            salesNum: 10,
            state: 1,
            createdAt: '2024-01-01T00:00:00Z',
            supplier: { id: 1, name: '供应商1' },
            merchant: { id: 1, name: '商户1' },
            costPrice: 50.00,
            categoryId1: 1,
            categoryId2: 2,
            categoryId3: 3,
            goodsType: 1,
            supplierId: 1,
            merchantId: 1,
            imageFileId: null,
            slideImageIds: [],
            detail: '',
            instructions: '',
            sort: 0,
            lowestBuy: 1,
            updatedAt: '2024-01-01T00:00:00Z',
            createdBy: 1,
            updatedBy: 1,
            category1: { id: 1, name: '分类1' },
            category2: { id: 2, name: '分类2' },
            category3: { id: 3, name: '分类3' },
            imageFile: null,
            slideImages: []
          }
        ],
        pagination: { total: 1, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 等待数据加载
      await waitFor(() => {
        expect(screen.getByText('父商品1')).toBeInTheDocument();
      });

      // 验证默认传递了filters参数
      expect(goodsClientManager.get().index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: '',
          filters: '{"spuId": 0}'
        },
      });

      // 验证筛选器默认选中"只显示父商品"
      const parentRadio = screen.getByLabelText('只显示父商品');
      expect(parentRadio).toBeChecked();

      // 验证父子关系标识显示
      expect(screen.getByText('父商品')).toBeInTheDocument();
      expect(screen.getByText('子商品: 2个')).toBeInTheDocument();
    });

    it('应该切换筛选器时实时刷新商品列表', async () => {
      const mockAllGoods = {
        data: [
          {
            id: 1,
            name: '父商品1',
            price: 100.00,
            spuId: 0,
            spuName: null,
            childGoodsIds: [2, 3],
            stock: 100,
            salesNum: 10,
            state: 1,
            createdAt: '2024-01-01T00:00:00Z',
            supplier: { id: 1, name: '供应商1' },
            merchant: { id: 1, name: '商户1' },
            costPrice: 50.00,
            categoryId1: 1,
            categoryId2: 2,
            categoryId3: 3,
            goodsType: 1,
            supplierId: 1,
            merchantId: 1,
            imageFileId: null,
            slideImageIds: [],
            detail: '',
            instructions: '',
            sort: 0,
            lowestBuy: 1,
            updatedAt: '2024-01-01T00:00:00Z',
            createdBy: 1,
            updatedBy: 1,
            category1: { id: 1, name: '分类1' },
            category2: { id: 2, name: '分类2' },
            category3: { id: 3, name: '分类3' },
            imageFile: null,
            slideImages: []
          },
          {
            id: 2,
            name: '子商品1',
            price: 120.00,
            spuId: 1,
            spuName: '父商品1',
            parent: { id: 1, name: '父商品1' },
            childGoodsIds: [],
            stock: 50,
            salesNum: 5,
            state: 1,
            createdAt: '2024-01-01T00:00:00Z',
            supplier: { id: 1, name: '供应商1' },
            merchant: { id: 1, name: '商户1' },
            costPrice: 60.00,
            categoryId1: 1,
            categoryId2: 2,
            categoryId3: 3,
            goodsType: 1,
            supplierId: 1,
            merchantId: 1,
            imageFileId: null,
            slideImageIds: [],
            detail: '',
            instructions: '',
            sort: 0,
            lowestBuy: 1,
            updatedAt: '2024-01-01T00:00:00Z',
            createdBy: 1,
            updatedBy: 1,
            category1: { id: 1, name: '分类1' },
            category2: { id: 2, name: '分类2' },
            category3: { id: 3, name: '分类3' },
            imageFile: null,
            slideImages: []
          }
        ],
        pagination: { total: 2, page: 1, pageSize: 10 },
      };

      // 第一次调用：默认只显示父商品
      (goodsClientManager.get().index.$get as any)
        .mockResolvedValueOnce(createMockResponse(200, {
          data: [mockAllGoods.data[0]],
          pagination: { total: 1, page: 1, pageSize: 10 }
        }))
        .mockResolvedValueOnce(createMockResponse(200, mockAllGoods)); // 第二次调用：显示所有商品

      renderWithProviders(<GoodsManagement />);

      // 等待初始加载
      await waitFor(() => {
        expect(screen.getByText('父商品1')).toBeInTheDocument();
      });

      // 切换到"显示所有商品"
      const allRadio = screen.getByLabelText('显示所有商品');
      fireEvent.click(allRadio);

      // 验证API调用不包含filters参数
      await waitFor(() => {
        expect(goodsClientManager.get().index.$get).toHaveBeenCalledWith({
          query: {
            page: 1,
            pageSize: 10,
            keyword: '',
            // 不传递filters参数
          },
        });
      });

      // 等待列表刷新
      await waitFor(() => {
        expect(screen.getByText('子商品1')).toBeInTheDocument();
      });

      // 验证子商品标识显示
      expect(screen.getByText('子商品')).toBeInTheDocument();
      // TODO: 组件可能没有显示父商品名称，暂时注释掉这个检查
      expect(screen.getByText(/父商品[:：]\s*父商品1/)).toBeInTheDocument();
    });

    it('应该处理筛选器与搜索参数的协同工作', async () => {
      const mockGoods = {
        data: [],
        pagination: { total: 0, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 修改搜索关键词
      const searchInput = screen.getByPlaceholderText('搜索商品名称...');
      fireEvent.change(searchInput, { target: { value: '测试' } });

      // 提交搜索
      const searchButton = screen.getByText('搜索');
      fireEvent.click(searchButton);

      // 验证搜索时保持筛选器状态
      await waitFor(() => {
        expect(goodsClientManager.get().index.$get).toHaveBeenCalledWith({
          query: {
            page: 1,
            pageSize: 10,
            keyword: '测试',
            filters: '{"spuId": 0}'
          },
        });
      });

      // 切换到"显示所有商品"
      const allRadio = screen.getByLabelText('显示所有商品');
      fireEvent.click(allRadio);

      // 验证切换筛选器时重置页码并包含搜索关键词
      await waitFor(() => {
        expect(goodsClientManager.get().index.$get).toHaveBeenCalledWith({
          query: {
            page: 1,
            pageSize: 10,
            keyword: '测试',
            // 不传递filters参数
          },
        });
      });
    });
  });

  describe('父子商品管理面板完整流程测试 (故事006.002)', () => {
    it('应该完成创建模式下的父子商品配置完整流程', async () => {
      const mockGoods = {
        data: [],
        pagination: { total: 0, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 1. 打开创建商品表单
      const createButton = screen.getByTestId('create-goods-button');
      fireEvent.click(createButton);

      // 2. 填写基本商品信息
      await waitFor(() => {
        expect(screen.getByTestId('goods-name-input')).toBeInTheDocument();
      });

      const nameInput = screen.getByTestId('goods-name-input');
      const priceInput = screen.getByTestId('goods-price-input');
      const stockInput = screen.getByTestId('goods-stock-input');

      fireEvent.change(nameInput, { target: { value: '测试父商品' } });
      fireEvent.change(priceInput, { target: { value: '199.99' } });
      fireEvent.change(stockInput, { target: { value: '100' } });

      // 3. 验证父子商品管理面板存在
      await waitFor(() => {
        // 面板应该显示创建模式
        expect(screen.getByText('父子商品管理')).toBeInTheDocument();
      });

      // 4. 验证父子商品管理面板的基本功能
      // 面板标题应该存在
      expect(screen.getByText('父子商品管理')).toBeInTheDocument();

      // 根据组件逻辑，创建模式下商品默认是普通商品（spuId=0）
      // 但"设为父商品"按钮只在 !isParent && !isChild 时显示
      // 由于spuId=0时isParent=true，所以按钮可能不显示
      // 我们验证面板的其他元素

      // Mock设为父商品API调用
      (goodsClientManager.get()[':id']['set-as-parent'].$post as any).mockResolvedValue(
        createMockResponse(200, { success: true })
      );

      // 5. 测试批量创建子商品功能
      // 查找批量创建相关的UI元素
      const batchCreateButtons = screen.getAllByText(/批量创建|批量规格/i);
      expect(batchCreateButtons.length).toBeGreaterThan(0);

      // 6. 提交创建商品
      // Mock商品创建成功
      (goodsClientManager.get().index.$post as any).mockResolvedValue(
        createMockResponse(201, { id: 100, name: '测试父商品' })
      );

      // Mock批量创建子商品API
      (goodsClientManager.get().batchCreateChildren.$post as any).mockResolvedValue(
        createMockResponse(200, { success: true, createdCount: 2 })
      );

      const submitButton = screen.getByText('创建');
      fireEvent.click(submitButton);

      // 7. 验证API调用
      await waitFor(() => {
        expect(goodsClientManager.get().index.$post).toHaveBeenCalled();
      });
    });

    it('应该完成编辑模式下的父子商品管理完整流程', async () => {
      // Mock包含父子关系的商品数据
      const mockGoods = {
        data: [
          {
            id: 100,
            name: '测试父商品',
            price: 199.99,
            spuId: 0,
            spuName: null,
            childGoodsIds: [101, 102],
            stock: 100,
            salesNum: 50,
            state: 1,
            createdAt: '2024-01-01T00:00:00Z',
            supplier: { id: 1, name: '供应商1' },
            merchant: { id: 1, name: '商户1' },
            costPrice: 150.00,
            categoryId1: 1,
            categoryId2: 2,
            categoryId3: 3,
            goodsType: 1,
            supplierId: 1,
            merchantId: 1,
            imageFileId: null,
            slideImageIds: [],
            detail: '',
            instructions: '',
            sort: 0,
            lowestBuy: 1,
            updatedAt: '2024-01-01T00:00:00Z',
            createdBy: 1,
            updatedBy: 1,
            category1: { id: 1, name: '分类1' },
            category2: { id: 2, name: '分类2' },
            category3: { id: 3, name: '分类3' },
            imageFile: null,
            slideImages: []
          }
        ],
        pagination: { total: 1, page: 1, pageSize: 10 },
      };

      // Mock子商品列表数据
      const mockChildrenData = {
        data: [
          {
            id: 101,
            name: '子商品-红色',
            price: 209.99,
            costPrice: 160.00,
            stock: 50,
            sort: 1,
            state: 1,
            createdAt: '2024-01-01T00:00:00Z'
          },
          {
            id: 102,
            name: '子商品-蓝色',
            price: 219.99,
            costPrice: 170.00,
            stock: 60,
            sort: 2,
            state: 1,
            createdAt: '2024-01-01T00:00:00Z'
          }
        ],
        total: 2
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));
      (goodsClientManager.get()[':id'].children.$get as any).mockResolvedValue(
        createMockResponse(200, mockChildrenData)
      );

      renderWithProviders(<GoodsManagement />);

      // 1. 等待商品列表加载
      await waitFor(() => {
        expect(screen.getByText('测试父商品')).toBeInTheDocument();
      });

      // 2. 打开编辑表单
      const editButtons = screen.getAllByTestId('edit-goods-button');
      expect(editButtons.length).toBeGreaterThan(0);
      fireEvent.click(editButtons[0]);

      // 3. 验证编辑表单加载 - 增加超时和更具体的验证
      await waitFor(() => {
        // 首先验证编辑表单的基本元素
        expect(screen.getByText('更新')).toBeInTheDocument();
        expect(screen.getByText('取消')).toBeInTheDocument();

        // 验证商品名称字段存在
        const nameInput = screen.getByDisplayValue('测试父商品');
        expect(nameInput).toBeInTheDocument();
      }, { timeout: 5000 });

      // 4. 验证父子商品管理面板显示编辑模式
      // 面板可能在表单加载后才会显示
      await waitFor(() => {
        // 先验证面板标题
        const panelTitle = screen.getByText('父子商品管理');
        expect(panelTitle).toBeInTheDocument();

        // 验证面板描述（编辑模式）
        expect(screen.getByText(/管理商品的父子关系/)).toBeInTheDocument();
      }, { timeout: 5000 });

      // 5. 验证父商品的相关功能
      // 父商品（spuId=0）应该显示"批量创建子商品"按钮
      // 查找批量创建相关的UI元素
      const batchCreateButtons = screen.getAllByText(/批量创建/i);
      expect(batchCreateButtons.length).toBeGreaterThan(0);

      // Mock批量创建API（如果需要）
      (goodsClientManager.get().batchCreateChildren.$post as any).mockResolvedValue(
        createMockResponse(200, { success: true })
      );

      // 6. 测试更新商品信息
      const updateNameInput = screen.getByDisplayValue('测试父商品');
      fireEvent.change(updateNameInput, { target: { value: '更新后的父商品' } });

      // Mock更新API
      (goodsClientManager.get()[':id']['$put'] as any).mockResolvedValue(
        createMockResponse(200, { success: true })
      );

      const updateButton = screen.getByText('更新');
      fireEvent.click(updateButton);

      // 7. 验证API调用
      await waitFor(() => {
        expect(goodsClientManager.get()[':id']['$put']).toHaveBeenCalled();
      });
    });

    it('应该处理父子商品数据同步', async () => {
      const mockGoods = {
        data: [],
        pagination: { total: 0, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 打开创建表单
      const createButton = screen.getByTestId('create-goods-button');
      fireEvent.click(createButton);

      await waitFor(() => {
        expect(screen.getByTestId('goods-name-input')).toBeInTheDocument();
      });

      // 填写商品名称
      const nameInput = screen.getByTestId('goods-name-input');
      fireEvent.change(nameInput, { target: { value: '同步测试商品' } });

      // 验证父子商品管理面板能够访问商品名称
      // 面板应该能够通过goodsName属性获取商品名称
      await waitFor(() => {
        expect(screen.getByText('父子商品管理')).toBeInTheDocument();
      });

      // 测试数据同步：面板操作应该能够更新表单数据
      // 这里我们验证面板的存在和基本功能
      const panelTitle = screen.getByText('父子商品管理');
      expect(panelTitle).toBeInTheDocument();

      // 验证面板包含必要的功能区域
      // 注意：根据组件逻辑，某些按钮可能只在特定条件下显示
      // 我们验证面板的基本渲染
      expect(screen.getByText(/父子商品管理/)).toBeInTheDocument();

      // 验证面板描述
      expect(screen.getByText(/创建商品时配置父子关系/)).toBeInTheDocument();
    });

    it('应该支持批量创建子商品完整流程', async () => {
      const mockGoods = {
        data: [],
        pagination: { total: 0, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 打开创建表单
      const createButton = screen.getByTestId('create-goods-button');
      fireEvent.click(createButton);

      await waitFor(() => {
        expect(screen.getByTestId('goods-name-input')).toBeInTheDocument();
      });

      // 填写基本商品信息
      const nameInput = screen.getByTestId('goods-name-input');
      const priceInput = screen.getByTestId('goods-price-input');
      fireEvent.change(nameInput, { target: { value: '批量创建测试商品' } });
      fireEvent.change(priceInput, { target: { value: '299.99' } });

      // 验证批量创建功能存在
      await waitFor(() => {
        expect(screen.getByText('批量创建')).toBeInTheDocument();
      });

      // Mock商品创建成功
      (goodsClientManager.get().index.$post as any).mockResolvedValue(
        createMockResponse(201, { id: 200, name: '批量创建测试商品' })
      );

      // Mock批量创建API
      (goodsClientManager.get().batchCreateChildren.$post as any).mockResolvedValue(
        createMockResponse(200, {
          success: true,
          createdCount: 3,
          children: [
            { id: 201, name: '规格1' },
            { id: 202, name: '规格2' },
            { id: 203, name: '规格3' }
          ]
        })
      );

      // 提交创建
      const submitButton = screen.getByText('创建');
      fireEvent.click(submitButton);

      // 验证商品创建API被调用
      await waitFor(() => {
        expect(goodsClientManager.get().index.$post).toHaveBeenCalled();
      });

      // 注意：批量创建会在商品创建成功后自动调用
      // 这里我们验证批量创建API的mock已设置
      expect(goodsClientManager.get().batchCreateChildren.$post).toBeDefined();
    });

    it('应该完成完整的创建商品和批量创建规格流程', async () => {
      const mockGoods = {
        data: [],
        pagination: { total: 0, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 1. 打开创建表单
      const createButton = screen.getByTestId('create-goods-button');
      fireEvent.click(createButton);

      // 等待对话框打开 - 先检查对话框是否显示
      await waitFor(() => {
        expect(screen.getByTestId('create-edit-goods-dialog')).toBeInTheDocument();
      }, { timeout: 5000 });


      // 然后等待输入框出现
      await waitFor(() => {
        expect(screen.getByTestId('goods-name-input')).toBeInTheDocument();
      }, { timeout: 5000 });

      // 2. 填写基本商品信息
      const nameInput = screen.getByTestId('goods-name-input');
      const priceInput = screen.getByTestId('goods-price-input');
      fireEvent.change(nameInput, { target: { value: '测试商品-带批量规格' } });
      fireEvent.change(priceInput, { target: { value: '199.99' } });

      // 3. 填写其他必填字段
      const costPriceInput = screen.getByTestId('goods-cost-price-input');
      const stockInput = screen.getByTestId('goods-stock-input');
      fireEvent.change(costPriceInput, { target: { value: '100.00' } });
      fireEvent.change(stockInput, { target: { value: '50' } });

      // 4. 验证父子商品管理面板存在
      await waitFor(() => {
        expect(screen.getByText('父子商品管理')).toBeInTheDocument();
      });

      // 5. 在创建模式下，商品默认是父商品，直接点击"批量创建子商品"按钮
      const batchCreateButton = screen.getByText('批量创建子商品');
      await waitFor(() => {
        expect(screen.getByText('批量创建子商品'))
      })

      fireEvent.click(batchCreateButton);

      // 重新获取切换tab后的对话框元素
      let createDialog = await screen.findByTestId('create-edit-goods-dialog');

      // 8. 验证BatchSpecCreatorInline组件已渲染
      // 使用queryByText检查，如果找不到也不失败
      expect(within(createDialog).getByText('快速模板')).toBeInTheDocument();
      expect(within(createDialog).getByText('颜色规格模板')).toBeInTheDocument();
      expect(within(createDialog).getByText('添加')).toBeInTheDocument();

      // 验证面板模式已切换
      // 从调试输出可以看到面板模式已切换到batch
      // 我们只需要验证批量创建相关的API mock已设置
      expect(goodsClientManager.get().batchCreateChildren.$post).toBeDefined();

      // 验证可以提交表单
      expect(within(createDialog).getByText('创建')).toBeInTheDocument();

      // 9. 填写规格数据
      // 找到规格名称输入框
      const specNameInput = within(createDialog).getByTestId('spec-name-input');
      const specPriceInput = within(createDialog).getByTestId('spec-price-input');
      const specStockInput = within(createDialog).getByTestId('spec-stock-input');
      const addSpecButton = within(createDialog).getByTestId('add-spec-button');

      // 添加第一个规格：红色
      fireEvent.change(specNameInput, { target: { value: '红色' } });
      fireEvent.change(specPriceInput, { target: { value: '219.99' } });
      fireEvent.change(specStockInput, { target: { value: '50' } });

      // 等待按钮启用 - 根据组件逻辑，按钮在规格名称不为空时启用
      await waitFor(() => {
        expect(addSpecButton).toBeEnabled();
      });

      fireEvent.click(addSpecButton);

      // 等待规格添加完成
      await waitFor(() => {
        expect(within(createDialog).getByTestId('spec-row-0')).toBeInTheDocument();
      });

      // 添加第二个规格：蓝色
      fireEvent.change(specNameInput, { target: { value: '蓝色' } });
      fireEvent.change(specPriceInput, { target: { value: '229.99' } });
      fireEvent.change(specStockInput, { target: { value: '30' } });

      // 等待按钮启用
      await waitFor(() => {
        expect(addSpecButton).toBeEnabled();
      }, { timeout: 1000 });

      fireEvent.click(addSpecButton);

      // 等待第二个规格添加完成
      await waitFor(() => {
        expect(within(createDialog).getByTestId('spec-row-1')).toBeInTheDocument();
      });

      // 10. Mock商品创建成功
      (goodsClientManager.get().index.$post as any).mockResolvedValue(
        createMockResponse(201, { id: 300, name: '测试商品-带批量规格' })
      );

      // 11. Mock批量创建API - 验证会传递正确的规格数据
      const batchCreateMock = vi.fn().mockResolvedValue(
        createMockResponse(200, {
          success: true,
          createdCount: 2,
          children: [
            { id: 301, name: '红色' },
            { id: 302, name: '蓝色' }
          ]
        })
      );
      (goodsClientManager.get().batchCreateChildren.$post as any) = batchCreateMock;

      // 12. 提交创建
      const submitButton = within(createDialog).getByText('创建');
      fireEvent.click(submitButton);

      // 13. 验证商品创建API被调用
      await waitFor(() => {
        expect(goodsClientManager.get().index.$post).toHaveBeenCalled();
      });

      // 14. 验证批量创建API被调用，并且传递了正确的规格数据
      await waitFor(() => {
        expect(batchCreateMock).toHaveBeenCalled();
        // 验证传递的参数包含规格数据
        const callArgs = batchCreateMock.mock.calls[0][0];
        expect(callArgs).toBeDefined();
        expect(callArgs.json).toBeDefined();
        const jsonData = callArgs.json;
        expect(jsonData.parentGoodsId).toBe(300);
        expect(jsonData.specs).toHaveLength(2);
        expect(jsonData.specs[0]).toMatchObject({ name: '红色', price: 219.99, stock: 50 });
        expect(jsonData.specs[1]).toMatchObject({ name: '蓝色', price: 229.99, stock: 30 });
      });
    });

    it('应该完成完整的编辑商品和管理批量规格流程', async () => {
      const mockGoods = {
        data: [
          {
            id: 400,
            name: '待编辑商品',
            price: 299.99,
            spuId: 0, // 父商品
            spuName: null,
            childGoods: [],
            createdAt: '2024-01-01T00:00:00.000Z' // 添加createdAt字段
          }
        ],
        pagination: { total: 1, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 1. 等待商品列表加载
      await waitFor(() => {
        expect(screen.getByText('待编辑商品')).toBeInTheDocument();
      });

      // 2. 点击编辑按钮
      const editButtons = screen.getAllByTestId('edit-goods-button');
      fireEvent.click(editButtons[0]);

      // 3. 等待编辑表单加载
      await waitFor(() => {
        expect(screen.getByDisplayValue('待编辑商品')).toBeInTheDocument();
      });

      // 4. 验证父子商品管理面板存在
      expect(screen.getByText('父子商品管理')).toBeInTheDocument();

      // 5. Mock获取子商品列表（空列表）
      (goodsClientManager.get()[':id'].children.$get as any).mockResolvedValue(
        createMockResponse(200, {
          data: [],
          total: 0
        })
      );

      // 6. 点击"批量创建子商品"按钮切换到批量创建标签页
      const batchCreateButton = screen.getByText('批量创建子商品');
      fireEvent.click(batchCreateButton);

      // 7. 等待标签页切换，先验证"批量创建"标签页内容
      await waitFor(() => {
        // 检查是否有"批量创建规格"标题
        expect(screen.getByText('批量创建规格')).toBeInTheDocument();
      });

      // 8. 等待批量创建标签页加载
      await waitFor(() => {
        expect(screen.getByLabelText('规格名称 *')).toBeInTheDocument();
      });

      const specNameInput = screen.getByLabelText('规格名称 *');
      const specPriceInput = screen.getByLabelText('价格');
      // 使用更具体的查询，找到批量创建规格表单中的库存输入框
      const specStockInputs = screen.getAllByLabelText('库存');
      const specStockInput = specStockInputs.find(input =>
        input.id === 'spec-stock' || input.getAttribute('name') === 'spec-stock'
      ) || specStockInputs[0];

      // 添加规格
      fireEvent.change(specNameInput, { target: { value: '黑色' } });
      fireEvent.change(specPriceInput, { target: { value: '319.99' } });
      fireEvent.change(specStockInput, { target: { value: '20' } });
      fireEvent.click(screen.getByText('添加'));

      // 验证规格已添加
      await waitFor(() => {
        expect(screen.getByDisplayValue('黑色')).toBeInTheDocument();
      });

      // 8. Mock商品更新成功
      (goodsClientManager.get()[':id'].$put as any).mockResolvedValue(
        createMockResponse(200, { id: 400, name: '更新后的商品' })
      );

      // 9. Mock批量创建API
      const batchCreateMock = vi.fn().mockResolvedValue(
        createMockResponse(200, {
          success: true,
          createdCount: 1,
          children: [{ id: 401, name: '黑色' }]
        })
      );
      (goodsClientManager.get().batchCreateChildren.$post as any) = batchCreateMock;

      // 10. 在编辑模式下，需要先点击"批量创建子商品"按钮来调用API
      const batchCreateSubmitButton = screen.getByText('批量创建子商品');
      fireEvent.click(batchCreateSubmitButton);

      // 11. 等待批量创建API被调用
      await waitFor(() => {
        expect(batchCreateMock).toHaveBeenCalled();
      });

      // 12. 提交更新
      const updateButton = screen.getByText('更新');
      fireEvent.click(updateButton);

      // 13. 验证商品更新API被调用
      await waitFor(() => {
        expect(goodsClientManager.get()[':id'].$put).toHaveBeenCalled();
      });
    });

    it('应该测试完整的创建商品和使用预定义模板流程', async () => {
      const mockGoods = {
        data: [],
        pagination: { total: 0, page: 1, pageSize: 10 },
      };

      (goodsClientManager.get().index.$get as any).mockResolvedValue(createMockResponse(200, mockGoods));

      renderWithProviders(<GoodsManagement />);

      // 1. 打开创建表单
      const createButton = screen.getByTestId('create-goods-button');
      fireEvent.click(createButton);

      // 等待对话框打开 - 先检查对话框是否显示
      await waitFor(() => {
        expect(screen.getByTestId('create-edit-goods-dialog')).toBeInTheDocument();
      }, { timeout: 5000 });

      // 然后等待输入框出现
      await waitFor(() => {
        expect(screen.getByTestId('goods-name-input')).toBeInTheDocument();
      }, { timeout: 5000 });

      // 找到对话框容器 - 使用更通用的查询方式
      // 先检查是否有"创建商品"标题（对话框中的标题）
      const dialogTitles = screen.getAllByText('创建商品');
      // 第一个是页面上的创建按钮，第二个是对话框标题
      const dialogTitle = dialogTitles[1];
      // 找到包含标题的对话框容器
      const dialogContainerByTitle = dialogTitle.closest('[role="dialog"], [data-radix-portal]');

      // 2. 填写基本商品信息
      const nameInput = screen.getByTestId('goods-name-input');
      const priceInput = screen.getByTestId('goods-price-input');
      fireEvent.change(nameInput, { target: { value: '模板测试商品' } });
      fireEvent.change(priceInput, { target: { value: '99.99' } });

      // 3. 验证父子商品管理面板存在
      await waitFor(() => {
        expect(screen.getByText('父子商品管理')).toBeInTheDocument();
      });

      // 4. 在创建模式下，商品默认是父商品，直接点击"批量创建子商品"按钮
      const batchCreateButton = screen.getByText('批量创建子商品');
      fireEvent.click(batchCreateButton);

      // 5. 等待标签页切换，先验证"批量创建"标签页内容
      await waitFor(() => {
        // 检查是否有"批量创建规格"标题
        expect(screen.getByText('批量创建规格')).toBeInTheDocument();
      });

      // 6. 等待批量创建标签页加载
      await waitFor(() => {
        expect(screen.getByLabelText('规格名称 *')).toBeInTheDocument();
        expect(screen.getByText('快速模板')).toBeInTheDocument();
      });

      // 8. 点击预定义模板（颜色规格模板）
      const templateBadges = screen.getAllByText(/颜色规格模板|尺寸规格模板|容量规格模板/);
      fireEvent.click(templateBadges[0]); // 颜色规格模板

      // 9. 验证模板规格已加载
      await waitFor(() => {
        expect(screen.getByDisplayValue('红色')).toBeInTheDocument();
        expect(screen.getByDisplayValue('蓝色')).toBeInTheDocument();
        expect(screen.getByDisplayValue('绿色')).toBeInTheDocument();
      });

      // 10. 验证统计信息
      expect(screen.getByText('规格数量')).toBeInTheDocument();
      expect(screen.getByText('5')).toBeInTheDocument(); // 颜色模板有5个规格

      // 7. Mock商品创建成功
      (goodsClientManager.get().index.$post as any).mockResolvedValue(
        createMockResponse(201, { id: 500, name: '模板测试商品' })
      );

      // 8. Mock批量创建API
      const batchCreateMock = vi.fn().mockResolvedValue(
        createMockResponse(200, {
          success: true,
          createdCount: 5,
          children: [
            { id: 501, name: '红色' },
            { id: 502, name: '蓝色' },
            { id: 503, name: '绿色' },
            { id: 504, name: '黑色' },
            { id: 505, name: '白色' }
          ]
        })
      );
      (goodsClientManager.get().batchCreateChildren.$post as any) = batchCreateMock;

      // 9. 提交创建
      const submitButton = screen.getByText('创建');
      fireEvent.click(submitButton);

      // 10. 验证商品创建API被调用
      await waitFor(() => {
        expect(goodsClientManager.get().index.$post).toHaveBeenCalled();
      });

      // 11. 验证批量创建API被调用，传递了5个规格
      await waitFor(() => {
        expect(batchCreateMock).toHaveBeenCalled();
        const callArgs = batchCreateMock.mock.calls[0][0];
        const jsonData = callArgs.json;
        expect(jsonData.specs).toHaveLength(5);
      });
    });

  });
});