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

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

    // 创建测试商品
    // 创建可用状态的商品
    const activeGoods1 = 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,
      stock: 100
    });

    const activeGoods2 = 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,
      stock: 50
    });

    const activeGoods3 = await testFactory.createTestGoods(testUser.id, {
      name: '可用商品3',
      price: 300.00,
      costPrice: 240.00,
      categoryId1: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.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: testCategory.id,
      categoryId2: testCategory.id,
      categoryId3: testCategory.id,
      supplierId: testSupplier.id,
      merchantId: testMerchant.id,
      state: 2,
      stock: 10
    });
  });

  describe('GET /goods', () => {
    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);
        });

        // 验证不包含不可用状态的商品
        const inactiveGoodsInResponse = data.data.find((goods: any) => goods.state === 2);
        expect(inactiveGoodsInResponse).toBeUndefined();
      }
    });

    it('应该支持按名称搜索', async () => {
      const response = await client.index.$get({
        query: { keyword: '可用商品1' }
      });

      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.name).toContain('可用商品1');
          expect(goods.state).toBe(1);
        });
      }
    });

    it('应该支持按分类过滤', async () => {
      const response = await client.index.$get({
        query: { filters: JSON.stringify({ categoryId1: testCategory.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(testCategory.id);
          expect(goods.state).toBe(1);
        });
      }
    });

    it('应该支持按商品类型过滤', async () => {
      const response = await client.index.$get({
        query: { filters: JSON.stringify({ goodsType: 2 }) }
      });

      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.goodsType).toBe(2);
          expect(goods.state).toBe(1);
        });
      }
    });

    it('应该支持分页查询', async () => {
      const response = await client.index.$get({
        query: { page: 1, pageSize: 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: {}
      });

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

  describe('GET /goods/:id', () => {
    it('应该返回指定商品的详情', async () => {
      // 先获取一个可用商品的ID
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const goodsRepository = dataSource.getRepository(GoodsMt);
      const activeGoods = await goodsRepository.findOne({
        where: { state: 1 }
      });

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

        console.debug('公开商品详情响应状态:', response.status);
        expect(response.status).toBe(200);

        if (response.status === 200) {
          const data = await response.json();
          expect(data.id).toBe(activeGoods.id);
          expect(data.name).toBe(activeGoods.name);
          expect(data.state).toBe(1); // 确保是可用状态
        }
      }
    });

    it('应该拒绝访问不可用状态的商品', async () => {
      // 先获取一个不可用商品的ID
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const goodsRepository = dataSource.getRepository(GoodsMt);
      const inactiveGoods = await goodsRepository.findOne({
        where: { state: 2 }
      });

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

        expect(response.status).toBe(404); // 不可用状态的商品应该返回404
      }
    });

    it('应该处理不存在的商品', async () => {
      const response = await client[':id'].$get({
        param: { id: 999999 }
      });

      expect(response.status).toBe(404);
    });
  });

  describe('POST /goods', () => {
    it('应该拒绝创建商品操作', async () => {
      const createData = {
        name: '尝试创建商品',
        price: 100.00,
        categoryId1: testCategory.id,
        state: 1
      };

      const response = await client.index.$post({
        json: createData
      });

      expect(response.status).toBe(404); // 只读模式下路由不存在
    });
  });

  describe('PUT /goods/:id', () => {
    it('应该拒绝更新商品操作', async () => {
      // 先获取一个可用商品的ID
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const goodsRepository = dataSource.getRepository(GoodsMt);
      const activeGoods = await goodsRepository.findOne({
        where: { state: 1 }
      });

      if (activeGoods) {
        const updateData = {
          name: '尝试更新商品'
        };

        const response = await client[':id'].$put({
          param: { id: activeGoods.id },
          json: updateData
        });

        expect(response.status).toBe(404); // 只读模式下路由不存在
      }
    });
  });

  describe('DELETE /goods/:id', () => {
    it('应该拒绝删除商品操作', async () => {
      // 先获取一个可用商品的ID
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const goodsRepository = dataSource.getRepository(GoodsMt);
      const activeGoods = await goodsRepository.findOne({
        where: { state: 1 }
      });

      if (activeGoods) {
        const response = await client[':id'].$delete({
          param: { id: activeGoods.id }
        });

        expect(response.status).toBe(404); // 只读模式下路由不存在
      }
    });
  });

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

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

    it('应该验证只支持查询操作', async () => {
      // 测试所有非查询操作都应该被拒绝
      const createResponse = await client.index.$post({
        json: { name: '测试' }
      });
      expect(createResponse.status).toBe(404);

      const updateResponse = await client[':id'].$put({
        param: { id: 1 },
        json: { name: '测试' }
      });
      expect(updateResponse.status).toBe(404);

      const deleteResponse = await client[':id'].$delete({
        param: { id: 1 }
      });
      expect(deleteResponse.status).toBe(404);
    });
  });

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