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


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.family.FamilyLevelConfigDAO;
import com.red.circle.other.infra.database.rds.entity.family.FamilyLevelConfig;
import com.red.circle.other.infra.database.rds.service.family.FamilyLevelConfigService;
import com.red.circle.other.inner.model.cmd.famliy.FamilyLevelConfigQryCmd;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 家族等级配置表 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-20
 */
@Service
@RequiredArgsConstructor
public class FamilyLevelConfigServiceImpl extends
    BaseServiceImpl<FamilyLevelConfigDAO, FamilyLevelConfig> implements FamilyLevelConfigService {


  @Override
  public FamilyLevelConfig getFamilyLevelConfig(Long id) {
    return Optional.ofNullable(query().eq(FamilyLevelConfig::getId, id)
            .last(PageConstant.LIMIT_ONE)
            .getOne())
        .orElse(new FamilyLevelConfig());
  }

  @Override
  public Map<Long, FamilyLevelConfig> mapByIds(Set<Long> ids) {

    if (CollectionUtils.isEmpty(ids)) {
      return CollectionUtils.newHashMap();
    }

    return Optional.ofNullable(
            query().in(FamilyLevelConfig::getId, ids).orderByAsc(FamilyLevelConfig::getSort).list())
        .map(config -> config.stream()
            .collect(Collectors.toMap(FamilyLevelConfig::getId, level -> level)))
        .orElse(CollectionUtils.newHashMap());
  }

  @Override
  public FamilyLevelConfig getIntiLevel(String sysOrigin) {
    return query()
        .eq(FamilyLevelConfig::getSysOrigin, sysOrigin)
        .orderByAsc(FamilyLevelConfig::getSort)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }


  @Override
  public List<FamilyLevelConfig> listLevelBySysOrigin(String sysOrigin) {
    return query().eq(FamilyLevelConfig::getSysOrigin, sysOrigin).list();
  }

  @Override
  public List<FamilyLevelConfig> listLevelConfig(String sysOrigin) {
    return Optional.ofNullable(query().eq(FamilyLevelConfig::getSysOrigin, sysOrigin)
        .orderByAsc(FamilyLevelConfig::getSort).list()).orElse(CollectionUtils.newArrayList());
  }

  @Override
  public FamilyLevelConfig getNextLevel(String sysOrigin, Integer sort) {
    return query()
        .gt(FamilyLevelConfig::getSort, sort)
        .eq(FamilyLevelConfig::getSysOrigin, sysOrigin)
        .orderByAsc(FamilyLevelConfig::getSort)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public List<FamilyLevelConfig> listLevelConfig() {

    return Optional.ofNullable(query()
        .last(PageConstant.formatLimit(100))
        .list()).orElse(CollectionUtils.newArrayList());
  }


  @Override
  public PageResult<FamilyLevelConfig> pageData(FamilyLevelConfigQryCmd queryWhere) {

    return query()
        .eq(Objects.nonNull(queryWhere.getId()), FamilyLevelConfig::getId, queryWhere.getId())
        .eq(StringUtils.isNotEmpty(queryWhere.getLevelKey()), FamilyLevelConfig::getLevelKey,
            queryWhere.getLevelKey())
        .eq(StringUtils.isNotEmpty(queryWhere.getSysOrigin()), FamilyLevelConfig::getSysOrigin,
            queryWhere.getSysOrigin())
        .orderByAsc(FamilyLevelConfig::getSort)
        .page(queryWhere.getPageQuery());
  }

  @Override
  public List<FamilyLevelConfig> listAllLevel() {
    return query().list();
  }

  @Override
  public void saveFamilyLevelConfig(FamilyLevelConfig param) {

    checkParam(param);

    if (Objects.isNull(param.getId())) {

      ResponseAssert.isFalse(CommonErrorCode.DATA_ERROR, isExistKey(param));

      save(param);
      return;
    }

    FamilyLevelConfig level = getFamilyLevelConfigByKey(param);

    if (Objects.isNull(level) || Objects.equals(level.getId(), param.getId())) {
      updateSelectiveById(param);
      return;
    }

    ResponseAssert.isFalse(CommonErrorCode.DATA_ERROR, isExistKey(param));
  }

  private FamilyLevelConfig getFamilyLevelConfigByKey(FamilyLevelConfig param) {
    return query().eq(FamilyLevelConfig::getLevelKey, param.getLevelKey())
        .eq(FamilyLevelConfig::getSysOrigin, param.getSysOrigin()).getOne();
  }

  private Boolean isExistKey(FamilyLevelConfig param) {
    return Objects.nonNull(getFamilyLevelConfigByKey(param));
  }

  private void checkParam(FamilyLevelConfig param) {
    ResponseAssert.isFalse(CommonErrorCode.DATA_ERROR,
        param.getMaxManager() <= 0 ||
            param.getMaxMember() <= 0);
  }

}
