import { describe, it, expect, beforeEach } from 'vitest';
import { testClient } from 'hono/testing';
import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
import { JWTUtil } from '@d8d/shared-utils';
import { UserEntityMt, RoleMt } from '@d8d/user-module-mt';
import { FileMt } from '@d8d/file-module-mt';
import { SupplierMt } from '@d8d/supplier-module-mt';
import { MerchantMt } from '@d8d/merchant-module-mt';
import { publicGoodsRoutesMt } from '../../src/routes/index.mt';
import { GoodsMt, GoodsCategoryMt } from '../../src/entities/index.mt';
import { GoodsTestFactory } from '../factories/goods-test-factory';

// 设置集成测试钩子
setupIntegrationDatabaseHooksWithEntities([
  UserEntityMt, RoleMt, GoodsMt, GoodsCategoryMt, FileMt, SupplierMt, MerchantMt
])

describe('公开商品列表父商品过滤集成测试', () => {
  let client: ReturnType<typeof testClient<typeof publicGoodsRoutesMt>>;
  let testUser: UserEntityMt;
  let testCategory: GoodsCategoryMt;
  let testSupplier: SupplierMt;
  let testMerchant: MerchantMt;
  let testFactory: GoodsTestFactory;
  let parentGoods1: GoodsMt;
  let parentGoods2: GoodsMt;
  let childGoods1: GoodsMt;
  let childGoods2: GoodsMt;

  beforeEach(async () => {
    // 创建测试客户端
    client = testClient(publicGoodsRoutesMt);

    // 获取数据源并创建测试工厂
    const dataSource = await IntegrationTestDatabase.getDataSource();
    testFactory = new GoodsTestFactory(dataSource);

    // 使用测试工厂创建测试数据
    testUser = await testFactory.createTestUser();
    testCategory = await testFactory.createTestCategory(testUser.id);
    testSupplier = await testFactory.createTestSupplier(testUser.id);
    testMerchant = await testFactory.createTestMerchant(testUser.id);

    // 创建父商品1
    parentGoods1 = await testFactory.createTestGoods(testUser.id, {
      name: '父商品1',
      price: 100.00,
      costPrice: 80.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      spuId: 0,
      spuName: null
    });

    // 创建父商品2
    parentGoods2 = await testFactory.createTestGoods(testUser.id, {
      name: '父商品2',
      price: 200.00,
      costPrice: 160.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      spuId: 0,
      spuName: null
    });

    // 创建子商品1（关联到父商品1）
    childGoods1 = await testFactory.createTestGoods(testUser.id, {
      name: '子商品1 - 红色',
      price: 110.00,
      costPrice: 90.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      spuId: parentGoods1.id,
      spuName: '父商品1'
    });

    // 创建子商品2（关联到父商品1）
    childGoods2 = await testFactory.createTestGoods(testUser.id, {
      name: '子商品2 - 蓝色',
      price: 120.00,
      costPrice: 100.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      spuId: parentGoods1.id,
      spuName: '父商品1'
    });

    // 创建不可用的父商品
    await testFactory.createTestGoods(testUser.id, {
      name: '不可用父商品',
      price: 300.00,
      costPrice: 250.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 0, // 不可用状态
      spuId: 0,
      spuName: null
    });

    // 创建不可用的子商品
    await testFactory.createTestGoods(testUser.id, {
      name: '不可用子商品',
      price: 130.00,
      costPrice: 110.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 0, // 不可用状态
      spuId: parentGoods1.id,
      spuName: '父商品1'
    });
  });

  describe('GET /api/v1/goods (公共商品列表)', () => {
    it('默认应该只返回可用状态的父商品', async () => {
      const response = await client.index.$get({
        query: { page: 1, pageSize: 10 }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 应该只返回2个父商品（parentGoods1, parentGoods2）
      expect(data.data).toHaveLength(2);
      expect(data.pagination.total).toBe(2);

      // 验证返回的是父商品
      const returnedIds = data.data.map((item: any) => item.id);
      expect(returnedIds).toContain(parentGoods1.id);
      expect(returnedIds).toContain(parentGoods2.id);
      expect(returnedIds).not.toContain(childGoods1.id);
      expect(returnedIds).not.toContain(childGoods2.id);

      // 验证父商品的spuId为0
      data.data.forEach((item: any) => {
        expect(item.spuId).toBe(0);
        expect(item.state).toBe(1); // 可用状态
      });
    });

    it('应该支持通过filters参数显示子商品', async () => {
      // 使用filters参数查询所有商品（包括子商品）
      // 传入spuId: null来禁用默认的spuId过滤
      const response = await client.index.$get({
        query: {
          page: 1,
          pageSize: 10,
          filters: JSON.stringify({ state: 1, spuId: null }) // 只过滤状态，禁用spuId过滤
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 应该返回4个商品：2个父商品 + 2个子商品
      expect(data.pagination.total).toBe(4);
      expect(data.data).toHaveLength(4);

      // 验证包含所有商品
      const returnedIds = data.data.map((item: any) => item.id);
      expect(returnedIds).toContain(parentGoods1.id);
      expect(returnedIds).toContain(parentGoods2.id);
      expect(returnedIds).toContain(childGoods1.id);
      expect(returnedIds).toContain(childGoods2.id);
    });

    it('应该支持通过filters参数查询特定父商品的子商品', async () => {
      // 查询父商品1的子商品
      const response = await client.index.$get({
        query: {
          page: 1,
          pageSize: 10,
          filters: JSON.stringify({
            state: 1,
            spuId: parentGoods1.id
          })
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 应该返回2个子商品
      expect(data.pagination.total).toBe(2);
      expect(data.data).toHaveLength(2);

      // 验证返回的是子商品
      const returnedIds = data.data.map((item: any) => item.id);
      expect(returnedIds).toContain(childGoods1.id);
      expect(returnedIds).toContain(childGoods2.id);
      expect(returnedIds).not.toContain(parentGoods1.id);
      expect(returnedIds).not.toContain(parentGoods2.id);

      // 验证子商品的spuId为parentGoods1.id
      data.data.forEach((item: any) => {
        expect(item.spuId).toBe(parentGoods1.id);
        // spuName字段已从API响应中移除，改为通过parent对象获取父商品名称
        // expect(item.spuName).toBe('父商品1');
      });
    });

    it('应该支持搜索关键词过滤', async () => {
      const response = await client.index.$get({
        query: {
          page: 1,
          pageSize: 10,
          keyword: '父商品1'
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 应该只返回父商品1
      expect(data.pagination.total).toBe(1);
      expect(data.data[0].id).toBe(parentGoods1.id);
      expect(data.data[0].name).toBe('父商品1');
    });

    it('应该保持与现有查询参数的兼容性', async () => {
      // 测试分类过滤
      const response = await client.index.$get({
        query: {
          page: 1,
          pageSize: 10,
          filters: JSON.stringify({
            state: 1,
            categoryId1: testCategory.id
          })
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 应该返回所有符合条件的父商品
      expect(data.pagination.total).toBe(2);
      data.data.forEach((item: any) => {
        expect(item.categoryId1).toBe(testCategory.id);
        expect(item.spuId).toBe(0);
      });
    });

    it('应该正确处理空结果集', async () => {
      // 查询不存在的分类
      const response = await client.index.$get({
        query: {
          page: 1,
          pageSize: 10,
          filters: JSON.stringify({
            state: 1,
            categoryId1: 99999 // 不存在的分类
          })
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.pagination.total).toBe(0);
      expect(data.data).toHaveLength(0);
    });
  });

  describe('GET /api/v1/goods/:id (商品详情)', () => {
    it('父商品详情应该包含子商品列表', async () => {
      const response = await client[':id'].$get({
        param: { id: parentGoods1.id }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 验证父商品详情
      expect(data.id).toBe(parentGoods1.id);
      expect(data.name).toBe('父商品1');
      expect(data.spuId).toBe(0);

      // 验证包含子商品列表
      expect(data).toHaveProperty('children');
      expect(data.children).toHaveLength(2);

      // 验证子商品数据
      const childIds = data.children.map((item: any) => item.id);
      expect(childIds).toContain(childGoods1.id);
      expect(childIds).toContain(childGoods2.id);

      // 验证子商品包含正确的关联关系
      const firstChild = data.children[0];
      expect(firstChild).toHaveProperty('category1');
      expect(firstChild).toHaveProperty('supplier');
      expect(firstChild).toHaveProperty('merchant');
    });

    it('子商品详情应该包含父商品信息', async () => {
      const response = await client[':id'].$get({
        param: { id: childGoods1.id }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 验证子商品详情
      expect(data.id).toBe(childGoods1.id);
      expect(data.name).toBe('子商品1 - 红色');
      expect(data.spuId).toBe(parentGoods1.id);
      // spuName字段已从API响应中移除，改为通过parent对象获取父商品名称
      // expect(data.spuName).toBe('父商品1');

      // 验证包含父商品信息
      expect(data).toHaveProperty('parent');
      expect(data.parent.id).toBe(parentGoods1.id);
      expect(data.parent.name).toBe('父商品1');
      expect(data.parent).toHaveProperty('price');
      expect(data.parent).toHaveProperty('stock');
      expect(data.parent).toHaveProperty('imageFileId');
    });

    it('单规格商品详情应该正常工作', async () => {
      // 创建一个单规格商品（spuId=0且无子商品）
      const singleGoods = await testFactory.createTestGoods(testUser.id, {
        name: '单规格商品',
        price: 150.00,
        costPrice: 120.00,
        categoryId1: testCategory.id,
        categoryId2: testCategory.id,
        categoryId3: testCategory.id,
        supplierId: testSupplier.id,
        merchantId: testMerchant.id,
        state: 1,
        spuId: 0,
        spuName: null
      });

      const response = await client[':id'].$get({
        param: { id: singleGoods.id }
      });

      expect(response.status).toBe(200);
      const data = await response.json();

      // 验证商品详情
      expect(data.id).toBe(singleGoods.id);
      expect(data.name).toBe('单规格商品');
      expect(data.spuId).toBe(0);

      // 单规格商品应该没有children属性或为空数组
      if (data.children !== undefined) {
        expect(data.children).toHaveLength(0);
      }

      // 应该没有parent属性
      expect(data.parent).toBeUndefined();
    });
  });
});