package com.zanxiang.game.module.sdk.adapter;

import com.zanxiang.game.module.base.pojo.enums.HttpStatusEnum;
import com.zanxiang.game.module.mybatis.entity.GameExt;
import com.zanxiang.game.module.sdk.annotation.ValidLogin;
import com.zanxiang.game.module.sdk.exception.TokenExpireException;
import com.zanxiang.game.module.sdk.pojo.dto.UserTokenDTO;
import com.zanxiang.game.module.sdk.pojo.param.UserData;
import com.zanxiang.game.module.sdk.service.IGameExtService;
import com.zanxiang.game.module.sdk.service.IUserTokenService;
import com.zanxiang.module.util.exception.BaseException;
import com.zanxiang.module.web.util.IpUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.annotation.Resource;

/**
 * @author : lingfeng
 * @time : 2022-09-28
 * @description : 参数解析器
 */
@Component
@Service
@Slf4j
public class ArgumentAdapter implements HandlerMethodArgumentResolver {

    @Resource
    private IUserTokenService userTokenService;

    @Resource
    private IGameExtService gameExtService;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(UserData.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        if (request == null) {
            throw new BaseException(HttpStatusEnum.UNKNOWN_ERROR.getMsg());
        }
        //是否强制验证登录状态
        boolean b = parameter.hasParameterAnnotation(ValidLogin.class);
        String token = request.getHeader("token");
        //需要登录, token不存在
        if (b && Strings.isBlank(token)) {
            throw new TokenExpireException(HttpStatusEnum.USER_NO_LOGIN.getMsg());
        }
        //设备类型
        Integer deviceType = Integer.valueOf(request.getHeader("deviceType"));
        //前端传过来的是appId,不是真正的gameId
        GameExt gameExt = gameExtService.getByGameAppId(request.getHeader("gameId"));
        if (gameExt == null) {
            throw new BaseException(HttpStatusEnum.UNKNOWN_ERROR.getMsg());
        }
        //构造用户信息
        UserData data = UserData.builder()
                .gameId(gameExt.getGameId())
                .ip(IpUtil.getRealIp(request))
                .ua(request.getHeader("User-Agent"))
                .deviceType(deviceType)
                .deviceSystem(request.getHeader("os"))
                .mac(request.getHeader("mac"))
                .imei(request.getHeader("imei"))
                .oaid(request.getHeader("oaid"))
                .androidId(request.getHeader("androidId"))
                .idfa(request.getHeader("idfa"))
                .caid(request.getHeader("caid"))
                .channel(request.getHeader("channel"))
                .build();
        //不需要登录, token不存在
        if (Strings.isBlank(token)) {
            return data;
        }
        UserTokenDTO userTokenDTO = userTokenService.getTokenInfoByTokenDevice(token, deviceType);
        if (userTokenDTO == null) {
            if (b) {
                throw new TokenExpireException(HttpStatusEnum.USER_NO_LOGIN.getMsg());
            }
            return data;
        }
        if (b && userTokenDTO.getUserId() == null) {
            throw new TokenExpireException(HttpStatusEnum.USER_NO_LOGIN.getMsg());
        }
        data.setUserId(userTokenDTO.getUserId());
        data.setToken(userTokenDTO.getToken());
        data.setExpireTime(userTokenDTO.getExpireTime());
        return data;
    }
}
