package com.mortals.xhx.base.framework.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.IAuthTokenService;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.AESUtil;
import com.mortals.framework.util.EntityUtil;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.utils.ServletUtils;
import com.mortals.framework.web.interceptor.BaseInterceptor;
import com.mortals.xhx.base.framework.config.InterceptorConfig;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.daemon.task.CustomerInfo;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Set;

/**
 * 用户权限验证，基于token
 *
 * @author: zxfei
 * @date: 2022/4/24 11:04
 */
@Slf4j
//@Component
public class AuthUserInterceptor extends BaseInterceptor {
    @Autowired
    private InterceptorConfig config;
    @Autowired
    private IAuthTokenService authTokenService;
    @Autowired
    private UserService userService;
    @Autowired
    private ResourceService resourceService;

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE - 1;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        JSONObject ret = new JSONObject();
        try {
            String uri = request.getServletPath();
            //校验配置的请求路径是否需要检查权限
            if (config.needCheckAuth(uri)) {
                //需要校验权限
                try {
                   // String token = request.getParameter("token");
                    String token =  authTokenService.getToken(request);

                    if (StringUtils.isEmpty(token)) {
                        throw new AppException("token为空！");
                    }
                    Claims claims = authTokenService.parseToken(token);
                    Map objMap = claims.get("userInfo", Map.class);
                    CustomerInfo userInfo =new CustomerInfo();
                    EntityUtil.mapToEntity(objMap,userInfo);
                    if (ObjectUtils.isEmpty(userInfo)) {
                        throw new AppException("未获取用户");
                    }

                    UserQuery userQuery = new UserQuery();
                    userQuery.setCustomerId(userInfo.getId());
                    userQuery.setLoginName(userInfo.getAccount());
                    UserEntity userEntity = userService.selectOne(userQuery);
                    if (ObjectUtils.isEmpty(userEntity)) {
                        throw new AppException("请求用户为空！");
                    }

                    boolean auth = this.checkAuth(userEntity, uri);
                    if (!auth) {
                        //不存在时候 如果是管理员也不做拦截
                        if (ObjectUtils.isEmpty(userEntity)) {
                            ret.put("code", -1);
                            ret.put("msg", "用户未登录或登录失效，请重新登录");
                            ServletUtils.renderString(response, JSONObject.toJSONString(ret));
                            return false;
                        } else if (userEntity.isAdmin()) {
                            return super.preHandle(request, response, handler);
                        } else {
                            ret.put("code", -1);
                            ret.put("msg", "用户无该操作权限!");
                            ServletUtils.renderString(response, JSONObject.toJSONString(ret));
                            return false;
                        }
                    }
                } catch (Exception e) {
                    log.error("解析jwt token异常！", e);
                    ret.put("code", -1);
                    ret.put("msg", e.getMessage());
                    ServletUtils.renderString(response, JSONObject.toJSONString(ret));
                    return false;
                }
            }
        } catch (Exception e) {
            logger.error("权限校验拦截请求处理异常-->" + e.getMessage());
            writeJsonResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "用户权限校验异常");
            return false;
        }

        return super.preHandle(request, response, handler);
    }

    private boolean checkAuth(UserEntity userEntity, String requestUrl) throws Exception {
        //查询用户路径
        Set<String> urls = resourceService.findUrlSetByUserId(userEntity.getId());
        if (urls.contains(requestUrl)) return true;
        return false;
    }

}
