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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zanxiang.game.module.base.pojo.enums.DeleteEnum;
import com.zanxiang.game.module.manage.pojo.params.ChatSubmitParam;
import com.zanxiang.game.module.manage.pojo.params.OpenGameServerParam;
import com.zanxiang.game.module.manage.service.IGameServerService;
import com.zanxiang.game.module.manage.service.IGameSupperService;
import com.zanxiang.game.module.manage.service.IGameUserChatService;
import com.zanxiang.game.module.manage.service.IListenCallService;
import com.zanxiang.game.module.manage.utils.SignUtil;
import com.zanxiang.game.module.mybatis.entity.GameServer;
import com.zanxiang.game.module.mybatis.entity.GameSupper;
import com.zanxiang.module.util.JsonUtil;
import com.zanxiang.module.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author : lingfeng
 * @time : 2024-04-25
 * @description : cp服务端交互
 */
@Slf4j
@Service
public class CpServerApiService {

    @Autowired
    private IGameServerService gameServerService;

    @Autowired
    private IGameSupperService gameSupperService;

    @Autowired
    private IListenCallService listenCallService;

    @Autowired
    private IGameUserChatService gameUserChatService;

    @Autowired
    private RestTemplate restTemplate;

    public boolean chatMsgSubmit(ChatSubmitParam param) {
        log.error("收到游戏聊天内容, param : {}", JsonUtil.toString(param));
        GameSupper gameSupper = gameSupperService.getById(param.getGameId());
        if (gameSupper == null) {
            throw new BaseException("参数错误");
        }
        //签名验证
        this.signCheck(gameSupper.getCpServerKey(), param.getGameId(), param.getServerId(),
                param.getSignTime(), param.getSign());
        //调武哥接口, 监测聊天通知
        try {
            this.chatContentCheck(gameSupper, param);
        } catch (Exception e) {
            log.error("调武哥接口通知消息异常, chatContentMap : {}, e : {}", JsonUtil.toString(param), e.getMessage(), e);
        }
        //保存聊天数据到数据库
        try {
            gameUserChatService.addGameUserChat(param);
        } catch (Exception e) {
            log.error("保存聊天数据到数据库异常, param : {}, e : {}", JsonUtil.toString(param), e.getMessage(), e);
        }
        return Boolean.TRUE;
    }

    private void chatContentCheck(GameSupper gameSupper, ChatSubmitParam param) {
        //查询区服信息
        GameServer gameServer = gameServerService.getOne(new LambdaQueryWrapper<GameServer>()
                .eq(GameServer::getGameId, param.getGameId())
                .eq(GameServer::getServerId, param.getServerId())
                .last("limit 1"));
        //组装聊天参数
        Map<String, Object> chatContentMap = param.getChatContentMap();
        chatContentMap.put("game_name", gameSupper.getName());
        if (gameServer != null) {
            chatContentMap.put("server_name", gameServer.getServerName());
        }
        Map<String, Object> paramMap = new HashMap<>(1);
        paramMap.put("data", chatContentMap);
        //调武哥接口通知消息
        restTemplate.postForObject("http://47.99.157.216:9000/game/roleChat", paramMap, Object.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean openGameServer(OpenGameServerParam param) {
        GameSupper gameSupper = gameSupperService.getById(param.getGameId());
        if (gameSupper == null) {
            throw new BaseException("参数错误");
        }
        this.signCheck(gameSupper.getCpServerKey(), param.getGameId(), param.getServerId(),
                param.getSignTime(), param.getSign());
        //查询区服id
        GameServer gameServer = gameServerService.getOne(new LambdaQueryWrapper<GameServer>()
                .eq(GameServer::getGameId, param.getGameId())
                .eq(GameServer::getServerId, param.getServerId())
        );
        GameServer transform = this.transform(param);
        if (gameServer == null) {
            gameServer = transform;
        } else {
            gameServer.setGameId(transform.getGameId());
            gameServer.setServerId(transform.getServerId());
            gameServer.setServerName(transform.getServerName());
            gameServer.setNickName(transform.getNickName());
            gameServer.setStartTime(transform.getStartTime());
            gameServer.setUpdateTime(LocalDateTime.now());
        }
        //区服添加或者更新
        gameServerService.saveOrUpdate(gameServer);
        //钉钉通知
        String content = LocalDateTime.now() + "游戏开服通知\n游戏名称 : " + gameSupper.getName()
                + "\n区服名称:" + param.getServerName() + "\n开服时间:" + param.getStartTime().toString();
        listenCallService.sendDingTalkMsg(param.getGameId(), Boolean.TRUE, content);
        return Boolean.TRUE;
    }

    private GameServer transform(OpenGameServerParam param) {
        return GameServer.builder()
                .gameId(param.getGameId())
                .serverId(param.getServerId())
                .serverName(param.getServerName())
                .nickName(param.getNickName())
                .startTime(param.getStartTime())
                .isDelete(DeleteEnum.NO.getCode())
                .createBy(0L)
                .createTime(LocalDateTime.now())
                .isSourceServer(Boolean.TRUE)
                .isMerge(Boolean.FALSE)
                .updateBy(0L)
                .updateTime(LocalDateTime.now())
                .build();
    }

    private void signCheck(String cpServerKey, Long gameId, String serverId, Long signTime, String sign) {
        String signStr = "cpServerKey=" + cpServerKey + "gameId=" + gameId
                + "serverId=" + serverId + "signTime=" + signTime;
        String mySign = SignUtil.md5(signStr);
        if (!Objects.equals(mySign.toUpperCase(), sign.toUpperCase())) {
            log.error("加密验证失败, sign : {}, mySign : {}", sign, mySign);
            throw new BaseException("加密标识错误");
        }
    }
}
