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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.erp.base.ErpServer;
import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
import com.zanxiang.erp.base.rpc.ISysUserRpc;
import com.zanxiang.erp.security.util.SecurityUtil;
import com.zanxiang.game.module.base.pojo.enums.DeleteEnum;
import com.zanxiang.game.module.base.pojo.enums.GameAuthEnum;
import com.zanxiang.game.module.manage.pojo.params.GameAuthRoleAddParam;
import com.zanxiang.game.module.manage.pojo.params.GameAuthRoleListParam;
import com.zanxiang.game.module.manage.pojo.params.GameAuthRoleUpdateParam;
import com.zanxiang.game.module.manage.pojo.vo.GameAuthRoleVO;
import com.zanxiang.game.module.manage.service.IGameAuthRoleService;
import com.zanxiang.game.module.manage.service.IGameAuthService;
import com.zanxiang.game.module.mybatis.entity.GameAuth;
import com.zanxiang.game.module.mybatis.entity.GameAuthRole;
import com.zanxiang.game.module.mybatis.mapper.GameAuthRoleMapper;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : lingfeng
 * @time : 2023-08-17
 * @description : 游戏授权角色
 */
@Slf4j
@Service
public class GameAuthRoleServiceImpl extends ServiceImpl<GameAuthRoleMapper, GameAuthRole> implements IGameAuthRoleService {

    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private ISysUserRpc sysUserRpc;

    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private IDingTalkMsgRpc dingTalkMsgRpc;

    @Autowired
    private IGameAuthService gameAuthService;

    @Override
    public void dingTalkCustomer(Long gameId, String gameName, String msg) {
        Set<Long> customerIdSet = super.list(new LambdaQueryWrapper<GameAuthRole>()
                .eq(GameAuthRole::getAuthType, GameAuthEnum.CUSTOMER.getValue())
        ).stream().map(GameAuthRole::getUserId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(customerIdSet)) {
            return;
        }
        Set<Long> gameCustomerIdSet = gameAuthService.list(new LambdaQueryWrapper<GameAuth>()
                .eq(GameAuth::getGameId, gameId)
                .in(GameAuth::getUserId, customerIdSet)
        ).stream().map(GameAuth::getUserId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(gameCustomerIdSet)) {
            return;
        }
        gameCustomerIdSet.forEach(customerId -> {
            try {
                dingTalkMsgRpc.sendByUserId(customerId, msgStr(gameName, msg));
            } catch (Exception ignored) {
            }
        });
    }

    private String msgStr(String gameName, String msg) {
        return "客服系统关键词监测: " +
                "\n" +
                "时间: " +
                LocalDateTime.now() +
                "\n" +
                "游戏名称: " +
                gameName +
                "\n" +
                "玩家发送内容: " +
                msg;
    }

    @Override
    public boolean isCustomer() {
        return super.count(new LambdaQueryWrapper<GameAuthRole>()
                .eq(GameAuthRole::getUserId, SecurityUtil.getUserId())
                .and(qw -> qw.eq(GameAuthRole::getAuthType, GameAuthEnum.CUSTOMER.getValue())
                        .or().eq(GameAuthRole::getCustomerPower, Boolean.TRUE))
        ) > 0;
    }

    @Override
    public Map<Long, String> getUserByAuthType(String authType) {
        List<GameAuthRole> authRoleList = super.list(new LambdaQueryWrapper<GameAuthRole>()
                .eq(GameAuthRole::getAuthType, authType));
        if (CollectionUtils.isEmpty(authRoleList)) {
            return Collections.emptyMap();
        }
        //查询相关人得名字
        return sysUserRpc.getUserNameByIds(authRoleList.stream()
                .map(GameAuthRole::getUserId).collect(Collectors.toList())).getData();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean gameAuthRoleAdd(GameAuthRoleAddParam param) {
        //游戏id
        List<Long> userIdList = param.getUserIdList();
        List<GameAuthRole> addList = new ArrayList<>();
        userIdList.forEach(userId -> {
            //判断提交的参数数据是否已经存在
            if (super.count(new LambdaQueryWrapper<GameAuthRole>()
                    .eq(GameAuthRole::getUserId, userId)
            ) > 0) {
                return;
            }
            addList.add(this.transform(userId, param.getAuthType().getValue()));
        });
        if (addList.isEmpty()) {
            return Boolean.FALSE;
        }
        return super.saveBatch(addList);
    }

    private GameAuthRole transform(Long userId, String authType) {
        return GameAuthRole.builder()
                .authType(authType)
                .userId(userId)
                .isDelete(DeleteEnum.NO.getCode())
                .createBy(SecurityUtil.getUserId())
                .createTime(LocalDateTime.now())
                .updateBy(SecurityUtil.getUserId())
                .updateTime(LocalDateTime.now())
                .build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean gameAuthRoleUpdate(GameAuthRoleUpdateParam param) {
        return super.update(new LambdaUpdateWrapper<GameAuthRole>()
                .set(GameAuthRole::getAuthType, param.getAuthType().getValue())
                .eq(GameAuthRole::getId, param.getId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        //查询用户是否存在游戏
        GameAuthRole gameAuthRole = super.getById(id);
        if (gameAuthRole == null) {
            return false;
        }
        if (gameAuthService.count(new LambdaQueryWrapper<GameAuth>()
                .eq(GameAuth::getUserId, gameAuthRole.getUserId())
        ) > 0) {
            throw new BaseException("该角色存在分配的游戏, 禁止删除");
        }
        return super.removeById(id);
    }

    @Override
    public IPage<GameAuthRoleVO> listOfPage(GameAuthRoleListParam param) {
        return page(param.toPage(), new QueryWrapper<GameAuthRole>().lambda()
                .eq(param.getUserId() != null, GameAuthRole::getUserId, param.getUserId())
                .eq(param.getAuthType() != null, GameAuthRole::getAuthType, param.getAuthType() == null ? null : param.getAuthType().getValue())
                .orderByDesc(GameAuthRole::getUpdateTime)
        ).convert(this::toVo);
    }

    private GameAuthRoleVO toVo(GameAuthRole gameAuthRole) {
        if (Objects.isNull(gameAuthRole)) {
            return null;
        }
        GameAuthRoleVO gameAuthRoleVO = BeanUtil.copy(gameAuthRole, GameAuthRoleVO.class);
        Map<Long, String> userMap = sysUserRpc.getUserNameByIds(Collections.singletonList(gameAuthRoleVO.getUserId())).getData();
        gameAuthRoleVO.setUserName(userMap.get(gameAuthRoleVO.getUserId()));
        gameAuthRoleVO.setAuthType(GameAuthEnum.getByValue(gameAuthRole.getAuthType()));
        return gameAuthRoleVO;
    }

}
