package com.red.circle.other.app.inner.service.user.region.impl;

import com.google.common.collect.Maps;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.order.inner.endpoint.PayCountryClient;
import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService;
import com.red.circle.other.infra.database.rds.service.user.region.RegionRelationService;
import com.red.circle.other.inner.model.dto.sys.SysPayCountryDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.app.inner.convertor.user.RegionRelationInnerConvertor;
import com.red.circle.other.inner.model.cmd.user.SysRegionRelationCmd;
import com.red.circle.other.inner.model.cmd.user.SysRegionRelationQryCmd;
import com.red.circle.other.inner.model.dto.user.reigon.RegionRelationDTO;
import com.red.circle.other.inner.enums.user.RegionRelationGroupEnum;
import com.red.circle.other.app.inner.service.user.region.RegionRelationClientService;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 区域关系.
 *
 * @author pengliang on 2023/8/20
 */
@Service
@RequiredArgsConstructor
public class RegionRelationClientServiceImpl implements RegionRelationClientService {

  private final PayCountryClient payCountryClient;
  private final SysRegionConfigService regionConfigService;
  private final RegionRelationService regionRelationService;
  private final RegionRelationInnerConvertor regionRelationInnerConvertor;

  @Override
  public List<RegionRelationDTO> listByRegionId(String regionId, String sysOrigin,
      RegionRelationGroupEnum group) {
    return regionRelationInnerConvertor.toListRegionRelationDTO(
        regionRelationService.listByRegionId(regionId, sysOrigin, group));
  }

  @Override
  public PageResult<RegionRelationDTO> pageRelation(SysRegionRelationQryCmd query) {

    RegionRelationGroupEnum groupEnum = RegionRelationGroupEnum.valueOf(query.getGroupType());
    ResponseAssert.notNull(UserErrorCode.CODE_ALREADY_EXISTS, groupEnum);

    PageResult<RegionRelationDTO> relationIPage = regionRelationService.pageRelation(query)
        .convert(regionRelationInnerConvertor::toRegionRelationDTO);
    if (CollectionUtils.isEmpty(relationIPage.getRecords())) {
      return relationIPage;
    }

    Map<String, String> regionNameMap = getRegionNameMap(relationIPage);

    Map<Long, SysPayCountryDTO> relationDescMap = getRelationDescMap(groupEnum,
        getRelationIds(relationIPage));

    return relationIPage.convert(relation -> {

      SysPayCountryDTO payCountry = relationDescMap.get(relation.getRelationId());
      if (Objects.nonNull(payCountry)) {
        relation.setRelationDesc(payCountry.getCountry().getCountryName());
      }
      relation.setRegionName(regionNameMap.get(relation.getRegionId()));
      return relation;
    });

  }

  private Set<Long> getRelationIds(PageResult<RegionRelationDTO> relationIPage) {
    return relationIPage.getRecords().stream()
        .map(RegionRelationDTO::getRelationId)
        .collect(Collectors.toSet());
  }

  private Map<Long, SysPayCountryDTO> getRelationDescMap(RegionRelationGroupEnum groupEnum,
      Set<Long> relationIds) {

    if (CollectionUtils.isEmpty(relationIds)) {
      return Maps.newHashMap();
    }

    if (Objects.equals(groupEnum, RegionRelationGroupEnum.OPEN_PAY_COUNTRY)) {
      return regionRelationInnerConvertor.toMapSysPayCountryDTO(
          ResponseAssert.requiredSuccess(payCountryClient.mapCountryByIds(relationIds)));
    }
    return Maps.newHashMap();
  }

  private Map<String, String> getRegionNameMap(PageResult<RegionRelationDTO> relationIPage) {
    return regionConfigService.mapRegionName(relationIPage.getRecords().stream()
        .map(RegionRelationDTO::getRegionId)
        .collect(Collectors.toSet()));
  }

  @Override
  public void add(SysRegionRelationCmd param) {
    regionRelationService.add(param);
  }

  @Override
  public void update(SysRegionRelationCmd param) {
    regionRelationService.update(param);
  }

  @Override
  public Set<Long> getRelationIdsByRegionId(String regionId, String name) {
    return regionRelationService.getRelationIdsByRegionId(regionId, name);
  }

}
