package com.red.circle.other.infra.database.rds.service.user.region.impl;

import com.google.common.collect.Sets;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.user.region.RegionRelationDAO;
import com.red.circle.other.infra.database.rds.entity.user.reigon.RegionRelation;
import com.red.circle.other.infra.database.rds.service.user.region.RegionRelationService;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
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.enums.user.RegionRelationGroupEnum;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 区域关系
 * </p>
 *
 * @author pengshigang
 * @since 2023-04-03
 */
@Service
public class RegionRelationServiceImpl extends
    BaseServiceImpl<RegionRelationDAO, RegionRelation> implements RegionRelationService {


  @Override
  public List<RegionRelation> listByRegionId(String regionId, String sysOrigin,
      RegionRelationGroupEnum group) {

    return query()
        .eq(RegionRelation::getRegionId, regionId)
        .eq(RegionRelation::getSysOrigin, sysOrigin)
        .eq(RegionRelation::getShowcase, Boolean.TRUE)
        .eq(RegionRelation::getGroupType, group.name())
        .last(PageConstant.formatLimit(100))
        .list();
  }

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

    return query()
        .eq(Objects.nonNull(query.getShowcase()), RegionRelation::getShowcase,
            query.getShowcase())
        .eq(RegionRelation::getSysOrigin, query.getSysOrigin())
        .eq(Objects.nonNull(query.getRelationId()), RegionRelation::getRelationId,
            query.getRelationId())
        .eq(RegionRelation::getGroupType, query.getGroupType())
        .eq(StringUtils.isNotBlank(query.getRegion()), RegionRelation::getRegionId,
            query.getRegion())
        .orderByDesc(RegionRelation::getCreateTime)
        .page(query.getPageQuery());
  }

  @Override
  public void add(SysRegionRelationCmd param) {

    ResponseAssert.isEmpty(CommonErrorCode.INFORMATION_EXISTS, query()
        .eq(RegionRelation::getSysOrigin, param.getSysOrigin())
        .eq(RegionRelation::getRegionId, param.getRegionId())
        .in(RegionRelation::getRelationId, param.getRelationIds())
        .eq(RegionRelation::getGroupType, param.getGroupType())
        .last(PageConstant.DEFAULT_LIMIT)
        .list());

    saveBatch(param.getRelationIds().stream().map(relationId -> {
      RegionRelation regionRelation = new RegionRelation();
      regionRelation.setId(IdWorkerUtils.getId());
      regionRelation.setRegionId(param.getRegionId());
      regionRelation.setRelationId(relationId);
      regionRelation.setGroupType(param.getGroupType());
      regionRelation.setSysOrigin(param.getSysOrigin());
      regionRelation.setCreateTime(TimestampUtils.now());
      regionRelation.setShowcase(param.getShowcase());
      return regionRelation;
    }).collect(Collectors.toList()));

  }

  @Override
  public void update(SysRegionRelationCmd param) {

    ResponseAssert.isEmpty(
        CommonErrorCode.INFORMATION_EXISTS,
        query()
            .eq(RegionRelation::getSysOrigin, param.getSysOrigin())
            .eq(RegionRelation::getRegionId, param.getRegionId())
            .in(RegionRelation::getRelationId, param.getRelationIds())
            .eq(RegionRelation::getGroupType, param.getGroupType())
            .ne(RegionRelation::getId, param.getId())
            .last(PageConstant.DEFAULT_LIMIT)
            .list());

    update()
        .set(RegionRelation::getRelationId, param.getRelationIds().get(0))
        .set(RegionRelation::getRegionId, param.getRegionId())
        .set(RegionRelation::getShowcase, param.getShowcase())
        .eq(RegionRelation::getId, param.getId())
        .last(PageConstant.LIMIT_ONE)
        .execute();

  }

  @Override
  public Set<Long> getRelationIdsByRegionId(String regionId, String groupType) {

    if (StringUtils.isBlanks(regionId, groupType)) {
      return Sets.newHashSet();
    }

    return Optional.ofNullable(query()
            .eq(RegionRelation::getRegionId, regionId)
            .eq(RegionRelation::getGroupType, groupType)
            .eq(RegionRelation::getShowcase, Boolean.TRUE)
            .last(PageConstant.formatLimit(100))
            .list())
        .map(relations -> relations.stream().map(RegionRelation::getRelationId).collect(
            Collectors.toSet()))
        .orElse(Sets.newHashSet());

  }
}
