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 { publicGoodsRandomRoutesMt } from '../../src/routes/public-goods-random.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 publicGoodsRandomRoutesMt>>;
  let testUser: UserEntityMt;
  let testSupplier: SupplierMt;
  let testMerchant: MerchantMt;
  let testCategory1: GoodsCategoryMt;
  let testCategory2: GoodsCategoryMt;
  let testFactory: GoodsTestFactory;

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

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

    // 使用测试工厂创建测试数据
    testUser = await testFactory.createTestUser();
    testSupplier = await testFactory.createTestSupplier(testUser.id);
    testMerchant = await testFactory.createTestMerchant(testUser.id);
    testCategory1 = await testFactory.createTestCategory(testUser.id, { name: '测试分类1' });
    testCategory2 = await testFactory.createTestCategory(testUser.id, { name: '测试分类2' });

    // 创建测试商品
    // 创建可用状态的商品
    const activeGoods1 = await testFactory.createTestGoods(testUser.id, {
      name: '可用商品1',
      price: 100.00,
      costPrice: 80.00,
      categoryId1: testCategory1.id,
      categoryId2: testCategory1.id,
      categoryId3: testCategory1.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      stock: 100
    });

    const activeGoods2 = await testFactory.createTestGoods(testUser.id, {
      name: '可用商品2',
      price: 200.00,
      costPrice: 160.00,
      categoryId1: testCategory2.id,
      categoryId2: testCategory2.id,
      categoryId3: testCategory2.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      stock: 50
    });

    const activeGoods3 = await testFactory.createTestGoods(testUser.id, {
      name: '可用商品3',
      price: 300.00,
      costPrice: 240.00,
      categoryId1: testCategory1.id,
      categoryId2: testCategory1.id,
      categoryId3: testCategory1.id,
      goodsType: 2,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 1,
      stock: 30
    });

    // 创建不可用状态的商品（不应该被随机查询返回）
    const inactiveGoods = await testFactory.createTestGoods(testUser.id, {
      name: '不可用商品',
      price: 400.00,
      costPrice: 320.00,
      categoryId1: testCategory1.id,
      categoryId2: testCategory1.id,
      categoryId3: testCategory1.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 2,
      stock: 10
    });
  });

  describe('GET /goods/random', () => {
    it('应该返回随机商品列表', async () => {
      const response = await client.index.$get({
        query: {}
      });

      console.debug('随机商品列表响应状态:', response.status);
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data).toHaveProperty('data');
        expect(Array.isArray(data.data)).toBe(true);

        // 验证只返回可用状态的商品
        data.data.forEach((goods: any) => {
          expect(goods.state).toBe(1);
        });
      }
    });

    it('应该支持按分类过滤', async () => {
      const response = await client.index.$get({
        query: { categoryId: testCategory1.id }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(Array.isArray(data.data)).toBe(true);

        // 验证只返回指定分类的商品
        data.data.forEach((goods: any) => {
          expect(goods.categoryId1).toBe(testCategory1.id);
          expect(goods.state).toBe(1);
        });
      }
    });

    it('应该支持限制返回数量', async () => {
      const response = await client.index.$get({
        query: { limit: 2 }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(Array.isArray(data.data)).toBe(true);
        expect(data.data.length).toBeLessThanOrEqual(2);

        // 验证只返回可用状态的商品
        data.data.forEach((goods: any) => {
          expect(goods.state).toBe(1);
        });
      }
    });

    it('应该支持包含图片选项', async () => {
      const response = await client.index.$get({
        query: { includeImages: true }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(Array.isArray(data.data)).toBe(true);

        // 验证返回的商品数据包含图片关联信息
        data.data.forEach((goods: any) => {
          expect(goods.state).toBe(1);
          // 注意：实际图片数据需要先创建文件实体才能测试
        });
      }
    });

    it('应该正确处理不存在的分类', async () => {
      const response = await client.index.$get({
        query: { categoryId: 999999 }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(Array.isArray(data.data)).toBe(true);
        // 不存在的分类应该返回空数组
        expect(data.data.length).toBe(0);
      }
    });
  });

  describe('随机商品关联关系测试', () => {
    it('应该正确加载商品关联关系', async () => {
      const response = await client.index.$get({
        query: {}
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(Array.isArray(data.data)).toBe(true);

        // 验证至少返回一个商品
        if (data.data.length > 0) {
          const goods = data.data[0];

          // 验证基础字段
          expect(goods).toHaveProperty('id');
          expect(goods).toHaveProperty('name');
          expect(goods).toHaveProperty('price');
          expect(goods).toHaveProperty('state', 1);

          // 验证关联关系字段存在
          expect(goods).toHaveProperty('category1');
          expect(goods).toHaveProperty('supplier');
          expect(goods).toHaveProperty('merchant');
        }
      }
    });
  });

  describe('随机商品排序测试', () => {
    it('应该返回随机排序的商品', async () => {
      // 多次请求验证排序的随机性
      const responses = await Promise.all([
        client.index.$get({ query: {} }),
        client.index.$get({ query: {} }),
        client.index.$get({ query: {} })
      ]);

      // 验证所有请求都成功
      responses.forEach((response: any) => {
        expect(response.status).toBe(200);
      });

      // 提取所有商品ID
      const allGoodsIds: number[] = [];
      for (const response of responses) {
        if (response.status === 200) {
          const data = await response.json();
          data.data.forEach((goods: any) => {
            allGoodsIds.push(goods.id);
          });
        }
      }

      // 验证返回了商品（可能有重复，因为是随机）
      expect(allGoodsIds.length).toBeGreaterThan(0);
    });
  });
});