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

import com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.GameStateEnum;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.annotation.TaskCacheLock;
import com.red.circle.mq.business.model.event.game.GameIndoorTeamPkEvent;
import com.red.circle.mq.business.model.event.game.GameRoomPkEvent;
import com.red.circle.other.app.manager.activity.refresh.ActivityPkManager;
import com.red.circle.other.app.manager.game.GameIndoorTeamPkManager;
import com.red.circle.other.app.manager.game.GameRoomPkManager;
import com.red.circle.other.infra.database.rds.entity.game.GameIndoorTeamPkRecord;
import com.red.circle.other.infra.database.rds.entity.game.GameRoomPkRecord;
import com.red.circle.other.infra.database.rds.entity.game.GameRoomPkWinnerRecord;
import com.red.circle.other.infra.database.rds.service.game.GameIndoorTeamPkRecordService;
import com.red.circle.other.infra.database.rds.service.game.GameRoomPkRecordService;
import com.red.circle.other.infra.database.rds.service.game.GameRoomPkWinnerRecordService;
import com.red.circle.other.inner.enums.game.GamePkTypeEnum;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 游戏-房间Pk.
 *
 * @author pengshigang on 2021/9/27
 */
@Slf4j
//@Component
@AllArgsConstructor
public class GameRoomPkTask {

  private final ActivityPkManager activityPkManager;
  private final GameRoomPkManager gameRoomPkManager;
  private final GameIndoorTeamPkManager gameIndoorTeamPkManager;
  private final GameRoomPkRecordService gameRoomPkRecordService;
  private final GameRoomPkWinnerRecordService gameRoomPkWinnerRecordService;
  private final GameIndoorTeamPkRecordService gameIndoorTeamPkRecordService;

  /**
   * 每10分钟检查一次是否有超时未关闭的pk记录，有则将其主动结束掉
   */
  @Scheduled(cron = "0 0/10 * * * ?")
  @TaskCacheLock(key = "PK_RECORD_TIME_OUT_CLOSE_TASK", expireSecond = 540)
//  @XxlJob("pk_record_time_out_close_task")
  public void pkRecordTimeOutCloseTask() {
    long startTime = System.currentTimeMillis();
    log.info("exec pk_record_time_out_close_task start");
    //Pk游戏 - 处理结束消息发送与数据处理
    listExpiredPkRecords().forEach(
        item -> gameRoomPkManager.processRoomPk(new GameRoomPkEvent().setGameId(item.getId())
            .setState(GameStateEnum.valueOf(item.getGameStatus())))
    );

    //房间内团队PK游戏 - 处理结束消息发送与数据处理
    listExpiredIndoorTeamPkRecords().forEach(item -> gameIndoorTeamPkManager
        .processRoomPk(new GameIndoorTeamPkEvent().setGameId(item.getId())
            .setState(GameStateEnum.valueOf(item.getGameStatus())))
    );
    log.info("exec pk_record_time_out_close_task end with {}",System.currentTimeMillis()-startTime);
  }


  /**
   * 每天0点执行，给昨天的top用户加额外积分.
   */
  @Scheduled(cron = "0 0 3 1/1 * ?", zone = "Asia/Riyadh")
  @TaskCacheLock(key = "GAME_ROOM_PK_TASK_DAY", expireSecond = 1800)
  public void gameRoomPkTaskDay() {
    long startTime = System.currentTimeMillis();
    log.info("exec game_room_pk_task_day start");
    log.warn("[execute] ResetUserWeekConsumeManager.everyDay start:{}",
        LocalDateTimeUtils.nowFormat("yyyy-MM-dd"));

    //给昨天的top3奖励额外积分
    addedDailyTop3Bonus();
    //刷新上周PK数据（暂时这么处理）
    activityPkManager.weekly();

    log.warn("[execute] ResetUserWeekConsumeManager.everyDay end:{}",
        LocalDateTimeUtils.nowFormat("yyyy-MM-dd"));
    log.info("exec game_room_pk_task_day end with {}",System.currentTimeMillis()-startTime);
  }

  /**
   * 给昨天的top3奖励额外积分
   */
  private void addedDailyTop3Bonus() {

    List<GameRoomPkWinnerRecord> saveAll = Lists.newArrayList();

    SysOriginPlatformEnum.getVoiceSystems().forEach(origin -> {

      List<GameRoomPkWinnerRecord> tops = listDayWinnerTop(origin);

      for (int i = 0; i < tops.size(); i++) {

        GameRoomPkWinnerRecord save =new GameRoomPkWinnerRecord()
            .setId(IdWorkerUtils.getId())
            .setSysOrigin(origin.name())
            .setTotalIntegral(getTotalIntegral(tops.get(i).getTotalIntegral(), i))
            .setUserId(tops.get(i).getUserId())
            .setIntegral(0L)
            .setPkType(GamePkTypeEnum.ONE_VS_ONE.name())
            .setType(Boolean.TRUE);
        save.setCreateTime(TimestampUtils.nowMinusMinutes(10));
        save.setCreateUser(tops.get(i).getUserId());
        save.setUpdateTime(TimestampUtils.now());
        save.setUpdateUser(tops.get(i).getUserId());
        saveAll.add(save);

      }
    });

    if (CollectionUtils.isNotEmpty(saveAll) && saveAll.size() > 0) {
      gameRoomPkWinnerRecordService.saveBatch(saveAll);
    }
  }

  private List<GameRoomPkWinnerRecord> listDayWinnerTop(SysOriginPlatformEnum origin) {

    return Optional.ofNullable(gameRoomPkWinnerRecordService.dayTop(origin, Boolean.TRUE))
        .orElse(Lists.newArrayList());
  }

  /**
   * 根据总积分与排行榜名次计算额外奖励积分
   */
  private long getTotalIntegral(Long totalIntegral, int topIndex) {

    if (Objects.isNull(totalIntegral) || totalIntegral.intValue() <= 0) {
      return 0L;
    }
    if (topIndex == 0) {
      return Double.valueOf(totalIntegral * 0.03).longValue();
    }
    if (topIndex == 1) {
      return Double.valueOf(totalIntegral * 0.02).longValue();
    }
    if (topIndex == 2) {
      return Double.valueOf(totalIntegral * 0.01).longValue();
    }
    return 0L;
  }


  /**
   * 获得超时未结束记录 - PK
   */
  private List<GameRoomPkRecord> listExpiredPkRecords() {

    List<GameRoomPkRecord> startList = getListExpiredStartedRecordByNow();
    List<GameRoomPkRecord> waitingList = getListExpiredWaitingRecordByNow();
    List<GameRoomPkRecord> items = Lists.newArrayList();

    if (CollectionUtils.isNotEmpty(startList)) {
      items.addAll(startList);
    }

    if (CollectionUtils.isNotEmpty(waitingList)) {
      items.addAll(waitingList);
    }
    return items;
  }

  /**
   * 获得超时未结束记录 - 房间内团队PK
   */
  private List<GameIndoorTeamPkRecord> listExpiredIndoorTeamPkRecords() {

    List<GameIndoorTeamPkRecord> startList = getListExpiredStartedIndoorTeamPkRecordByNow();
    List<GameIndoorTeamPkRecord> waitingList = getListExpiredWaitingIndoorTeamPkRecordByNow();
    List<GameIndoorTeamPkRecord> items = Lists.newArrayList();

    if (CollectionUtils.isNotEmpty(startList)) {
      items.addAll(startList);
    }

    if (CollectionUtils.isNotEmpty(waitingList)) {
      items.addAll(waitingList);
    }
    return items;
  }

  private List<GameIndoorTeamPkRecord> getListExpiredStartedIndoorTeamPkRecordByNow() {
    return gameIndoorTeamPkRecordService
        .listExpiredStartedRecordByNow(TimestampUtils.now());
  }

  private List<GameIndoorTeamPkRecord> getListExpiredWaitingIndoorTeamPkRecordByNow() {
    return gameIndoorTeamPkRecordService
        .listExpiredWaitingRecordByNow(TimestampUtils.now());
  }

  private List<GameRoomPkRecord> getListExpiredStartedRecordByNow() {
    return gameRoomPkRecordService
        .listExpiredStartedRecordByNow(TimestampUtils.now());
  }

  private List<GameRoomPkRecord> getListExpiredWaitingRecordByNow() {
    return gameRoomPkRecordService
        .listExpiredWaitingRecordByNow(TimestampUtils.now());
  }

}
