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 channelRoutes from '../../src/routes/channel.routes';
import { Channel } from '../../src/entities/channel.entity';

// 设置集成测试钩子
setupIntegrationDatabaseHooksWithEntities([UserEntity, File, Role, Channel])

describe('渠道管理API集成测试', () => {
  let client: ReturnType<typeof testClient<typeof channelRoutes>>;
  let testToken: string;
  let testUser: UserEntity;

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

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

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

    // 生成测试用户的token
    testToken = JWTUtil.generateToken({
      id: testUser.id,
      username: testUser.username,
      roles: [{name:'user'}]
    });
  });

  describe('POST /channel/createChannel', () => {
    it('应该成功创建渠道', async () => {
      const createData = {
        channelName: '微信小程序渠道',
        channelType: '小程序',
        contactPerson: '张三',
        contactPhone: '13800138000',
        description: '微信小程序渠道描述'
      };

      const response = await client.createChannel.$post({
        json: createData
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      console.debug('创建渠道响应状态:', response.status);
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.channelName).toBe(createData.channelName);
        expect(data.channelType).toBe(createData.channelType);
      }
    });

    it('应该验证渠道名称重复', async () => {
      // 先创建一个渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);
      const existingChannel = channelRepository.create({
        channelName: '微信小程序渠道',
        channelType: '小程序',
        contactPerson: '张三',
        contactPhone: '13800138000',
        status: 1
      });
      await channelRepository.save(existingChannel);

      // 尝试创建同名渠道
      const createData = {
        channelName: '微信小程序渠道', // 重复的名称
        channelType: '小程序',
        contactPerson: '李四',
        contactPhone: '13900139000'
      };

      const response = await client.createChannel.$post({
        json: createData
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(400);
      if (response.status === 400) {
        const data = await response.json();
        expect(data.message).toContain('渠道名称已存在');
      }
    });

    it('应该拒绝未认证用户的访问', async () => {
      const createData = {
        channelName: '测试渠道',
        channelType: '测试'
      };

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

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

  describe('POST /channel/deleteChannel', () => {
    it('应该成功删除渠道', async () => {
      // 先创建一个渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);
      const testChannel = channelRepository.create({
        channelName: `待删除渠道_${Date.now()}`,
        channelType: '测试',
        contactPerson: '张三',
        contactPhone: '13800138000',
        status: 1
      });
      await channelRepository.save(testChannel);

      const deleteData = {
        id: testChannel.id
      };

      const response = await client.deleteChannel.$post({
        json: deleteData
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      console.debug('删除渠道响应状态:', response.status);
      expect(response.status).toBe(200);

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

      // 验证渠道状态变为0（软删除）
      const deletedChannel = await channelRepository.findOne({
        where: { id: testChannel.id }
      });
      expect(deletedChannel?.status).toBe(0);
    });
  });

  describe('POST /channel/updateChannel', () => {
    it('应该成功更新渠道', async () => {
      // 先创建一个渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);
      const testChannel = channelRepository.create({
        channelName: `原始渠道_${Date.now()}`,
        channelType: '原始类型',
        contactPerson: '张三',
        contactPhone: '13800138000',
        status: 1
      });
      await channelRepository.save(testChannel);

      const updateData = {
        id: testChannel.id,
        channelName: '更新后的渠道名称',
        channelType: '更新类型',
        contactPerson: '李四',
        contactPhone: '13900139000'
      };

      const response = await client.updateChannel.$post({
        json: updateData
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      console.debug('更新渠道响应状态:', response.status);

      if (response.status !== 200) {
        const errorData = await response.json();
        console.debug('更新渠道错误:', errorData);
      }

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

      if (response.status === 200) {
        const data = await response.json();
        expect(data.channelName).toBe(updateData.channelName);
        expect(data.channelType).toBe(updateData.channelType);
      }

      // 验证渠道已更新
      const updatedChannel = await channelRepository.findOne({
        where: { id: testChannel.id }
      });
      expect(updatedChannel?.channelName).toBe(updateData.channelName);
      expect(updatedChannel?.channelType).toBe(updateData.channelType);
    });

    it('应该验证更新时的渠道名称重复', async () => {
      // 创建两个渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);

      const channel1 = channelRepository.create({
        channelName: '渠道A',
        channelType: '类型A',
        status: 1
      });
      await channelRepository.save(channel1);

      const channel2 = channelRepository.create({
        channelName: '渠道B',
        channelType: '类型B',
        status: 1
      });
      await channelRepository.save(channel2);

      // 尝试将渠道B的名称改为渠道A的名称
      const updateData = {
        id: channel2.id,
        channelName: '渠道A' // 重复的名称
      };

      const response = await client.updateChannel.$post({
        json: updateData
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(400);
      if (response.status === 400) {
        const data = await response.json();
        expect(data.message).toContain('渠道名称已存在');
      }
    });
  });

  describe('GET /channel/getAllChannels', () => {
    it('应该返回渠道列表', async () => {
      // 创建一些测试渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);

      for (let i = 0; i < 3; i++) {
        const channel = channelRepository.create({
          channelName: `测试渠道${i}`,
          channelType: '测试',
          contactPerson: `联系人${i}`,
          contactPhone: `1380013800${i}`,
          status: 1
        });
        await channelRepository.save(channel);
      }

      const response = await client.getAllChannels.$get({
        query: { skip: 0, take: 10 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      console.debug('渠道列表响应状态:', response.status);
      expect(response.status).toBe(200);

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

    it('应该支持分页参数', async () => {
      const response = await client.getAllChannels.$get({
        query: { skip: 0, take: 5 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

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

    it('应该过滤已删除的渠道（status=0）', async () => {
      // 创建测试数据：3个正常渠道，2个已删除渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);

      // 创建3个正常渠道
      for (let i = 1; i <= 3; i++) {
        const channel = channelRepository.create({
          channelName: `正常渠道${i}`,
          channelType: `类型${i}`,
          contactPerson: `联系人${i}`,
          contactPhone: `1380013800${i}`,
          status: 1
        });
        await channelRepository.save(channel);
      }

      // 创建2个已删除渠道
      for (let i = 4; i <= 5; i++) {
        const channel = channelRepository.create({
          channelName: `已删除渠道${i}`,
          channelType: `类型${i}`,
          contactPerson: `联系人${i}`,
          contactPhone: `1380013800${i}`,
          status: 0
        });
        await channelRepository.save(channel);
      }

      const response = await client.getAllChannels.$get({
        query: { skip: 0, take: 10 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

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

      if (response.status === 200) {
        const data = await response.json();
        // 应该只返回3个正常渠道，不返回已删除的渠道
        expect(data.data).toHaveLength(3);
        expect(data.total).toBe(3);

        // 验证返回的都是正常渠道
        data.data.forEach((channel: any) => {
          expect(channel.status).toBe(1);
          expect(channel.channelName).toMatch(/^正常渠道/);
        });
      }
    });
  });

  describe('GET /channel/searchChannels', () => {
    it('应该按名称搜索渠道', async () => {
      // 创建测试渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);

      const channel = channelRepository.create({
        channelName: '微信小程序搜索测试',
        channelType: '小程序',
        contactPerson: '张三',
        contactPhone: '13800138000',
        status: 1
      });
      await channelRepository.save(channel);

      const response = await client.searchChannels.$get({
        query: { name: '微信', skip: 0, take: 10 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      console.debug('搜索渠道响应状态:', response.status);
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data.length).toBeGreaterThan(0);
        expect(data.data[0].channelName).toContain('微信');
      }
    });

    it('应该过滤已删除的渠道（搜索时）', async () => {
      // 创建测试数据
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);

      // 创建正常渠道
      const normalChannel = channelRepository.create({
        channelName: '测试搜索渠道正常',
        channelType: '正常类型',
        contactPerson: '张三',
        contactPhone: '13800138000',
        status: 1
      });
      await channelRepository.save(normalChannel);

      // 创建已删除的渠道（不同名称）
      const deletedChannel = channelRepository.create({
        channelName: '测试搜索渠道已删除',
        channelType: '删除类型',
        contactPerson: '李四',
        contactPhone: '13900139000',
        status: 0
      });
      await channelRepository.save(deletedChannel);

      const response = await client.searchChannels.$get({
        query: { name: '测试搜索', skip: 0, take: 10 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

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

      if (response.status === 200) {
        const data = await response.json();
        // 应该只返回1个正常渠道，不返回已删除的渠道
        expect(data.data).toHaveLength(1);
        expect(data.total).toBe(1);
        expect(data.data[0].channelName).toBe('测试搜索渠道正常');
        expect(data.data[0].status).toBe(1);
        expect(data.data[0].contactPerson).toBe('张三'); // 正常渠道的联系人
      }
    });
  });

  describe('GET /channel/getChannel/:id', () => {
    it('应该返回指定渠道的详情', async () => {
      // 先创建一个渠道
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const channelRepository = dataSource.getRepository(Channel);
      const testChannel = channelRepository.create({
        channelName: `详情测试渠道_${Date.now()}`,
        channelType: '测试',
        contactPerson: '张三',
        contactPhone: '13800138000',
        status: 1
      });
      await channelRepository.save(testChannel);

      const response = await client.getChannel[':id'].$get({
        param: { id: testChannel.id }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      console.debug('渠道详情响应状态:', response.status);
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data!.id).toBe(testChannel.id);
        expect(data!.channelName).toBe(testChannel.channelName);
      }
    });

    it('应该处理不存在的渠道', async () => {
      const response = await client.getChannel[':id'].$get({
        param: { id: 999999 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

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