import { describe, it, expect, beforeEach } from 'vitest';
import { testClient } from 'hono/testing';
import {
  IntegrationTestDatabase,
  setupIntegrationDatabaseHooksWithEntities,
  IntegrationTestAssertions
} from '@d8d/shared-test-util';
import { areaRoutes } from '../../src/api/areas';
import { AreaEntity, AreaLevel } from '../../src/modules/areas/area.entity';
import { DisabledStatus } from '@d8d/shared-types';
import { TestDataFactory } from '../utils/test-data-factory';

// 设置集成测试钩子
setupIntegrationDatabaseHooksWithEntities([AreaEntity])

describe('区域API集成测试', () => {
  let client: ReturnType<typeof testClient<typeof areaRoutes>>;
  let testAreas: AreaEntity[];

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

    // 创建测试数据
    const dataSource = await IntegrationTestDatabase.getDataSource();

    // 创建启用状态的省份
    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 province3 = await TestDataFactory.createTestArea(dataSource, {
      name: '广东省',
      level: AreaLevel.PROVINCE,
      isDisabled: DisabledStatus.ENABLED
    });

    // 创建启用状态的城市
    const city11 = await TestDataFactory.createTestArea(dataSource, {
      name: '北京市',
      level: AreaLevel.CITY,
      parentId: province1.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const city12 = await TestDataFactory.createTestArea(dataSource, {
      name: '朝阳区',
      level: AreaLevel.CITY,
      parentId: province1.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const city13 = await TestDataFactory.createTestArea(dataSource, {
      name: '海淀区',
      level: AreaLevel.CITY,
      parentId: province1.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const city21 = await TestDataFactory.createTestArea(dataSource, {
      name: '上海市',
      level: AreaLevel.CITY,
      parentId: province2.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const city22 = await TestDataFactory.createTestArea(dataSource, {
      name: '浦东新区',
      level: AreaLevel.CITY,
      parentId: province2.id,
      isDisabled: DisabledStatus.ENABLED
    });

    // 创建启用状态的区县
    const district101 = await TestDataFactory.createTestArea(dataSource, {
      name: '朝阳区',
      level: AreaLevel.DISTRICT,
      parentId: city12.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const district102 = await TestDataFactory.createTestArea(dataSource, {
      name: '海淀区',
      level: AreaLevel.DISTRICT,
      parentId: city13.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const district103 = await TestDataFactory.createTestArea(dataSource, {
      name: '西城区',
      level: AreaLevel.DISTRICT,
      parentId: city12.id,
      isDisabled: DisabledStatus.ENABLED
    });
    const district201 = await TestDataFactory.createTestArea(dataSource, {
      name: '浦东新区',
      level: AreaLevel.DISTRICT,
      parentId: city22.id,
      isDisabled: DisabledStatus.ENABLED
    });

    // 创建禁用状态的区域用于测试过滤
    const disabledProvince = await TestDataFactory.createTestArea(dataSource, {
      name: '禁用省份',
      level: AreaLevel.PROVINCE,
      isDisabled: DisabledStatus.DISABLED
    });
    const disabledCity = await TestDataFactory.createTestArea(dataSource, {
      name: '禁用城市',
      level: AreaLevel.CITY,
      parentId: province3.id,
      isDisabled: DisabledStatus.DISABLED
    });
    const disabledDistrict = await TestDataFactory.createTestArea(dataSource, {
      name: '禁用区县',
      level: AreaLevel.DISTRICT,
      parentId: city12.id,
      isDisabled: DisabledStatus.DISABLED
    });

    testAreas = [
      province1, province2, province3,
      city11, city12, city13, city21, city22,
      district101, district102, district103, district201,
      disabledProvince, disabledCity, disabledDistrict
    ];
  });

  describe('GET /areas/provinces', () => {
    it('应该成功获取启用状态的省份列表', async () => {
      const response = await client.provinces.$get({
        query: { page: 1, pageSize: 50 }
      });

      IntegrationTestAssertions.expectStatus(response, 200);

      if (response.status === 200) {
        const data = await response.json();

        // 验证响应数据格式
        expect(data).toHaveProperty('success', true);
        expect(data).toHaveProperty('data');
        expect(data.data).toHaveProperty('provinces');
        expect(data.data).toHaveProperty('pagination');

        // 验证只返回启用状态的省份
        const provinces = data.data.provinces;
        expect(provinces).toHaveLength(3); // 只返回3个启用状态的省份

        // 验证不包含禁用状态的省份
        const disabledProvince = provinces.find((p: any) => p.isDisabled === DisabledStatus.DISABLED);
        expect(disabledProvince).toBeUndefined();

        // 验证分页信息
        expect(data.data.pagination).toEqual({
          page: 1,
          pageSize: 50,
          total: 3,
          totalPages: 1
        });
      }
    });

    it('应该正确处理分页参数', async () => {
      const response = await client.provinces.$get({
        query: { page: 1, pageSize: 2 }
      });

      IntegrationTestAssertions.expectStatus(response, 200);

      if (response.status === 200) {
        const data = await response.json();

        // 验证分页结果
        expect(data.data.provinces).toHaveLength(2);
        expect(data.data.pagination).toEqual({
          page: 1,
          pageSize: 2,
          total: 3,
          totalPages: 2
        });
      }
    });
  });

  describe('GET /areas/cities', () => {
    it('应该成功获取指定省份下启用状态的城市列表', async () => {
      const response = await client.cities.$get({
        query: { provinceId: testAreas[0].id, page: 1, pageSize: 50 }
      });

      IntegrationTestAssertions.expectStatus(response, 200);

      if (response.status === 200) {
        const data = await response.json();

        // 验证响应数据格式
        expect(data).toHaveProperty('success', true);
        expect(data).toHaveProperty('data');
        expect(data.data).toHaveProperty('cities');

        // 验证只返回启用状态的城市
        const cities = data.data.cities;
        expect(cities).toHaveLength(3); // 北京市下有3个启用状态的城市

        // 验证城市数据正确
        const cityNames = cities.map((c: any) => c.name);
        expect(cityNames).toContain('北京市');
        expect(cityNames).toContain('朝阳区');
        expect(cityNames).toContain('海淀区');

        // 验证不包含禁用状态的城市
        const disabledCity = cities.find((c: any) => c.name === '禁用城市');
        expect(disabledCity).toBeUndefined();
      }
    });

    it('应该处理不存在的省份ID', async () => {
      const response = await client.cities.$get({
        query: { provinceId: 999, page: 1, pageSize: 50 }
      });

      IntegrationTestAssertions.expectStatus(response, 200);

      if (response.status === 200) {
        const data = await response.json();

        // 不存在的省份应该返回空数组
        expect(data.data.cities).toHaveLength(0);
      }
    });

    it('应该验证省份ID参数', async () => {
      const response = await client.cities.$get({
        query: { provinceId: 0, page: 1, pageSize: 50 }
      });

      // 参数验证应该返回400错误
      IntegrationTestAssertions.expectStatus(response, 400);
    });
  });

  describe('GET /areas/districts', () => {
    it('应该成功获取指定城市下启用状态的区县列表', async () => {
      // 找到朝阳区城市对象
      const chaoyangCity = testAreas.find(area => area.name === '朝阳区' && area.level === AreaLevel.CITY);
      expect(chaoyangCity).toBeDefined();

      const response = await client.districts.$get({
        query: { cityId: chaoyangCity!.id, page: 1, pageSize: 50 }
      });

      IntegrationTestAssertions.expectStatus(response, 200);

      if (response.status === 200) {
        const data = await response.json();

        // 验证响应数据格式
        expect(data).toHaveProperty('success', true);
        expect(data).toHaveProperty('data');
        expect(data.data).toHaveProperty('districts');

        // 验证只返回启用状态的区县
        const districts = data.data.districts;
        expect(districts).toHaveLength(2); // 朝阳区下有2个启用状态的区县

        // 验证区县数据正确
        const districtNames = districts.map((d: any) => d.name);
        expect(districtNames).toContain('朝阳区');
        expect(districtNames).toContain('西城区');

        // 验证不包含禁用状态的区县
        const disabledDistrict = districts.find((d: any) => d.name === '禁用区县');
        expect(disabledDistrict).toBeUndefined();
      }
    });

    it('应该处理不存在的城市ID', async () => {
      const response = await client.districts.$get({
        query: { cityId: 999, page: 1, pageSize: 50 }
      });

      IntegrationTestAssertions.expectStatus(response, 200);

      if (response.status === 200) {
        const data = await response.json();

        // 不存在的城市应该返回空数组
        expect(data.data.districts).toHaveLength(0);
      }
    });

    it('应该验证城市ID参数', async () => {
      const response = await client.districts.$get({
        query: { cityId: 0, page: 1, pageSize: 50 }
      });

      // 参数验证应该返回400错误
      IntegrationTestAssertions.expectStatus(response, 400);
    });
  });

  describe('过滤禁用状态验证', () => {
    it('应该确保所有API只返回启用状态的区域', async () => {
      // 测试省份API
      const provincesResponse = await client.provinces.$get({
        query: { page: 1, pageSize: 50 }
      });
      IntegrationTestAssertions.expectStatus(provincesResponse, 200);
      const provincesData = await provincesResponse.json();

      // 验证省份不包含禁用状态
      if ('data' in provincesData) {
        const provinces = provincesData.data.provinces;
        const hasDisabledProvince = provinces.some((p: any) => p.isDisabled === DisabledStatus.DISABLED);
        expect(hasDisabledProvince).toBe(false);
      }

      // 测试城市API
      const citiesResponse = await client.cities.$get({
        query: { provinceId: testAreas[0].id, page: 1, pageSize: 50 }
      });
      IntegrationTestAssertions.expectStatus(citiesResponse, 200);
      const citiesData = await citiesResponse.json();

      // 验证城市不包含禁用状态
      if ('data' in citiesData) {
        const cities = citiesData.data.cities;
        const hasDisabledCity = cities.some((c: any) => c.isDisabled === DisabledStatus.DISABLED);
        expect(hasDisabledCity).toBe(false);
      }

      // 测试区县API
      const chaoyangCity = testAreas.find(area => area.name === '朝阳区' && area.level === AreaLevel.CITY);
      const districtsResponse = await client.districts.$get({
        query: { cityId: chaoyangCity!.id, page: 1, pageSize: 50 }
      });
      IntegrationTestAssertions.expectStatus(districtsResponse, 200);
      const districtsData = await districtsResponse.json();

      // 验证区县不包含禁用状态
      if ('data' in districtsData) {
        const districts = districtsData.data.districts;
        const hasDisabledDistrict = districts.some((d: any) => d.isDisabled === DisabledStatus.DISABLED);
        expect(hasDisabledDistrict).toBe(false);
      }
    });
  });
});