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


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.user.CpCabinAchieveDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.CpCabinAchieve;
import com.red.circle.other.infra.database.rds.service.user.user.CpCabinAchieveService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.date.ZonedId;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Service;

/**
 * <p>
 * CP小屋成就 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-16
 */
@Service
public class CpCabinAchieveImpl extends
    BaseServiceImpl<CpCabinAchieveDAO, CpCabinAchieve> implements CpCabinAchieveService {

  @Override
  public void incr(Long cpValId, Long cpVal) {

    Integer dateNumber = ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt();
    CpCabinAchieve achieve = query().select(CpCabinAchieve::getId)
        .eq(CpCabinAchieve::getCpValId, cpValId)
        .eq(CpCabinAchieve::getDateNumber, dateNumber)
        .getOne();
    if (Objects.isNull(achieve)) {
      save(CpCabinAchieve.builder()
          .id(IdWorkerUtils.getId())
          .cpValId(cpValId)
          .cpVal(cpVal)
          .dateNumber(dateNumber)
          .build());
      return;
    }

    update().setSql("cp_val=cp_val+" + cpVal)
        .eq(CpCabinAchieve::getId, achieve.getId())
        .last(PageConstant.LIMIT_ONE)
        .execute();

  }

  @Override
  public Long lastMonthCpVal(Long cpValId) {

    if (Objects.isNull(cpValId)) {
      return 0L;
    }

    return Optional.ofNullable(query()
            .select(CpCabinAchieve::getCpVal)
            .eq(CpCabinAchieve::getCpValId, cpValId)
            .eq(CpCabinAchieve::getDateNumber, ZonedDateTime.now(ZonedId.ASIA_RIYADH.getZonedId()).minusMonths(1)
                .format(DateTimeFormatter.ofPattern(DateFormatConstant.yyyyMM)))
            .getOne())
        .map(CpCabinAchieve::getCpVal)
        .orElse(0L);
  }

  @Override
  public Long maxCpVal(Long cpValId) {

    if (Objects.isNull(cpValId)) {
      return 0L;
    }

    return Optional.ofNullable(query()
            .select(CpCabinAchieve::getCpVal)
            .eq(CpCabinAchieve::getCpValId, cpValId)
            .lt(CpCabinAchieve::getDateNumber, ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt())
            .orderByDesc(CpCabinAchieve::getCpVal)
            .last(PageConstant.formatLimit(1))
            .list())
        .map(list -> {
          if (CollectionUtils.isEmpty(list)) {
            return 0L;
          }
          return Optional.ofNullable(list.get(0)).map(CpCabinAchieve::getCpVal).orElse(0L);
        })
        .orElse(0L);
  }

  @Override
  public void deleteByCpValId(Long cpValId) {

    delete()
        .eq(CpCabinAchieve::getCpValId, cpValId)
        .execute();
  }

}
