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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zanxiang.game.back.base.ServerInfo;
import com.zanxiang.game.back.base.pojo.dto.*;
import com.zanxiang.game.back.base.rpc.ITencentMiniGameBackRpc;
import com.zanxiang.game.back.base.rpc.ITencentUserActionBackRpc;
import com.zanxiang.game.back.base.rpc.ITtMiniGameBackRpc;
import com.zanxiang.game.module.base.pojo.enums.AccountTypeEnum;
import com.zanxiang.game.module.base.pojo.enums.GameCategoryEnum;
import com.zanxiang.game.module.mybatis.entity.*;
import com.zanxiang.game.module.sdk.pojo.dto.PlatformOrderDTO;
import com.zanxiang.game.module.sdk.pojo.param.UserData;
import com.zanxiang.game.module.sdk.service.*;
import com.zanxiang.module.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
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.Map;
import java.util.Objects;

/**
 * @author : lingfeng
 * @time : 2022-11-10
 * @description : 回传
 */
@Slf4j
@Service
public class CallBackServiceImpl implements ICallBackService {

    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
    private ITencentUserActionBackRpc tencentUserActionBackRpc;

    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
    private ITencentMiniGameBackRpc tencentMiniGameBackRpc;

    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
    private ITtMiniGameBackRpc ttMiniGameBackRpc;

    @Autowired
    private IAgentService agentService;

    @Autowired
    private IGameService gameService;

    @Autowired
    private IGameAppletService gameAppletService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IGameExtService gameExtService;

    @Autowired
    private IGameBackLogService gameBackLogService;

    @Override
    public void userCallBack(User user, Map<String, String> urlParamMap) {
        //判断游戏是否开启广告回传, 未开启, 不回传
        GameExt gameExt = gameExtService.getByGameId(user.getGameId());
        if (!Objects.equals(gameExt.getAdCallBackSwitch(), Boolean.TRUE)) {
            return;
        }
        //自然量, 或者跳转链接参数不存在, 不做回传处理
        if (user.getAgentId() == 0L || CollectionUtils.isEmpty(urlParamMap)) {
            return;
        }
        //查询用户渠道信息
        Agent agent = agentService.getById(user.getAgentId());
        if (agent == null) {
            log.error("用户回传不存在渠道信息, userId : {}", user.getId());
            return;
        }
        //查询小游戏信息或者H5游戏相关公众号信息
        GameApplet gameApplet = gameAppletService.getOne(new LambdaQueryWrapper<GameApplet>()
                .eq(GameApplet::getGameId, user.getGameId()));
        log.error("用户注册回传, userId : {}", user.getId());
        try {
            //腾讯H5回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_H5.getValue())) {
                TencentUserDTO tencentUserDTO = this.transform(user, agent, gameApplet);
                tencentUserActionBackRpc.backUser(tencentUserDTO);
                gameBackLogService.addLog(user.getId(), null, "腾讯H5用户回传提交", JsonUtil.toString(tencentUserDTO));
            }
            //腾讯小游戏回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())) {
                TencentUserDTO tencentUserDTO = this.transform(user, agent, gameApplet);
                //解析设置clickId
                Map<String, String> channelMap = agentService.channelTransform(user.getChannel());
                tencentUserDTO.setClickId(channelMap.get("gdt_vid"));
                tencentMiniGameBackRpc.backUser(tencentUserDTO);
                gameBackLogService.addLog(user.getId(), null, "腾讯小游戏用户回传提交", JsonUtil.toString(tencentUserDTO));
            }
            //头条回传
            if (CollectionUtils.isNotEmpty(urlParamMap) && Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE.getValue())) {
                Game game = gameService.getById(user.getGameId());
                //判断是微信小游戏
                if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_WX_APPLET.getId())) {
                    TtUserActiveRpcDTO activeReportRpcDTO = this.transform(user, agent, gameApplet, urlParamMap);
                    ttMiniGameBackRpc.userActiveReport(activeReportRpcDTO);
                    gameBackLogService.addLog(user.getId(), null, "头条用户回传提交", JsonUtil.toString(activeReportRpcDTO));
                }
            }
        } catch (Exception e) {
            log.error("用户回传异常, userId : {}, e : {}", user.getId(), e.getMessage());
        }
    }

    @Override
    public void roleCallBack(GameUserRole gameUserRole, UserData userData) {
        //判断游戏是否开启广告回传, 未开启, 不回传
        GameExt gameExt = gameExtService.getByGameId(userData.getGameId());
        if (!Objects.equals(gameExt.getAdCallBackSwitch(), Boolean.TRUE)) {
            return;
        }
        //用户信息
        User user = userService.getById(userData.getUserId());
        //用户渠道信息
        Agent agent = agentService.getAgentByChannel(user.getChannel());
        if (agent == null) {
            return;
        }
        //查询小游戏信息或者H5游戏相关公众号信息
        GameApplet gameApplet = gameAppletService.getOne(new LambdaQueryWrapper<GameApplet>()
                .eq(GameApplet::getGameId, user.getGameId()));
        log.error("用户创角回传, userId : {}", user.getId());
        try {
            //腾讯H5回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_H5.getValue())) {
                TencentRoleRegisterRpcDTO tencentRoleRegisterRpcDTO = this.transform(user, agent, gameApplet, gameUserRole);
                tencentUserActionBackRpc.backRoleRegister(tencentRoleRegisterRpcDTO);
                gameBackLogService.addLog(user.getId(), gameUserRole.getRoleId(), "腾讯H5创角回传提交", JsonUtil.toString(tencentRoleRegisterRpcDTO));
            }
            //腾讯小游戏回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())) {
                TencentRoleRegisterRpcDTO tencentRoleRegisterRpcDTO = this.transform(user, agent, gameApplet, gameUserRole);
                tencentMiniGameBackRpc.backRoleRegister(tencentRoleRegisterRpcDTO);
                gameBackLogService.addLog(user.getId(), gameUserRole.getRoleId(), "腾讯小游戏创角回传提交", JsonUtil.toString(tencentRoleRegisterRpcDTO));
            }
            //头条回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE.getValue())) {
                Game game = gameService.getById(user.getGameId());
                //判断是微信小游戏
                if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_WX_APPLET.getId())) {
                    TtRoleRegisterRpcDTO ttRoleRegisterRpcDTO = this.transform(user, agent, gameUserRole, gameApplet);
                    ttMiniGameBackRpc.roleRegisterReport(ttRoleRegisterRpcDTO);
                    gameBackLogService.addLog(user.getId(), gameUserRole.getRoleId(), "头条创角回传提交", JsonUtil.toString(ttRoleRegisterRpcDTO));
                }
            }
        } catch (Exception e) {
            log.error("创角回传异常, userId : {}, e : {}", user.getId(), e.getMessage());
        }
    }

    @Override
    public void orderCallBack(PlatformOrderDTO platformOrderDTO) {
        //判断游戏是否开启广告回传, 未开启, 不回传
        GameExt gameExt = gameExtService.getByGameId(platformOrderDTO.getGameId());
        if (!Objects.equals(gameExt.getAdCallBackSwitch(), Boolean.TRUE)) {
            return;
        }
        //用户信息
        User user = userService.getById(platformOrderDTO.getUserId());
        //用户渠道信息
        Agent agent = agentService.getAgentByChannel(user.getChannel());
        if (agent == null) {
            log.error("订单回传不存在渠道信息, orderId : {}", platformOrderDTO.getOrderId());
            return;
        }
        //查询小游戏信息或者H5游戏相关公众号信息
        GameApplet gameApplet = gameAppletService.getOne(new LambdaQueryWrapper<GameApplet>()
                .eq(GameApplet::getGameId, user.getGameId()));
        log.error("用户订单回传, orderId : {}", platformOrderDTO.getOrderId());
        try {
            //腾讯H5回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_H5.getValue())) {
                TencentOrderDTO tencentOrderDTO = this.transform(platformOrderDTO, user, agent, gameApplet);
                tencentUserActionBackRpc.backOrder(tencentOrderDTO);
                gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "腾讯H5订单回传提交", JsonUtil.toString(tencentOrderDTO));
            }
            //腾讯小游戏回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())) {
                TencentOrderDTO tencentOrderDTO = this.transform(platformOrderDTO, user, agent, gameApplet);
                //解析设置clickId
                Map<String, String> channelMap = agentService.channelTransform(user.getChannel());
                tencentOrderDTO.setClickId(channelMap.get("gdt_vid"));
                tencentMiniGameBackRpc.backOrder(tencentOrderDTO);
                gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "腾讯小游戏订单回传提交", JsonUtil.toString(tencentOrderDTO));
            }
            //头条回传
            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE.getValue())) {
                //判断游戏类型
                Game game = gameService.getById(platformOrderDTO.getGameId());
                if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_WX_APPLET.getId())) {
                    TtOrderRpcDTO ttOrderRpcDTO = this.transform(platformOrderDTO, user.getOpenId(), agent, gameApplet, user.getCreateTime());
                    ttMiniGameBackRpc.orderReport(ttOrderRpcDTO);
                    gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "头条订单回传提交", JsonUtil.toString(ttOrderRpcDTO));
                }
            }
        } catch (Exception e) {
            log.error("订单回传异常, orderId : {}, e : {}", platformOrderDTO.getOrderId(), e.getMessage());
        }
    }

    private TencentRoleRegisterRpcDTO transform(User user, Agent agent, GameApplet gameApplet, GameUserRole gameUserRole) {
        return TencentRoleRegisterRpcDTO.builder()
                .backPolicyId(agent.getBackPolicyId())
                .gameId(gameUserRole.getGameId())
                .adAccountId(agent.getAccountId())
                .registerTime(gameUserRole.getCreateTime())
                .channel(agent.getAgentKey())
                .wechatOpenid(user.getOpenId())
                .wechatAppId(gameApplet == null ? null : gameApplet.getAppId())
                .userActionSetId(agent.getUserActionSetId())
                .roleId(gameUserRole.getRoleId())
                .roleName(gameUserRole.getRoleName())
                .build();
    }

    private TtRoleRegisterRpcDTO transform(User user, Agent agent, GameUserRole gameUserRole, GameApplet gameApplet) {
        TtAccountRpcDTO ttAccountRpcDTO = TtAccountRpcDTO.builder()
                .accountId(agent.getAccountId())
                .reportToken(agent.getReportToken())
                .reportUrl(agent.getReportUrl())
                .build();
        return TtRoleRegisterRpcDTO.builder()
                .gameId(gameUserRole.getGameId())
                .backPolicyId(agent.getBackPolicyId())
                .accountReport(ttAccountRpcDTO)
                .wechatAppId(gameApplet == null ? null : gameApplet.getAppId())
                .wechatOpenId(user.getOpenId())
                .agentKey(agent.getAgentKey())
                .roleId(gameUserRole.getRoleId())
                .roleName(gameUserRole.getRoleName())
                .registerTime(gameUserRole.getCreateTime())
                .build();
    }

    private TencentUserDTO transform(User user, Agent agent, GameApplet gameApplet) {
        return TencentUserDTO.builder()
                .backPolicyId(agent.getBackPolicyId())
                .gameId(user.getGameId())
                .adAccountId(agent.getAccountId())
                .registerTime(user.getCreateTime())
                .channel(agent.getAgentKey())
                .wechatOpenid(user.getOpenId())
                .wechatAppId(gameApplet == null ? null : gameApplet.getAppId())
                .userActionSetId(agent.getUserActionSetId())
                .build();
    }

    private TtUserActiveRpcDTO transform(User user, Agent agent, GameApplet gameApplet, Map<String, String> urlParamMap) {
        TtAccountRpcDTO ttAccountRpcDTO = TtAccountRpcDTO.builder()
                .accountId(agent.getAccountId())
                .reportToken(agent.getReportToken())
                .reportUrl(agent.getReportUrl())
                .build();
        return TtUserActiveRpcDTO.builder()
                .gameId(user.getGameId())
                .wechatAppId(gameApplet == null ? null : gameApplet.getAppId())
                .wechatOpenId(user.getOpenId())
                .accountReport(ttAccountRpcDTO)
                .agentKey(agent.getAgentKey())
                .activeTime(user.getCreateTime())
                .clueToken(urlParamMap.get("clue_token"))
                .projectId(Strings.isBlank(urlParamMap.get("project_id")) ? null : Long.valueOf(urlParamMap.get("project_id")))
                .promotionId(Strings.isBlank(urlParamMap.get("promotion_id")) ? null : Long.valueOf(urlParamMap.get("promotion_id")))
                .advertiserId(Strings.isBlank(urlParamMap.get("advertiser_id")) ? null : Long.valueOf(urlParamMap.get("advertiser_id")))
                .reqId(urlParamMap.get("req_id"))
                .build();
    }

    private TencentOrderDTO transform(PlatformOrderDTO platformOrderDTO, User user, Agent agent, GameApplet gameApplet) {
        return TencentOrderDTO.builder()
                .backPolicyId(agent.getBackPolicyId())
                .gameId(platformOrderDTO.getGameId())
                .adAccountId(agent.getAccountId())
                .registerTime(user.getCreateTime())
                .rechargeMoney(platformOrderDTO.getAmount().longValue() * 100)
                .rechargeTime(platformOrderDTO.getCreateTime())
                .orderId(platformOrderDTO.getOrderId())
                .channel(agent.getAgentKey())
                .wechatOpenid(user.getOpenId())
                .wechatAppId(gameApplet == null ? null : gameApplet.getAppId())
                .orderStatus(platformOrderDTO.getStatus())
                .payTime(platformOrderDTO.getPayTime())
                .userActionSetId(agent.getUserActionSetId())
                .roleId(platformOrderDTO.getRoleId())
                .roleName(platformOrderDTO.getRoleName())
                .build();
    }

    private TtOrderRpcDTO transform(PlatformOrderDTO platformOrderDTO, String openId, Agent agent, GameApplet gameApplet, LocalDateTime regTime) {
        TtAccountRpcDTO ttAccountRpcDTO = TtAccountRpcDTO.builder()
                .accountId(agent.getAccountId())
                .reportToken(agent.getReportToken())
                .reportUrl(agent.getReportUrl())
                .build();
        return TtOrderRpcDTO.builder()
                .gameId(platformOrderDTO.getGameId())
                .accountReport(ttAccountRpcDTO)
                .wechatAppId(gameApplet == null ? null : gameApplet.getAppId())
                .wechatOpenId(openId)
                .orderId(platformOrderDTO.getOrderId())
                .agentKey(agent.getAgentKey())
                .backPolicyId(agent.getBackPolicyId())
                .rechargeMoney(platformOrderDTO.getAmount().longValue() * 100)
                .orderStatus(platformOrderDTO.getStatus())
                .createTime(platformOrderDTO.getCreateTime())
                .payTime(platformOrderDTO.getPayTime())
                .regTime(regTime)
                .roleId(platformOrderDTO.getRoleId())
                .roleName(platformOrderDTO.getRoleName())
                .build();
    }
}
