import { IntegrationTestDatabase } from './integration-test-db';
import { EntityTarget, ObjectLiteral } from 'typeorm';

/**
 * 测试数据工厂
 * 用于创建多租户测试数据，减少重复代码
 */
export class TestDataFactory {
  /**
   * 创建测试用户
   */
  static async createTestUser(overrides: Partial<any> = {}): Promise<any> {
    const dataSource = await IntegrationTestDatabase.getDataSource();
    const userRepository = dataSource.getRepository('UserEntityMt');

    const defaultUser = {
      username: `test_user_${Date.now()}`,
      password: 'test_password',
      nickname: '测试用户',
      registrationSource: 'web',
      tenantId: 1
    };

    const userData = { ...defaultUser, ...overrides };
    const user = userRepository.create(userData);
    return await userRepository.save(user);
  }

  /**
   * 创建测试地区数据
   */
  static async createTestArea(overrides: Partial<any> = {}): Promise<any> {
    const dataSource = await IntegrationTestDatabase.getDataSource();
    const areaRepository = dataSource.getRepository('AreaEntityMt');

    const defaultArea = {
      name: '测试地区',
      code: '110000',
      level: 1,
      parentId: null,
      tenantId: 1
    };

    const areaData = { ...defaultArea, ...overrides };
    const area = areaRepository.create(areaData);
    return await areaRepository.save(area);
  }

  /**
   * 创建测试省份数据
   */
  static async createTestProvince(overrides: Partial<any> = {}): Promise<any> {
    return await this.createTestArea({
      name: '北京市',
      code: '110000',
      level: 1, // PROVINCE
      parentId: null,
      ...overrides
    });
  }

  /**
   * 创建测试城市数据
   */
  static async createTestCity(provinceId: number, overrides: Partial<any> = {}): Promise<any> {
    return await this.createTestArea({
      name: '北京市',
      code: '110100',
      level: 2, // CITY
      parentId: provinceId,
      ...overrides
    });
  }

  /**
   * 创建测试区县数据
   */
  static async createTestDistrict(cityId: number, overrides: Partial<any> = {}): Promise<any> {
    return await this.createTestArea({
      name: '朝阳区',
      code: '110105',
      level: 3, // DISTRICT
      parentId: cityId,
      ...overrides
    });
  }

  /**
   * 创建测试配送地址数据
   */
  static async createTestDeliveryAddress(
    userId: number,
    provinceId: number,
    cityId: number,
    districtId: number,
    overrides: Partial<any> = {}
  ): Promise<any> {
    const dataSource = await IntegrationTestDatabase.getDataSource();
    const deliveryAddressRepository = dataSource.getRepository('DeliveryAddressMt');

    const defaultAddress = {
      userId,
      name: '测试收货人',
      phone: '13800138000',
      address: '测试详细地址',
      receiverProvince: provinceId,
      receiverCity: cityId,
      receiverDistrict: districtId,
      receiverTown: 1,
      state: 1,
      isDefault: 0,
      createdBy: userId,
      tenantId: 1
    };

    const addressData = { ...defaultAddress, ...overrides };
    const address = deliveryAddressRepository.create(addressData);
    return await deliveryAddressRepository.save(address);
  }

  /**
   * 创建完整的测试数据集合
   */
  static async createTestDataSet(tenantId: number = 1): Promise<{
    user: any;
    otherUser: any;
    province: any;
    city: any;
    district: any;
  }> {
    // 创建测试用户
    const user = await this.createTestUser({ tenantId });
    const otherUser = await this.createTestUser({
      username: `other_user_${Date.now()}`,
      nickname: '其他用户',
      tenantId
    });

    // 创建测试地区数据
    const province = await this.createTestProvince({ tenantId });
    const city = await this.createTestCity(province.id, { tenantId });
    const district = await this.createTestDistrict(city.id, { tenantId });

    return {
      user,
      otherUser,
      province,
      city,
      district
    };
  }

  /**
   * 通用实体创建方法
   */
  static async createEntity<T extends ObjectLiteral>(
    entity: EntityTarget<T>,
    data: Partial<T>
  ): Promise<T> {
    const dataSource = await IntegrationTestDatabase.getDataSource();
    const repository = dataSource.getRepository(entity);
    const entityInstance = repository.create(data as T);
    return await repository.save(entityInstance);
  }

  /**
   * 批量创建实体
   */
  static async createEntities<T extends ObjectLiteral>(
    entity: EntityTarget<T>,
    dataArray: Partial<T>[]
  ): Promise<T[]> {
    const dataSource = await IntegrationTestDatabase.getDataSource();
    const repository = dataSource.getRepository(entity);
    const entities = dataArray.map(data => repository.create(data as T));
    return await repository.save(entities);
  }

  /**
   * 清理测试数据
   */
  static async cleanupTestData(entities: EntityTarget<any>[]): Promise<void> {
    const dataSource = await IntegrationTestDatabase.getDataSource();

    for (const entity of entities) {
      const repository = dataSource.getRepository(entity);
      await repository.clear();
    }
  }
}