package com.zanxiang.game.module.manage.rpc.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zanxiang.game.module.base.pojo.params.PushMsgParam;
import com.zanxiang.game.module.base.rpc.IPushMsgRpc;
import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
import com.zanxiang.game.module.manage.enums.CpSendRoleResultEnum;
import com.zanxiang.game.module.manage.enums.PushMsgStrategyTypeEnum;
import com.zanxiang.game.module.manage.service.IPushMsgSendResultService;
import com.zanxiang.game.module.manage.service.IPushMsgStrategyService;
import com.zanxiang.game.module.mybatis.entity.PushMsgSendResult;
import com.zanxiang.game.module.mybatis.entity.PushMsgStrategy;
import com.zanxiang.module.redis.service.IDistributedLockComponent;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.concurrent.TimeUnit;

/**
 * @author : lingfeng
 * @time : 2024-05-24
 * @description : 消息推送
 */
@Slf4j
@DubboService
public class PushMsgRpcImpl implements IPushMsgRpc {

    @Autowired
    private IPushMsgStrategyService pushMsgStrategyService;

    @Autowired
    private IPushMsgSendResultService pushMsgSendResultService;

    @Autowired
    private IDistributedLockComponent distributedLockComponent;

    @Async
    @Override
    public void pushMsgByRecharge(PushMsgParam param) {
        //全局策略控制是否限制
        if (this.defaultStrategyCheck(param)) {
            return;
        }
        //查询充值策略
        PushMsgStrategy pushMsgStrategy = pushMsgStrategyService.getOne(new LambdaQueryWrapper<PushMsgStrategy>()
                .eq(PushMsgStrategy::getStrategyType, PushMsgStrategyTypeEnum.PUSH_MSG_STRATEGY_RECHARGE.getValue())
                .eq(PushMsgStrategy::getGameId, param.getGameId())
                .orderByDesc(PushMsgStrategy::getCreateTime)
                .last("limit 1"));
        if (pushMsgStrategy == null) {
            return;
        }
        pushMsgStrategyService.strategyPushMsgRun(pushMsgStrategy, param);
    }

    @Async
    @Override
    public void pushMsgByLevelUpdate(PushMsgParam param) {
        String lock = RedisKeyConstant.GAME_USER_ROLE_UP_LOCK + param.getUserId() + "_" + param.getGameId() + "_"
                + param.getServerId() + "_" + param.getRoleId();
        //线程锁
        if (!distributedLockComponent.doLock(lock, 0L, 10L, TimeUnit.MINUTES)) {
            return;
        }
        try {
            //全局策略控制是否限制
            if (this.defaultStrategyCheck(param)) {
                return;
            }
            //查询等级策略
            PushMsgStrategy pushMsgStrategy = pushMsgStrategyService.getOne(new LambdaQueryWrapper<PushMsgStrategy>()
                    .eq(PushMsgStrategy::getStrategyType, PushMsgStrategyTypeEnum.PUSH_MSG_STRATEGY_LEVEL.getValue())
                    .eq(PushMsgStrategy::getGameId, param.getGameId())
                    .le(PushMsgStrategy::getRoleLevelMin, param.getRoleLevel())
                    .ge(PushMsgStrategy::getRoleLevelMax, param.getRoleLevel())
                    .orderByDesc(PushMsgStrategy::getCreateTime)
                    .last("limit 1"));
            if (pushMsgStrategy == null) {
                return;
            }
            pushMsgStrategyService.strategyPushMsgRun(pushMsgStrategy, param);
        } catch (Exception ignored) {
        } finally {
            distributedLockComponent.unlock(lock);
        }
    }

    private boolean defaultStrategyCheck(PushMsgParam param) {
        //查询全局策略
        PushMsgStrategy defaultStrategy = pushMsgStrategyService.getOne(new LambdaQueryWrapper<PushMsgStrategy>()
                .eq(PushMsgStrategy::getStrategyType, PushMsgStrategyTypeEnum.PUSH_MSG_STRATEGY_DEFAULT.getValue())
                .eq(PushMsgStrategy::getGameId, param.getGameId())
                .orderByDesc(PushMsgStrategy::getCreateTime)
                .last("limit 1"));
        if (defaultStrategy == null) {
            return Boolean.TRUE;
        }
        //判断今日推送次数是否已限制
        if (defaultStrategy.getSendCountMax() != null && pushMsgSendResultService.count(new LambdaQueryWrapper<PushMsgSendResult>()
                .eq(PushMsgSendResult::getGameId, param.getGameId())
                .eq(PushMsgSendResult::getServerId, param.getServerId())
                .eq(PushMsgSendResult::getRoleId, param.getRoleId())
                .ge(PushMsgSendResult::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT))
                .eq(PushMsgSendResult::getSendStatus, CpSendRoleResultEnum.CP_SEND_ROLE_RESULT_SUCCESS.getValue())
        ) >= defaultStrategy.getSendCountMax()) {
            return Boolean.TRUE;
        }
        //判断间隔时间是否已限制
        if (defaultStrategy.getSendTimeInterval() != null) {
            PushMsgSendResult pushMsgSendResult = pushMsgSendResultService.getOne(new LambdaQueryWrapper<PushMsgSendResult>()
                    .select(PushMsgSendResult::getCreateTime)
                    .eq(PushMsgSendResult::getGameId, param.getGameId())
                    .eq(PushMsgSendResult::getServerId, param.getServerId())
                    .eq(PushMsgSendResult::getRoleId, param.getRoleId())
                    .eq(PushMsgSendResult::getSendStatus, CpSendRoleResultEnum.CP_SEND_ROLE_RESULT_SUCCESS.getValue())
                    .orderByDesc(PushMsgSendResult::getCreateTime)
                    .last("limit 1"));
            if (pushMsgSendResult != null) {
                Duration duration = Duration.between(pushMsgSendResult.getCreateTime(), LocalDateTime.now());
                if (duration.toMinutes() <= defaultStrategy.getSendTimeInterval()) {
                    return Boolean.TRUE;
                }
            }
        }
        return Boolean.FALSE;
    }
}
