package com.red.circle.other.app.command.game.luckybox;

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.common.business.enums.PropsActivityRewardEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.other.app.common.game.GameLuckyBoxCommon;
import com.red.circle.other.app.dto.clientobject.game.GameLuckyBoxFortuneValueConfigCO;
import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
import com.red.circle.other.infra.common.activity.send.SendRewardParam;
import com.red.circle.other.infra.database.rds.entity.game.GameLuckyBoxAwardDetailsConfig;
import com.red.circle.other.infra.database.rds.entity.game.GameLuckyBoxUserAward;
import com.red.circle.other.infra.database.rds.entity.game.GameLuckyBoxUserOpenedAward;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.game.GameLuckyBoxAwardDetailsConfigService;
import com.red.circle.other.infra.database.rds.service.game.GameLuckyBoxUserAwardService;
import com.red.circle.other.infra.database.rds.service.game.GameLuckyBoxUserOpenedAwardService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribe;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * luckyBox开宝箱
 *
 * @author zongpubin on 2023/9/5
 */

@Component
@RequiredArgsConstructor
public class GameLuckyBoxOpenBoxCmdExe {

  private final RedisService redisService;
  private final GameLuckyBoxCommon gameLuckyBoxCommon;
  private final PropsActivitySendCommon propsActivitySendCommon;
  private final PropsSourceRecordService propsSourceRecordService;
  private final GameLuckyBoxUserAwardService gameLuckyBoxUserAwardService;
  private final GameLuckyBoxUserOpenedAwardService gameLuckyBoxUserOpenedAwardService;
  private final GameLuckyBoxAwardDetailsConfigService gameLuckyBoxAwardDetailsConfigService;


  public void execute(AppIdLongCmd cmd) {
    String lockKey = "LUCKY_BOX_OPEN_BOX:" + cmd.requiredReqUserId();

    if (redisService.lock(lockKey, 3)) {

      GameLuckyBoxAwardDetailsConfig awardDetailsConfig = gameLuckyBoxAwardDetailsConfigService.getById(
          cmd.getId());

      GameLuckyBoxFortuneValueConfigCO gameLuckyBoxFortuneValueConfigCO = gameLuckyBoxCommon.getFortuneValueConfig(
          cmd.requireReqSysOrigin());

      if (Objects.isNull(awardDetailsConfig)) {
        return;
      }

      PropsSourceRecord props = propsSourceRecordService.getPropsById(
          awardDetailsConfig.getPropsId());

      if (Objects.isNull(props)) {
        return;
      }

      propsActivitySendCommon.sendSingle(SendRewardParam.builder()
          .acceptUserId(cmd.requiredReqUserId())
          .origin(SendPropsOrigin.LUCKY_BOX_RECEIVE)
          .sysOrigin(SysOriginPlatformEnum.valueOf(cmd.requireReqSysOrigin()))
          .trackId(awardDetailsConfig.getId())
          .build(), new PrizeDescribe()
          .setType(PropsActivityRewardEnum.CHAT_BUBBLE.eq(props.getType())
              ? PropsActivityRewardEnum.CHAT_BUBBLE.name() : PropsActivityRewardEnum.PROPS.name())
          .setTrackId(awardDetailsConfig.getId())
          .setContent(awardDetailsConfig.getPropsId().toString())
          .setQuantity(Integer.valueOf(awardDetailsConfig.getValidDays()))
          .setDetailType(props.getType())
          .setRemark(SendPropsOrigin.LUCKY_BOX_REWARD.getDesc())
      );

      // 记录已领取的宝箱
      gameLuckyBoxUserOpenedAwardService.save(new GameLuckyBoxUserOpenedAward()
          .setId(IdWorkerUtils.getId())
          .setAwardDetailsId(awardDetailsConfig.getId())
          .setUserId(cmd.requiredReqUserId())
          .setSysOrigin(cmd.requireReqSysOrigin())
      );

      if (Objects.nonNull(gameLuckyBoxFortuneValueConfigCO) && Objects.equals(
          awardDetailsConfig.getLotteryNumber(),
          gameLuckyBoxFortuneValueConfigCO.getLuckyTimeTwo())) {
        // 清除开宝箱记录，进行下一轮开宝箱
        gameLuckyBoxUserOpenedAwardService.deleteByUserId(cmd.requiredReqUserId());

        gameLuckyBoxUserAwardService.updateByUserId(new GameLuckyBoxUserAward()
            .setUserId(cmd.requiredReqUserId())
            .setAwardCount(0)
        );
      }

    }
  }
}
