package com.red.circle.other.app.scheduler;

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.annotation.TaskCacheLock;
import com.red.circle.other.infra.database.cache.service.other.GiftCacheService;
import com.red.circle.other.infra.database.cache.service.other.WeekStarCacheService;
import com.red.circle.other.infra.database.rds.entity.sys.WeekStarGroup;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGiftService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGroupService;
import com.red.circle.other.infra.utils.DateFormatEnum;
import com.red.circle.other.infra.utils.ZonedDateTimeUtils;
import com.red.circle.other.inner.enums.activity.WeekStarGiftTypeEnum;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 重置周星礼物.
 *
 * @author pengliang on 2021/4/20
 */
@Slf4j
@Component
@AllArgsConstructor
public class ResetWeekStarGiftTask {

  private final GiftConfigService giftConfigService;
  private final WeekStarGiftService weekStarGiftService;
  private final WeekStarCacheService weekStarCacheService;
  private final WeekStarGroupService weekStarGroupService;
  private final GiftCacheService giftCacheService;

  /**
   * 每周一 0点执行
   */
  @Scheduled(cron = "0 0 0 ? * MON", zone = "Asia/Riyadh")
  @TaskCacheLock(key = "RESET_WEEK_STAR_GIFT", expireSecond = 86400)
  public void resetWeekStarGift() {
    long startTime = System.currentTimeMillis();
    log.warn("exec reset_week_star_gift start");
    printExecuteLog();
    processWeekStar();
    log.warn("exec reset_week_star_gift end with {}",System.currentTimeMillis()-startTime);
  }

  private void processWeekStar() {

    weekStarCacheService.setWeekStarStartEndDate(getStartDate() + " - " + getEndDate());

    SysOriginPlatformEnum.getVoiceSystems().forEach(this::changeWeekStarGift);

    weekStarCacheService.cacheCountDown(
        Duration.between(LocalDateTime.now(), LocalDateTime.now().plusWeeks(1)).toMillis());

  }


  private void printExecuteLog() {
    log.warn("[execute] resetWeekStarGift:{},{}",
        LocalDateTimeUtils.nowFormat(DateFormatEnum.yyyy_MM_dd_HH_mm_ss.getPattern()),
        ZonedDateTimeUtils.format(ZonedDateTimeUtils.nowAsiaRiyadhWeekMonday(),
            DateFormatEnum.yyyy_MM_dd_HH_mm_ss));
  }


  private String getStartDate() {
    return LocalDateTimeUtils.nowFormat("dd/MM/yyyy");
  }

  private String getEndDate() {
    return LocalDateTimeUtils.formatDayTimeEnd(
        TimestampUtils.nowPlusDays(6).toLocalDateTime(), "dd/MM/yyyy");
  }

  public void changeWeekStarGift(SysOriginPlatformEnum sysOrigin) {

    giftConfigService.updateWeekStarSetting(sysOrigin,
        weekStarGiftService.listGiftIdsByGroupId(settingWeekStarGift(sysOrigin)));

    giftCacheService.remove();
  }

  /**
   * 本周 - 下周 -上周.
   */
  private Long settingWeekStarGift(SysOriginPlatformEnum sysOrigin) {
    WeekStarGroup thisWeekStartGroup = getThisWeekStartGroup(sysOrigin);

    weekStarGroupService.updateLastWeekToNone(sysOrigin);

    if (Objects.isNull(thisWeekStartGroup)) {
      return createWeekStartGift(sysOrigin);
    }

    weekStarGroupService.updateTypeById(thisWeekStartGroup.getId(), WeekStarGiftTypeEnum.LAST_WEEK);

    return weekStarGroupService.getByTypeOne(sysOrigin, WeekStarGiftTypeEnum.NEXT_WEEK)
        .map(next -> {
          weekStarGroupService.updateTypeById(next.getId(), WeekStarGiftTypeEnum.THIS_WEEK);
          settingNext(sysOrigin, next);
          return next.getId();
        }).orElseGet(() -> {
          log.warn("【周星礼物】没有找到下轮结果切换结果，行补充逻辑:{},{}", sysOrigin, thisWeekStartGroup);
          weekStarGroupService.updateLastWeekToNone(sysOrigin,
              Arrays.asList(WeekStarGiftTypeEnum.THIS_WEEK, WeekStarGiftTypeEnum.NEXT_WEEK));
          return createWeekStartGift(sysOrigin);
        });
  }

  private Long createWeekStartGift(SysOriginPlatformEnum sysOrigin) {
    return weekStarGroupService.getStatusNoneMinDisplayNumber(sysOrigin)
        .map(that -> {
          that.incr();
          that.setType(WeekStarGiftTypeEnum.THIS_WEEK.name());
          weekStarGroupService.updateSelectiveById(that);
          settingNext(sysOrigin, that);
          return that.getId();
        }).orElseGet(() -> {
          log.warn("【周星礼物】没有获取到可切换礼物组:{}", sysOrigin);
          return null;
        });
  }

  private WeekStarGroup getThisWeekStartGroup(SysOriginPlatformEnum sysOrigin) {
    return weekStarGroupService
        .getByTypeOne(sysOrigin, WeekStarGiftTypeEnum.THIS_WEEK)
        .orElse(null);
  }

  private void settingNext(SysOriginPlatformEnum sysOrigin, WeekStarGroup that) {
    weekStarGroupService.getStatusNoneMinDisplayNumber(sysOrigin)
        .ifPresent(nextNext -> {
          if (Objects.equals(that.getId(), nextNext.getId())) {
            return;
          }
          nextNext.incr();
          nextNext.setType(WeekStarGiftTypeEnum.NEXT_WEEK.name());
          weekStarGroupService.updateSelectiveById(nextNext);
        });
  }

}
