import { describe, it, expect, beforeEach } from 'vitest';
import { testClient } from 'hono/testing';
import {
  IntegrationTestDatabase,
  setupIntegrationDatabaseHooksWithEntities
} from '@d8d/shared-test-util';
import { IntegrationTestAssertions } from '../utils/integration-test-utils';
import adminAreaRoutes from '../../src/api/admin/areas';
import { AreaEntity, AreaLevel } from '../../src/modules/areas/area.entity';
import { Role, UserEntity } from '@d8d/user-module';
import { File } from '@d8d/file-module';
import { DisabledStatus } from '@d8d/shared-types';
import { TestDataFactory } from '../utils/test-data-factory';
import { AuthService } from '@d8d/auth-module';
import { UserService } from '@d8d/user-module';

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

describe('管理地区API集成测试 (使用hono/testing)', () => {
  let client: ReturnType<typeof testClient<typeof adminAreaRoutes>>;
  let authService: AuthService;
  let userService: UserService;
  let testToken: string;
  let testUser: any;
  let testAreas: AreaEntity[];

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

    // 获取数据源
    const dataSource = await IntegrationTestDatabase.getDataSource();
    if (!dataSource) throw new Error('Database not initialized');

    // 初始化服务
    userService = new UserService(dataSource);
    authService = new AuthService(userService);

    // 创建测试用户并生成token
    testUser = await TestDataFactory.createTestUser(dataSource, {
      username: 'testuser_admin_areas',
      password: 'TestPassword123!',
      email: 'testuser_admin_areas@example.com'
    });

    // 生成测试用户的token
    testToken = authService.generateToken(testUser);

    // 创建测试地区数据
    const province1 = await TestDataFactory.createTestArea(dataSource, {
      name: '北京市',
      level: AreaLevel.PROVINCE,
      isDisabled: DisabledStatus.ENABLED
    });
    const province2 = await TestDataFactory.createTestArea(dataSource, {
      name: '上海市',
      level: AreaLevel.PROVINCE,
      isDisabled: DisabledStatus.ENABLED
    });
    const city1 = await TestDataFactory.createTestArea(dataSource, {
      name: '朝阳区',
      level: AreaLevel.CITY,
      parentId: province1.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const city2 = await TestDataFactory.createTestArea(dataSource, {
      name: '海淀区',
      level: AreaLevel.CITY,
      parentId: province1.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const district1 = await TestDataFactory.createTestArea(dataSource, {
      name: '朝阳区',
      level: AreaLevel.DISTRICT,
      parentId: city1.id,
      isDisabled: DisabledStatus.ENABLED
    });

    testAreas = [province1, province2, city1, city2, district1];
  });

  describe('认证测试', () => {
    it('应该拒绝无认证令牌的请求', async () => {
      const response = await client.index.$get({
        query: {}
      });

      // 应该返回401状态码，因为缺少认证
      expect(response.status).toBe(401);
      if (response.status === 401) {
        const responseData = await response.json();
        expect(responseData.message).toContain('Authorization header missing');
      }
    });

    it('应该拒绝无效认证令牌的请求', async () => {
      const response = await client.index.$get({
        query: {}
      }, {
        headers: {
          'Authorization': 'Bearer invalid.token.here'
        }
      });

      // 应该返回401状态码，因为令牌无效
      expect(response.status).toBe(401);
      if (response.status === 401) {
        const responseData = await response.json();
        expect(responseData.message).toContain('Invalid token');
      }
    });
  });

  describe('地区CRUD操作测试', () => {
    it('应该成功创建地区（使用有效认证令牌）', async () => {
      const areaData = {
        name: '测试省份',
        code: 'test_province_001',
        level: AreaLevel.PROVINCE,
        parentId: null,
        isDisabled: DisabledStatus.ENABLED
      };

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

      // 断言响应
      expect(response.status).toBe(201);
      if (response.status === 201) {
        const responseData = await response.json();
        expect(responseData).toHaveProperty('id');
        expect(responseData.name).toBe(areaData.name);
        expect(responseData.code).toBe(areaData.code);
        expect(responseData.level).toBe(areaData.level);

        // 断言数据库中存在地区
        await IntegrationTestAssertions.expectAreaToExist(areaData.name);
      }
    });

    it('应该成功获取地区列表', async () => {
      const response = await client.index.$get({
        query: {}
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(Array.isArray(responseData.data)).toBe(true);
        expect(responseData.data.length).toBeGreaterThanOrEqual(5); // 至少有5个测试地区
      }
    });

    it('应该成功获取单个地区详情', async () => {
      const testArea = testAreas[0];

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

      expect(response.status).toBe(200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(responseData.id).toBe(testArea.id);
        expect(responseData.name).toBe(testArea.name);
        expect(responseData.level).toBe(testArea.level);
      }
    });

    it('应该返回404当地区不存在时', async () => {
      const response = await client[':id'].$get({
        param: { id: 999999 }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(404);
      if (response.status === 404) {
        const responseData = await response.json();
        expect(responseData.message).toContain('资源不存在');
      }
    });

    it('应该成功更新地区信息', async () => {
      const testArea = testAreas[0];
      const updateData = {
        name: '更新后的北京市',
        code: 'updated_beijing'
      };

      const response = await client[':id'].$put({
        param: { id: testArea.id },
        json: updateData
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(responseData.name).toBe(updateData.name);
        expect(responseData.code).toBe(updateData.code);
      }
    });

    it('应该成功删除地区', async () => {
      const dataSource = await IntegrationTestDatabase.getDataSource();
      if (!dataSource) throw new Error('Database not initialized');

      const testArea = await TestDataFactory.createTestArea(dataSource, {
        name: '待删除地区',
        level: AreaLevel.PROVINCE
      });

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

      IntegrationTestAssertions.expectStatus(response, 204);

      // 验证地区已从数据库中删除
      await IntegrationTestAssertions.expectAreaNotToExist('待删除地区');
    });
  });

  describe('地区搜索测试', () => {
    it('应该能够按名称搜索地区', async () => {
      const response = await client.index.$get({
        query: { keyword: '北京' }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      IntegrationTestAssertions.expectStatus(response, 200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(Array.isArray(responseData.data)).toBe(true);
        expect(responseData.data.length).toBeGreaterThan(0);

        // 验证搜索结果包含正确的地区
        const names = responseData.data.map((area: any) => area.name);
        expect(names).toContain('北京市');
      }
    });

    it('应该能够按代码搜索地区', async () => {
      const response = await client.index.$get({
        query: { keyword: 'area_' }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      IntegrationTestAssertions.expectStatus(response, 200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(responseData.data.length).toBeGreaterThan(0);
      }
    });
  });

  describe('树形结构查询测试', () => {
    it('应该成功获取完整树形结构', async () => {
      const response = await client.tree.$get({}, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

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

        // 验证树形结构包含省份
        const provinceNames = responseData.data.map((area: any) => area.name);
        expect(provinceNames).toContain('北京市');
        expect(provinceNames).toContain('上海市');
      }
    });

    it('应该根据层级获取树形结构', async () => {
      const response = await client.tree.level[':level'].$get({
        param: { level: AreaLevel.PROVINCE }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      IntegrationTestAssertions.expectStatus(response, 200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(responseData).toHaveProperty('success', true);
        expect(responseData).toHaveProperty('data');

        // 验证只返回省级地区
        const provinces = responseData.data;
        expect(provinces.length).toBeGreaterThan(0);
        provinces.forEach((province: any) => {
          expect(province.level).toBe(AreaLevel.PROVINCE);
        });
      }
    });

    it('应该获取指定节点的子树', async () => {
      const province = testAreas.find(area => area.name === '北京市');
      expect(province).toBeDefined();

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

      IntegrationTestAssertions.expectStatus(response, 200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(responseData).toHaveProperty('success', true);
        expect(responseData).toHaveProperty('data');

        // 验证子树包含城市
        const subTree = responseData.data;
        expect(subTree).toBeDefined();
        expect(subTree).toHaveProperty('children');
        if (subTree && subTree.children) {
          const cityNames = subTree.children.map((city: any) => city.name);
          expect(cityNames).toContain('朝阳区');
          expect(cityNames).toContain('海淀区');
        }
      }
    });

    it('应该获取区域路径', async () => {
      const district = testAreas.find(area => area.level === AreaLevel.DISTRICT);
      expect(district).toBeDefined();

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

      IntegrationTestAssertions.expectStatus(response, 200);
      if (response.status === 200) {
        const responseData = await response.json();
        expect(responseData).toHaveProperty('success', true);
        expect(responseData).toHaveProperty('data');

        // 验证路径包含正确的层级
        const path = responseData.data;
        expect(Array.isArray(path)).toBe(true);
        expect(path.length).toBeGreaterThan(0);

        // 路径应该包含从省份到区县的完整路径
        const levels = path.map((area: any) => area.level);
        expect(levels).toContain(AreaLevel.PROVINCE);
        expect(levels).toContain(AreaLevel.CITY);
        expect(levels).toContain(AreaLevel.DISTRICT);
      }
    });
  });

  describe('性能测试', () => {
    it('地区列表查询响应时间应小于200ms', async () => {
      const startTime = Date.now();
      const response = await client.index.$get({
        query: {}
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });
      const endTime = Date.now();
      const responseTime = endTime - startTime;

      IntegrationTestAssertions.expectStatus(response, 200);
      expect(responseTime).toBeLessThan(200); // 响应时间应小于200ms
    });

    it('树形结构查询响应时间应小于300ms', async () => {
      const startTime = Date.now();
      const response = await client.tree.$get({}, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });
      const endTime = Date.now();
      const responseTime = endTime - startTime;

      IntegrationTestAssertions.expectStatus(response, 200);
      expect(responseTime).toBeLessThan(300); // 树形结构查询响应时间应小于300ms
    });
  });
});