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 { publicGoodsChildrenRoutesMt } 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('公开商品子商品API集成测试', () => {
  let client: ReturnType<typeof testClient<typeof publicGoodsChildrenRoutesMt>>;
  let testUser: UserEntityMt;
  let testCategory: GoodsCategoryMt;
  let testSupplier: SupplierMt;
  let testMerchant: MerchantMt;
  let testFactory: GoodsTestFactory;
  let parentGoods: GoodsMt;
  let childGoods1: GoodsMt;
  let childGoods2: GoodsMt;

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

    // 获取数据源并创建测试工厂
    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);

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

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

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

    // 创建另一个父商品和子商品（用于测试租户隔离）
    const otherParentGoods = 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: 1,
      spuId: 0,
      spuName: null
    });

    await testFactory.createTestGoods(testUser.id, {
      name: '其他子商品',
      price: 310.00,
      costPrice: 260.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      spuId: otherParentGoods.id,
      spuName: '其他父商品'
    });
  });

  describe('GET /api/v1/goods/:id/children', () => {
    it('应该成功获取父商品的子商品列表', async () => {
      const response = await client[':id'].children.$get({
        param: { id: parentGoods.id },
        query: { page: 1, pageSize: 10 }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.data).toHaveLength(2);
      expect(data.total).toBe(2);
      expect(data.page).toBe(1);
      expect(data.pageSize).toBe(10);
      expect(data.totalPages).toBe(1);

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

      // 验证子商品包含正确的关联关系
      const firstChild = data.data[0];
      expect(firstChild).toHaveProperty('category1');
      expect(firstChild).toHaveProperty('supplier');
      expect(firstChild).toHaveProperty('merchant');
      expect(firstChild.spuId).toBe(parentGoods.id);
      // spuName字段已从API响应中移除，改为通过parent对象获取父商品名称
      // expect(firstChild.spuName).toBe('父商品测试');
    });

    it('应该支持分页', async () => {
      // 创建更多子商品
      for (let i = 3; i <= 15; i++) {
        await testFactory.createTestGoods(testUser.id, {
          name: `子商品${i}`,
          price: 200 + i * 10,
          costPrice: 150 + i * 10,
          categoryId1: testCategory.id,
          categoryId2: testCategory.id,
          categoryId3: testCategory.id,
          supplierId: testSupplier.id,
          merchantId: testMerchant.id,
          state: 1,
          spuId: parentGoods.id,
          spuName: '父商品测试'
        });
      }

      // 第一页
      const response1 = await client[':id'].children.$get({
        param: { id: parentGoods.id },
        query: { page: 1, pageSize: 5 }
      });

      expect(response1.status).toBe(200);
      const data1 = await response1.json();
      expect(data1.data).toHaveLength(5);
      expect(data1.total).toBe(15); // 原有2个 + 新增13个 = 15个
      expect(data1.page).toBe(1);
      expect(data1.pageSize).toBe(5);
      expect(data1.totalPages).toBe(3);

      // 第二页
      const response2 = await client[':id'].children.$get({
        param: { id: parentGoods.id },
        query: { page: 2, pageSize: 5 }
      });

      expect(response2.status).toBe(200);
      const data2 = await response2.json();
      expect(data2.data).toHaveLength(5);
      expect(data2.page).toBe(2);
    });

    it('应该支持搜索关键词过滤', async () => {
      const response = await client[':id'].children.$get({
        param: { id: parentGoods.id },
        query: { page: 1, pageSize: 10, keyword: '红色' }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.data).toHaveLength(1);
      expect(data.data[0].name).toBe('子商品1 - 红色');
    });

    it('应该只返回可用状态的子商品', async () => {
      // 创建一个不可用的子商品
      const disabledChild = await testFactory.createTestGoods(testUser.id, {
        name: '不可用子商品',
        price: 230.00,
        costPrice: 180.00,
        categoryId1: testCategory.id,
        categoryId2: testCategory.id,
        categoryId3: testCategory.id,
        supplierId: testSupplier.id,
        merchantId: testMerchant.id,
        state: 0, // 不可用状态
        spuId: parentGoods.id,
        spuName: '父商品测试'
      });

      const response = await client[':id'].children.$get({
        param: { id: parentGoods.id },
        query: { page: 1, pageSize: 10 }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.total).toBe(2); // 只返回2个可用子商品
      const childIds = data.data.map((item: any) => item.id);
      expect(childIds).not.toContain(disabledChild.id);
    });

    it('应该验证父商品是否存在', async () => {
      const response = await client[':id'].children.$get({
        param: { id: 99999 }, // 不存在的商品ID
        query: { page: 1, pageSize: 10 }
      });

      expect(response.status).toBe(404);
      const data = await response.json();
      expect(data.code).toBe(404);
      expect(data.message).toContain('父商品不存在');
    });

    it('应该验证商品是否为父商品', async () => {
      // 尝试获取子商品的子商品列表
      const response = await client[':id'].children.$get({
        param: { id: childGoods1.id }, // 子商品ID
        query: { page: 1, pageSize: 10 }
      });

      expect(response.status).toBe(404);
      const data = await response.json();
      expect(data.code).toBe(404);
      expect(data.message).toContain('父商品不存在');
    });

    it('应该支持排序', async () => {
      // 修改子商品的排序字段
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const goodsRepo = dataSource.getRepository(GoodsMt);

      await goodsRepo.update(childGoods1.id, { sort: 2 });
      await goodsRepo.update(childGoods2.id, { sort: 1 });

      const response = await client[':id'].children.$get({
        param: { id: parentGoods.id },
        query: { page: 1, pageSize: 10, sortBy: 'sort', sortOrder: 'ASC' }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.data[0].id).toBe(childGoods2.id); // sort=1 应该在前
      expect(data.data[1].id).toBe(childGoods1.id); // sort=2 应该在后
    });
  });
});