package com.bohuikeji.delivery.backstage.lnterceptor;

import com.bohuikeji.delivery.backstage.entity.TCourier;
import com.bohuikeji.delivery.backstage.service.ITCourierService;
import com.bohuikeji.frame.module.admin.base.SuperBase;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.utils.IpUtil;
import com.bohuikeji.frame.module.admin.utils.JsonUtil;
import com.bohuikeji.frame.module.admin.utils.JwtTokenUtil;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Parameter;

/**
 * 接口拦截器
 * @author 10552
 */
@Slf4j
public class ApiLnterceptor extends SuperBase implements HandlerInterceptor {

    @Autowired
    ITCourierService courierService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        boolean checkUserFlag=checkAttributeId((HandlerMethod) handler,"JwtUserId");
        boolean checkAdminFlag=checkAttributeId((HandlerMethod) handler,"JwtAdminId");;
        if(!(checkUserFlag||checkAdminFlag)){
            if ("Knife4j".equals(request.getHeader("Request-Origion"))&&"delivery".equals(request.getHeader("knife4j-gateway-code"))) {
                log.info("接口文档请求，放行~");
                return true;
            }
        }
        String token = request.getHeader("token");
        if (StringUtils.isBlank(token)) {
            log.error("token为空，错误Code：410，来自IP：[{}]，接口地址：[{}]", IpUtil.getIpAddr(request),request.getRequestURL());
            returnJson(APIEntity.fail("token为空", 410), response);
            return false;
        }
        int verifyCode = JwtTokenUtil.verify(token);
        if (verifyCode == -1) {
            log.error("token=[{}]无效或已过期，错误Code：411，来自IP：[{}]，接口地址：[{}]",token,IpUtil.getIpAddr(request),request.getRequestURL());
            returnJson(APIEntity.fail("或已过期", 411), response);
            return false;
        }
        if(verifyCode>0){
            if("派送员".equals(JwtTokenUtil.getType(token))){
                TCourier courier=courierService.getCacheById(verifyCode);
                if(courier==null){
                    returnJson(APIEntity.fail("token无效或已过期", 412), response);
                    return false;
                }
                //log.info("派送员：[{}]访问接口：[{}]",courier.getCourierName(),request.getServletPath());
                if("禁止登陆".equals(courier.getCourierStatus())){
                    returnJson(APIEntity.fail("您已被禁止登陆，如有疑问请联系平台客服。", 412), response);
                    return false;

                }
            }
        }
        if(checkUserFlag){
            if("管理员".equals(JwtTokenUtil.getType(token))){
                log.error("token权限不足,您没有权限调用该接口，错误Code：412，请求地址：[{}]",request.getRequestURL());
                returnJson(APIEntity.fail("token权限不足,您没有权限调用该接口", 411), response);
                return false;
            }
            if(verifyCode==303714){
                log.error("该账户已注销！无法登录！，请求地址：[{}]",request.getRequestURL());
                returnJson(APIEntity.fail("该账户已注销！无法登录！", 412), response);
                return false;
            }
            if (verifyCode > 0) {
                request.setAttribute("JwtUserId", verifyCode);
                //log.info("派送员ID=[{}]访问，访问地址：[{}]",verifyCode,request.getRequestURL());
                return true;
            } else {
                log.error("token权限不足,该接口需要登陆用户的token，错误Code：412，请求地址：[{}]",request.getRequestURL());
                returnJson(APIEntity.fail("token权限不足,该接口需要登陆用户的token", 412), response);
                return false;
            }
        }
        if(checkAdminFlag){
            if(!"管理员".equals(JwtTokenUtil.getType(token))){
                log.error("token权限不足,您没有权限调用该接口，错误Code：412，请求地址：[{}]",request.getRequestURL());
                returnJson(APIEntity.fail("token权限不足,您没有权限调用该接口", 411), response);
                return false;
            }
            if (verifyCode > 0) {
                request.setAttribute("JwtAdminId", verifyCode);
                //log.info("管理员ID=[{}]访问，访问地址：[{}]",verifyCode,request.getRequestURL());
                return true;
            } else {
                log.error("token权限不足,该接口需要登陆用户的token，错误Code：412，请求地址：[{}]",request.getRequestURL());
                returnJson(APIEntity.fail("token权限不足,该接口需要登陆用户的token", 412), response);
                return false;
            }
        }
        //log.info("游客权限访问，访问地址：[{}][{}]",request.getMethod(),request.getRequestURL());
        return true;
    }

    /**
     * 检查接口是否需要自动注入Attribute参数
     * @param handlerMethod
     * @param paramName 参数名称
     * @return
     */
    private boolean checkAttributeId(HandlerMethod handlerMethod,String paramName) {
        Parameter[] parameters = handlerMethod.getMethod().getParameters();
        for (Parameter pm : parameters) {
            RequestAttribute attribute = pm.getAnnotation(RequestAttribute.class);
            if (attribute == null) {
                continue;
            }
            if (paramName.equals(attribute.value())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Response 返回处理
     *
     * @param result
     * @param response
     */
    private void returnJson(APIEntity result, HttpServletResponse response) {
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.print(JsonUtil.objToJson(result).toJSONString());
        writer.close();
        try {
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 打印接口访问日志
     * @param handlerMethod
     */
    private void printLog(HandlerMethod handlerMethod){
        //log.info("用户[{}]ID=[{}]访问");

    }
}
