import { describe, it, expect, beforeEach, vi, afterEach } 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 { tenantRoutes } from '../../src/routes';
import { TenantEntityMt } from '../../src/entities';

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

describe('租户管理API集成测试', () => {
  let client: ReturnType<typeof testClient<typeof tenantRoutes>>;
  let superAdminToken: string;
  let regularUserToken: string;
  let testUser: UserEntity;
  let superAdminUser: UserEntity;

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

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

    // 创建测试用户
    const userRepository = dataSource.getRepository(UserEntity);
    const roleRepository = dataSource.getRepository(Role);

    // 创建超级管理员用户（ID为1）
    superAdminUser = userRepository.create({
      id: 1,
      username: 'superadmin',
      password: 'hashed_password',
      nickname: '超级管理员',
      status: 1
    });
    await userRepository.save(superAdminUser);

    // 创建普通测试用户
    testUser = userRepository.create({
      username: 'testuser',
      password: 'hashed_password',
      nickname: '测试用户',
      status: 1
    });
    await userRepository.save(testUser);

    // 生成token
    superAdminToken = JWTUtil.generateToken(superAdminUser);
    regularUserToken = JWTUtil.generateToken(testUser);
  });

  afterEach(async () => {
    vi.clearAllMocks();
  });

  describe('创建租户', () => {
    it('超级管理员应该能够创建租户', async () => {
      const response = await client.index.$post({
        json: {
          name: '测试租户',
          code: 'test-tenant',
          contactName: '联系人',
          phone: '13800138000',
          email: 'test@example.com',
          status: 1
        }
      }, {
        headers: {
          Authorization: `Bearer ${superAdminToken}`
        }
      });

      expect(response.status).toBe(201);
      const data = await response.json();
      expect(data.name).toBe('测试租户');
      expect(data.code).toBe('test-tenant');
      expect(data.status).toBe(1);
    });

    it('普通用户不应该能够创建租户', async () => {
      const response = await client.index.$post({
        json: {
          name: '测试租户',
          code: 'test-tenant',
          contactName: '联系人',
          phone: '13800138000',
          email: 'test@example.com',
          status: 1
        }
      }, {
        headers: {
          Authorization: `Bearer ${regularUserToken}`
        }
      });

      expect(response.status).toBe(403);
      const data = await response.json();
      expect(data.message).toContain('Access denied');
    });

    it('未认证用户不应该能够创建租户', async () => {
      const response = await client.index.$post({
        json: {
          name: '测试租户',
          code: 'test-tenant',
          contactName: '联系人',
          phone: '13800138000',
          email: 'test@example.com',
          status: 1
        }
      });

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

  describe('获取租户列表', () => {
    beforeEach(async () => {
      // 创建测试租户数据
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const tenantRepository = dataSource.getRepository(TenantEntityMt);

      await tenantRepository.save([
        {
          name: '租户A',
          code: 'tenant-a',
          contactName: '联系人A',
          phone: '13800138001',
          email: 'a@example.com',
          status: 1,
          createdBy: 1
        },
        {
          name: '租户B',
          code: 'tenant-b',
          contactName: '联系人B',
          phone: '13800138002',
          email: 'b@example.com',
          status: 2,
          createdBy: 1
        }
      ]);
    });

    it('超级管理员应该能够获取租户列表', async () => {
      const response = await client.index.$get({
        query: {}
      }, {
        headers: {
          Authorization: `Bearer ${superAdminToken}`
        }
      });

      console.debug('列表查询响应状态:', response.status);
      if (response.status !== 200) {
        const errorData = await response.json();
        console.debug('错误响应:', errorData);
      }

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.data).toHaveLength(2);
      expect(data.pagination.total).toBe(2);
    });

    it('普通用户不应该能够获取租户列表', async () => {
      const response = await client.index.$get({
        query: {}
      }, {
        headers: {
          Authorization: `Bearer ${regularUserToken}`
        }
      });

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

  describe('获取单个租户', () => {
    let testTenant: TenantEntityMt;

    beforeEach(async () => {
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const tenantRepository = dataSource.getRepository(TenantEntityMt);

      testTenant = await tenantRepository.save({
        name: '测试租户',
        code: 'test-tenant',
        contactName: '联系人',
        phone: '13800138000',
        email: 'test@example.com',
        status: 1,
        createdBy: 1
      });
    });

    it('超级管理员应该能够获取租户详情', async () => {
      const response = await client[':id'].$get({
        param: { id: testTenant.id.toString() }
      }, {
        headers: {
          Authorization: `Bearer ${superAdminToken}`
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.name).toBe('测试租户');
      expect(data.code).toBe('test-tenant');
    });

    it('普通用户不应该能够获取租户详情', async () => {
      const response = await client[':id'].$get({
        param: { id: testTenant.id.toString() }
      }, {
        headers: {
          Authorization: `Bearer ${regularUserToken}`
        }
      });

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

  describe('更新租户', () => {
    let testTenant: TenantEntityMt;

    beforeEach(async () => {
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const tenantRepository = dataSource.getRepository(TenantEntityMt);

      testTenant = await tenantRepository.save({
        name: '测试租户',
        code: 'test-tenant',
        contactName: '联系人',
        phone: '13800138000',
        email: 'test@example.com',
        status: 1,
        createdBy: 1
      });
    });

    it('超级管理员应该能够更新租户', async () => {
      const response = await client[':id'].$put({
        param: { id: testTenant.id.toString() },
        json: {
          name: '更新后的租户',
          contactName: '新联系人',
          phone: '13900139000',
          status: 2
        }
      }, {
        headers: {
          Authorization: `Bearer ${superAdminToken}`
        }
      });

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.name).toBe('更新后的租户');
      expect(data.contactName).toBe('新联系人');
      expect(data.status).toBe(2);
    });

    it('普通用户不应该能够更新租户', async () => {
      const response = await client[':id'].$put({
        param: { id: testTenant.id.toString() },
        json: {
          name: '更新后的租户'
        }
      }, {
        headers: {
          Authorization: `Bearer ${regularUserToken}`
        }
      });

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

  describe('删除租户', () => {
    let testTenant: TenantEntityMt;

    beforeEach(async () => {
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const tenantRepository = dataSource.getRepository(TenantEntityMt);

      testTenant = await tenantRepository.save({
        name: '测试租户',
        code: 'test-tenant',
        contactName: '联系人',
        phone: '13800138000',
        email: 'test@example.com',
        status: 1,
        createdBy: 1
      });
    });

    it('超级管理员应该能够删除租户', async () => {
      const response = await client[':id'].$delete({
        param: { id: testTenant.id.toString() }
      }, {
        headers: {
          Authorization: `Bearer ${superAdminToken}`
        }
      });

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

    it('普通用户不应该能够删除租户', async () => {
      const response = await client[':id'].$delete({
        param: { id: testTenant.id.toString() }
      }, {
        headers: {
          Authorization: `Bearer ${regularUserToken}`
        }
      });

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