package com.lightinit.hsdataportal.controller;

import com.lightinit.hsdataportal.annotation.FieldDescriberHelper;
import com.lightinit.hsdataportal.common.WebUtilsPro;
import com.lightinit.hsdataportal.json.pojo.ErrorEntity;
import com.lightinit.hsdataportal.json.pojo.LoginResult;
import com.lightinit.hsdataportal.model.ResultState;
import com.lightinit.hsdataportal.model.ResultStateCode;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by Mr.Yao on 2017/4/18.
 */
public abstract class BaseController
{

//    /***
//     * 登录异常返回信息
//     * @param request 输入
//     * @param response 输出
//     * @return AJAX返回JSON数据格式 浏览器访问返回HTML格式
//     */
//    @ExceptionHandler({UnauthenticatedException.class,AuthenticationException.class})
//    public String authenticationException(HttpServletRequest request, HttpServletResponse response){
//        if(WebUtilsPro.isAjaxRequest(request)){
//            LoginResult loginResult=new LoginResult();
//            loginResult.setStatus(2008);
//            loginResult.setMessage(ErrorEntity.getMsg(loginResult.getStatus()));
//            writeJson(loginResult,response);
//            return null;
//        }else{
//            return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/passport/login.htm";
//        }
//    }
//
//    /***
//     * 授权异常返回信息
//     * @param request 输入
//     * @param response 输出
//     * @return AJAX返回JSON数据格式 浏览器访问返回HTML格式
//     */
//    @ExceptionHandler({ UnauthorizedException.class, AuthorizationException.class })
//    public String authorizationException(HttpServletRequest request, HttpServletResponse response) {
//        if (WebUtilsPro.isAjaxRequest(request)) {
//            LoginResult loginResult=new LoginResult();
//            loginResult.setStatus(2009);
//            loginResult.setMessage(ErrorEntity.getMsg(loginResult.getStatus()));
//            writeJson(loginResult,response);
//            return null;
//        } else {
//            return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/403.html";
//        }
//    }

    private void writeJson(LoginResult result,HttpServletResponse response){
        PrintWriter out=null;
        try{
            response.setContentType("application/json; charset=utf-8");
            out = response.getWriter();
            ObjectMapper objectMapper = new ObjectMapper();
            out.write(objectMapper.writeValueAsString(result));
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(out!=null)
                out.close();
        }
    }

    public static <T> LinkedHashMap<String, String> getAllFieldInvalidMsg(T modelObj, BindingResult bindingResult){
        if (modelObj == null || bindingResult == null){
            return null;
        }
        LinkedHashMap<String, String> result = new LinkedHashMap<>();
        for (FieldError error : bindingResult.getFieldErrors()){
            String fieldName = error.getField();
            String fieldDescription = FieldDescriberHelper.getFieldDescription(modelObj, fieldName);
            result.put(fieldName, fieldDescription + error.getDefaultMessage());
        }

        return result;
    }

    public static <T> Map.Entry<String, String> getFirstFieldInvalidMsg(T modelObj, BindingResult bindingResult){
        LinkedHashMap<String, String> allFieldInvalidMsg = getAllFieldInvalidMsg(modelObj, bindingResult);
        return allFieldInvalidMsg == null ? null : allFieldInvalidMsg.entrySet().stream().findFirst().get();
    }

    public static ResultState buildInvalidResultState(String message){
        return buildInvalidResultState(message, null);
    }

    public static <T> ResultState<T> buildInvalidResultState(int stateCode, String message){
        return buildInvalidResultState(stateCode, message, null);
    }

    public static <T> ResultState<T> buildInvalidResultState(String message, T data){
        return buildInvalidResultState(ResultStateCode.INVALID_DATA, message, data);
    }

    public static <T> ResultState<T> buildInvalidResultState(int stateCode, String message, T data){
        return new ResultState(stateCode, message, data);
    }

    public static <T> ResultState<LinkedHashMap<String, String>> getAllFieldInvalidResultState(T modelObj, BindingResult bindingResult){
        return buildInvalidResultState("", getAllFieldInvalidMsg(modelObj, bindingResult));
    }

    public static <T> ResultState getFirstInvalidResultState(T modelObj, BindingResult bindingResult){
        Map.Entry<String, String> firstFieldInvalidMsg = getFirstFieldInvalidMsg(modelObj, bindingResult);
        return buildInvalidResultState(firstFieldInvalidMsg == null ? "" : firstFieldInvalidMsg.getValue());
    }
}
