package com.qmth.jkserver.core.inteceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qmth.jkserver.common.Constants;
import com.qmth.jkserver.constant.SpringContextHolder;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.SystemResult;
import com.qmth.jkserver.core.annotation.LoginValidate;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.enums.LoginStatus;
import com.qmth.jkserver.model.BasicSchool;
import com.qmth.jkserver.model.User;
import com.qmth.jkserver.service.AuthInfoService;
import com.qmth.jkserver.service.CommonCacheService;
import com.qmth.jkserver.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.InetAddress;
import java.util.Objects;
import java.util.Optional;

/**
 * 系统登录状态拦截器
 *
 * @author
 */
public class SystemInterceptor extends HandlerInterceptorAdapter {

    private Logger logger = LoggerFactory.getLogger(SystemInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        logger.info("@@System Request URI:" + request.getRequestURI());
        AuthInfoService authInfoService = SpringContextHolder.getBean(AuthInfoService.class);
        CommonCacheService commonCacheService = SpringContextHolder.getBean(CommonCacheService.class);
        Long schoolId = (Long) ServletUtil.getRequestHeaderSchoolId();
        if (Objects.nonNull(schoolId) && schoolId.longValue() > 0) {
            BasicSchool basicSchool = commonCacheService.schoolCache(schoolId);
            Optional.ofNullable(basicSchool).orElseThrow(() -> new JkServerException("学校数据为空"));
            boolean expired = authInfoService.appHasExpired(basicSchool.getCode());
            if (!expired) {
                errorReturn(response, JkServerException.AUTH_INFO_ERROR);
                return false;
            }
        }
        HandlerMethod method = (HandlerMethod) handler;
        LoginValidate annotation = method.getMethodAnnotation(LoginValidate.class);
        if (annotation != null) {
            if (annotation.status() != null &&
                    LoginStatus.IGNORE.equals(annotation.status())) {
                return true;
            }
        }
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter(Constants.REQUEST_PARAM_TOKEN);
            if (StringUtils.isNotEmpty(token) && token.startsWith("$") && token.endsWith("~")) {
                //去掉首尾的字符计
                token = new StringBuffer(token).deleteCharAt(0).toString();
                token = new StringBuffer(token).deleteCharAt(token.length() - 1).toString();
                //倒序
                StringBuffer stringBuffer = new StringBuffer();
                for (int i = token.length() - 1; i >= 0; i--) {
                    stringBuffer.append(token.charAt(i));
                }
                token = stringBuffer.toString();
            }
        }
        // 返回服务器ip
        response.setHeader("serviceIp", InetAddress.getLocalHost().getHostAddress());
        if (StringUtils.isNotEmpty(token)) {
            User user = SystemConstant.tokenGetUser(token);
            if (Objects.nonNull(user) && Objects.nonNull(user.getToken()) && Objects.equals(user.getToken(), token)) {
                return true;
            } else if (Objects.nonNull(user)) {
                errorReturn(response, JkServerException.LOGIN_ERROR);
                return false;
            }
        }
        errorReturn(response, JkServerException.LOGIN_NEEDED);
        return false;
    }

    private void errorReturn(HttpServletResponse response, JkServerException exception) {
        SystemResult result = new SystemResult();
        result.returnError(exception.getCode(), exception.getMessage());
        try {
            ObjectMapper mapper = new ObjectMapper();
            response.setStatus(200);
            response.setCharacterEncoding(SystemConstant.CHARSET_NAME);
            response.setContentType(SystemConstant.CONTENT_TYPE_JSON + ";charset=" + SystemConstant.CHARSET_NAME);
            response.getWriter().write(mapper.writeValueAsString(result));
        } catch (Exception e) {
        }
    }


}