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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.game.module.base.pojo.params.PushMsgParam;
import com.zanxiang.game.module.manage.enums.CpSendRoleResultEnum;
import com.zanxiang.game.module.manage.enums.PushMsgAgentTypeEnum;
import com.zanxiang.game.module.manage.pojo.dto.UserDTO;
import com.zanxiang.game.module.manage.service.*;
import com.zanxiang.game.module.mybatis.entity.*;
import com.zanxiang.game.module.mybatis.mapper.PushMsgStrategyMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Objects;

/**
 * @author : lingfeng
 * @time : 2024-05-24
 * @description : 消息推送策略
 */
@Slf4j
@Service
public class PushMsgStrategyServiceImpl extends ServiceImpl<PushMsgStrategyMapper, PushMsgStrategy> implements IPushMsgStrategyService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleOperateService roleOperateService;

    @Autowired
    private IGameUserRoleService gameUserRoleService;

    @Autowired
    private IPushMsgTextStrategy pushMsgTextStrategy;

    @Autowired
    private IPushMsgTestRoleService pushMsgTestRoleService;

    @Autowired
    private IPushMsgSendLogService pushMsgSendLogService;

    @Autowired
    private IPushMsgSendResultService pushMsgSendResultService;

    @Override
    public void strategyPushMsgRun(PushMsgStrategy pushMsgStrategy, PushMsgParam param) {
        //策略开启测试, 查询是否在测试名单中, 不在测试名单中, 直接结束, 不执行
        if (Objects.equals(pushMsgStrategy.getRoleTestSwitch(), Boolean.TRUE)
                && pushMsgTestRoleService.count(new LambdaQueryWrapper<PushMsgTestRole>()
                .eq(PushMsgTestRole::getGameId, param.getGameId())
                .eq(PushMsgTestRole::getServerId, param.getServerId())
                .eq(PushMsgTestRole::getRoleId, param.getRoleId())
        ) <= 0) {
            return;
        }
        //查询玩家
        UserDTO userDTO = userService.getById(param.getUserId());
        //不存在等级策略, 或者玩家为空
        if (userDTO == null) {
            return;
        }
        //判断是否满足策略执行条件
        if (!this.strategyCheck(pushMsgStrategy, param, userDTO)) {
            return;
        }
        //查询策略执行角色
        GameUserRole gameUserRole = gameUserRoleService.getOne(new LambdaQueryWrapper<GameUserRole>()
                .eq(GameUserRole::getGameId, param.getGameId())
                .eq(GameUserRole::getUserId, param.getUserId())
                .eq(GameUserRole::getRoleId, param.getRoleId()));
        //查询策略执行文本
        String strategyText = pushMsgTextStrategy.getStrategyText(gameUserRole);
        if (Strings.isBlank(strategyText)) {
            return;
        }
        //执行发送
        pushMsgSendLogService.pushMsg(param.getGameId(), pushMsgStrategy.getId(), strategyText, Collections.singletonList(gameUserRole));
    }

    private boolean strategyCheck(PushMsgStrategy pushMsgStrategy, PushMsgParam param, UserDTO userDTO) {
        //渠道限制不为空, 且不是全渠道
        if (pushMsgStrategy.getAgentType() != null
                && !Objects.equals(pushMsgStrategy.getAgentType(), PushMsgAgentTypeEnum.PUSH_MSG_AGENT_ALL.getValue())) {
            //只允许自然量
            if (Objects.equals(pushMsgStrategy.getAgentType(), PushMsgAgentTypeEnum.PUSH_MSG_AGENT_DEFAULT.getValue())
                    && !Objects.equals(userDTO.getAgentId(), Agent.DEFAULT_AGENT)) {
                return Boolean.FALSE;
            }
            //只允许非自然量
            if (Objects.equals(pushMsgStrategy.getAgentType(), PushMsgAgentTypeEnum.PUSH_MSG_AGENT_UN_DEFAULT.getValue())
                    && Objects.equals(userDTO.getAgentId(), Agent.DEFAULT_AGENT)) {
                return Boolean.FALSE;
            }
        }
        //判断注册时间, 是否在最大限制之内
        if (pushMsgStrategy.getRegDayMax() != null
                && userDTO.getCreateTime().plusDays(pushMsgStrategy.getRegDayMax()).isBefore(LocalDateTime.now())) {
            return Boolean.FALSE;
        }
        //首个角色限制
        if (Objects.equals(pushMsgStrategy.getFirstRoleSwitch(), Boolean.TRUE)) {
            GameUserRole gameUserRole = gameUserRoleService.getOne(new LambdaQueryWrapper<GameUserRole>()
                    .eq(GameUserRole::getUserId, param.getUserId())
                    .eq(GameUserRole::getGameId, param.getGameId())
                    .orderByAsc(GameUserRole::getCreateTime)
                    .last("limit 1"));
            if (gameUserRole == null || !Objects.equals(gameUserRole.getRoleId(), param.getRoleId())) {
                return Boolean.FALSE;
            }
        }
        //判断最小充值金额
        if (pushMsgStrategy.getRechargeMoneyMin() != null) {
            GameUserRole gameUserRole = gameUserRoleService.getOne(new LambdaQueryWrapper<GameUserRole>()
                    .eq(GameUserRole::getUserId, param.getUserId())
                    .eq(GameUserRole::getGameId, param.getGameId())
                    .eq(GameUserRole::getRoleId, param.getRoleId()));
            if (gameUserRole.getRechargeMoney() == null
                    || gameUserRole.getRechargeMoney().longValue() < pushMsgStrategy.getRechargeMoneyMin()) {
                return Boolean.FALSE;
            }
        }
        //判断是否已加企微
        if (Objects.equals(pushMsgStrategy.getExcludeAddWechat(), Boolean.TRUE)) {
            RoleOperate roleOperate = roleOperateService.getOne(new LambdaQueryWrapper<RoleOperate>()
                    .eq(RoleOperate::getUserId, param.getUserId())
                    .eq(RoleOperate::getGameId, param.getGameId())
                    .eq(RoleOperate::getServerId, param.getServerId())
                    .eq(RoleOperate::getRoleId, param.getRoleId()));
            if (roleOperate != null && Objects.equals(roleOperate.getIsAddCorpWechat(), 1)) {
                return Boolean.FALSE;
            }
        }
        //单策略推送次数
        if (pushMsgStrategy.getSendCountMax() != null && pushMsgSendResultService.count(new LambdaQueryWrapper<PushMsgSendResult>()
                .eq(PushMsgSendResult::getGameId, param.getGameId())
                .eq(PushMsgSendResult::getStrategyId, pushMsgStrategy.getId())
                .eq(PushMsgSendResult::getServerId, param.getServerId())
                .eq(PushMsgSendResult::getRoleId, param.getRoleId())
                .eq(PushMsgSendResult::getSendStatus, CpSendRoleResultEnum.CP_SEND_ROLE_RESULT_SUCCESS.getValue())
        ) >= pushMsgStrategy.getSendCountMax()) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
}
