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 { UserEntity, Role } from '@d8d/user-module';
import { File } from '@d8d/file-module';
import { Supplier } from '@d8d/supplier-module';
import { Merchant } from '@d8d/merchant-module';
import { publicGoodsRandomRoutes } from '../../src/routes/public-goods-random';
import { Goods, GoodsCategory } from '../../src/entities';

// 设置集成测试钩子
setupIntegrationDatabaseHooksWithEntities([
  UserEntity, Role, Goods, GoodsCategory, File, Supplier, Merchant
])

describe('公开随机商品API集成测试', () => {
  let client: ReturnType<typeof testClient<typeof publicGoodsRandomRoutes>>;
  let testUser: UserEntity;
  let testSupplier: Supplier;
  let testMerchant: Merchant;
  let testCategory1: GoodsCategory;
  let testCategory2: GoodsCategory;

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

    // 获取数据源
    const dataSource = await IntegrationTestDatabase.getDataSource();

    // 创建测试用户
    const userRepository = dataSource.getRepository(UserEntity);
    testUser = userRepository.create({
      username: `test_user_${Math.floor(Math.random() * 100000)}`,
      password: 'test_password',
      nickname: '测试用户',
      registrationSource: 'web'
    });
    await userRepository.save(testUser);

    // 创建测试供应商
    const supplierRepository = dataSource.getRepository(Supplier);
    testSupplier = supplierRepository.create({
      name: '测试供应商',
      username: `test_supplier_${Math.floor(Math.random() * 100000)}`,
      password: 'password123',
      phone: '13800138000',
      realname: '测试供应商',
      state: 1,
      createdBy: testUser.id
    });
    await supplierRepository.save(testSupplier);

    // 创建测试商户
    const merchantRepository = dataSource.getRepository(Merchant);
    testMerchant = merchantRepository.create({
      name: '测试商户',
      username: `test_merchant_${Math.floor(Math.random() * 100000)}`,
      password: 'password123',
      phone: '13800138001',
      realname: '测试商户',
      state: 1,
      createdBy: testUser.id
    });
    await merchantRepository.save(testMerchant);

    // 创建测试商品分类
    const categoryRepository = dataSource.getRepository(GoodsCategory);
    testCategory1 = categoryRepository.create({
      name: '测试分类1',
      parentId: 0,
      level: 1,
      state: 1,
      createdBy: testUser.id
    });
    await categoryRepository.save(testCategory1);

    testCategory2 = categoryRepository.create({
      name: '测试分类2',
      parentId: 0,
      level: 1,
      state: 1,
      createdBy: testUser.id
    });
    await categoryRepository.save(testCategory2);

    // 创建测试商品
    const goodsRepository = dataSource.getRepository(Goods);

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

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

    const activeGoods3 = goodsRepository.create({
      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,
      lowestBuy: 1,
      createdBy: testUser.id
    });
    await goodsRepository.save(activeGoods3);

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

  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);
    });
  });
});