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.enums.DeleteEnum;
import com.zanxiang.game.module.manage.pojo.params.UserAppletSubmitParam;
import com.zanxiang.game.module.manage.service.IGameAppletService;
import com.zanxiang.game.module.manage.service.IGameExtService;
import com.zanxiang.game.module.manage.service.IKfAppletReplyService;
import com.zanxiang.game.module.manage.service.IUserAppletService;
import com.zanxiang.game.module.manage.utils.SignUtil;
import com.zanxiang.game.module.mybatis.entity.GameApplet;
import com.zanxiang.game.module.mybatis.entity.GameExt;
import com.zanxiang.game.module.mybatis.entity.KfAppletReply;
import com.zanxiang.game.module.mybatis.entity.UserApplet;
import com.zanxiang.game.module.mybatis.mapper.UserAppletMapper;
import com.zanxiang.module.util.JsonUtil;
import com.zanxiang.module.util.URIUtil;
import com.zanxiang.module.util.exception.BaseException;
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 org.springframework.web.client.RestTemplate;

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

/**
 * @author : lingfeng
 * @time : 2024-04-29
 * @description : 投放小程序用户信息
 */
@Slf4j
@Service
public class UserAppletServiceImpl extends ServiceImpl<UserAppletMapper, UserApplet> implements IUserAppletService {

    @Autowired
    private IGameAppletService gameAppletService;

    @Autowired
    private IGameExtService gameExtService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IKfAppletReplyService kfAppletReplyService;

    @Override
    public Map<String, String> userAppletSubmit(UserAppletSubmitParam param) {
        GameApplet gameApplet = gameAppletService.getOne(new LambdaQueryWrapper<GameApplet>()
                .eq(GameApplet::getAppId, param.getAppId())
                .last("limit 1"));
        if (gameApplet == null) {
            log.error("非法参数, 小程序信息不存在, param : {}", JsonUtil.toString(param));
            throw new BaseException("非法参数, 小程序信息不存在");
        }
        GameExt gameExt = gameExtService.getByGameId(gameApplet.getGameId());
        this.signCheck(gameExt.getLoginKey(), param);
        //获取用户小程序 openId
        String openId = this.getAppletOpenId(param.getCode(), param.getAppId(), gameApplet.getAppSecret());
        //数据保存且返回结果
        super.save(this.transform(param, openId));
        //参数转换
        Map<String, String> channelMap = JsonUtil.toMap(param.getChannel(), Map.class, String.class);
        if (!channelMap.containsKey(KfAppletReply.PAGE_SIGN)) {
            return Collections.emptyMap();
        }
        KfAppletReply kfAppletReply = kfAppletReplyService.getOne(new LambdaQueryWrapper<KfAppletReply>()
                .eq(KfAppletReply::getAppId, param.getAppId())
                .eq(KfAppletReply::getPageSign, channelMap.get(KfAppletReply.PAGE_SIGN)));
        return JsonUtil.toMap(kfAppletReply.getPageConfig(), Map.class, String.class);
    }

    private UserApplet transform(UserAppletSubmitParam param, String openId) {
        return UserApplet.builder()
                .appId(param.getAppId())
                .openId(openId)
                .channel(param.getChannel())
                .isDelete(DeleteEnum.NO.getCode())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
    }

    private void signCheck(String loginKey, UserAppletSubmitParam param) {
        String signStr = "loginKey=" + loginKey + "appId=" + param.getAppId()
                + "code=" + param.getCode() + "signTime=" + param.getSignTime();
        String mySign = SignUtil.md5(signStr);
        if (!Objects.equals(mySign.toUpperCase(), param.getSign().toUpperCase())) {
            log.error("加密验证失败, sign : {}, mySign : {}", param.getSign(), mySign);
            throw new BaseException("加密标识错误");
        }
    }

    private String getAppletOpenId(String code, String appId, String secret) {
        // 请求微信服务器，使用code获取openid
        Map<String, String> paramMap = new HashMap<>(4);
        paramMap.put("appid", appId);
        paramMap.put("secret", secret);
        paramMap.put("js_code", code);
        paramMap.put("grant_type", "authorization_code");
        // 发送请求
        String url = URIUtil.fillUrlParams("https://api.weixin.qq.com/sns/jscode2session", paramMap, Boolean.FALSE);
        String sr = restTemplate.getForObject(url, String.class);
        // 解析相应内容（转换成json对象）
        Map<String, String> resultMap = JsonUtil.toMap(sr, Map.class, String.class);
        if (resultMap == null || Strings.isBlank(resultMap.get("openid"))) {
            log.error("获取用户小程序/小游戏openId失败, appId : {}, resultMap : {}", appId, JsonUtil.toString(resultMap));
            throw new BaseException("获取用户小程序/小游戏openId失败");
        }
        return resultMap.get("openid");
    }
}
