import { GenericCrudService } from '@d8d/shared-crud';
import { DataSource } from 'typeorm';
import { DeliveryAddress } from '../entities';
import { AreaService } from '@d8d/geo-areas';
import { AreaLevel } from '@d8d/geo-areas';

export class DeliveryAddressService extends GenericCrudService<DeliveryAddress> {
  private areaService: AreaService;

  constructor(dataSource: DataSource, areaService: AreaService) {
    super(dataSource, DeliveryAddress);
    this.areaService = areaService;
  }

  /**
   * 获取用户的收货地址列表
   * @param userId 用户ID
   * @returns 收货地址列表
   */
  async findByUser(userId: number): Promise<DeliveryAddress[]> {
    return this.repository.find({
      where: { userId, state: 1 },
      relations: ['user', 'province', 'city', 'district', 'town'],
      order: { isDefault: 'DESC', createdAt: 'DESC' }
    });
  }

  /**
   * 设置默认地址
   * @param id 地址ID
   * @param userId 用户ID
   * @returns 是否设置成功
   */
  async setDefault(id: number, userId: number): Promise<boolean> {
    await this.repository.manager.transaction(async (transactionalEntityManager) => {
      // 先将该用户的所有地址设为非默认
      await transactionalEntityManager.update(DeliveryAddress,
        { userId },
        { isDefault: 0 }
      );

      // 将指定地址设为默认
      await transactionalEntityManager.update(DeliveryAddress,
        { id, userId },
        { isDefault: 1 }
      );
    });

    return true;
  }

  /**
   * 获取用户的默认地址
   * @param userId 用户ID
   * @returns 默认地址或null
   */
  async findDefaultByUser(userId: number): Promise<DeliveryAddress | null> {
    return this.repository.findOne({
      where: { userId, isDefault: 1, state: 1 },
      relations: ['user', 'province', 'city', 'district', 'town']
    });
  }

  /**
   * 验证地区数据
   * @param provinceId 省份ID
   * @param cityId 城市ID
   * @param districtId 区县ID
   * @param townId 街道ID
   * @returns 验证结果
   */
  async validateAreaData(
    provinceId: number,
    cityId: number,
    districtId: number,
    townId: number
  ): Promise<boolean> {
    try {
      // 验证省份
      if (provinceId > 0) {
        const province = await this.areaService.getAreaTreeByLevel(AreaLevel.PROVINCE);
        const validProvince = province.some(area => area.id === provinceId);
        if (!validProvince) return false;
      }

      // 验证城市
      if (cityId > 0) {
        const city = await this.areaService.getAreaTreeByLevel(AreaLevel.CITY);
        const validCity = city.some(area => area.id === cityId);
        if (!validCity) return false;

        // 验证城市是否属于指定的省份
        if (provinceId > 0) {
          const cityEntity = await this.areaService.getSubTree(cityId);
          if (!cityEntity || cityEntity.parentId !== provinceId) {
            return false;
          }
        }
      }

      // 验证区县
      if (districtId > 0) {
        const district = await this.areaService.getAreaTreeByLevel(AreaLevel.DISTRICT);
        const validDistrict = district.some(area => area.id === districtId);
        if (!validDistrict) return false;

        // 验证区县是否属于指定的城市
        if (cityId > 0) {
          const districtEntity = await this.areaService.getSubTree(districtId);
          if (!districtEntity || districtEntity.parentId !== cityId) {
            return false;
          }
        }
      }

      // 验证街道（如果支持）
      if (townId > 0) {
        // 街道级别的验证可以根据需要扩展
        // 目前假设街道ID是有效的
        return true;
      }

      return true;
    } catch (error) {
      console.error('地区数据验证失败:', error);
      return false;
    }
  }

  /**
   * 创建配送地址（包含地区验证）
   * @param data 创建数据
   * @returns 创建的地址
   */
  async createWithValidation(data: Partial<DeliveryAddress>): Promise<DeliveryAddress> {
    // 验证地区数据
    const isValid = await this.validateAreaData(
      data.receiverProvince || 0,
      data.receiverCity || 0,
      data.receiverDistrict || 0,
      data.receiverTown || 0
    );

    if (!isValid) {
      throw new Error('地区数据验证失败，请检查省市区信息是否正确');
    }

    return this.create(data);
  }

  /**
   * 更新配送地址（包含地区验证）
   * @param id 地址ID
   * @param data 更新数据
   * @returns 更新的地址
   */
  async updateWithValidation(id: number, data: Partial<DeliveryAddress>): Promise<DeliveryAddress | null> {
    // 验证地区数据
    const isValid = await this.validateAreaData(
      data.receiverProvince || 0,
      data.receiverCity || 0,
      data.receiverDistrict || 0,
      data.receiverTown || 0
    );

    if (!isValid) {
      throw new Error('地区数据验证失败，请检查省市区信息是否正确');
    }

    return this.update(id, data);
  }
}