package org.jeecg.modules.utils;

import cn.hutool.json.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.List;
import java.util.Map;

/**
 * 封装返回
 * @param <T>
 */
public class JsonResult<T> extends ResponseEntity<T> {
    //TODO 下方常量为暂时性方案,后期统计完全后,归类到统一枚举或字典内
    static final String CONSTANT_TRUE= "true";
    static final String QR_CODE_FALSE= "验证码校验失败";
    static final String LOGIN_FOBIDDEN = "错误次数太多,15分钟后再尝试登录";
    static final String USER_STATUS_UNUSUAL = "用户处于禁用状态";
    static final String USER_DEL_FLAG = "用户处于注销状态";
    static final String CHANGE_PASSWORD = "密码复杂度不够,需要修改密码!";


    public JsonResult(List data,MultiValueMap<String, String> header,String code) {
        super((T)data,header,Message.num2HttpStatus(code));
    }

    public JsonResult(String code, T data) {
        super(data, Message.num2HttpStatus(code));
    }

    public static <T> JsonResult<T> created(T data) {
        return new JsonResult("201", data);
    }
    public static <T> JsonResult<T> success(T data) {
        return new JsonResult("200", data);
    }
    public static <T> JsonResult<T> success(String msg) {
    	JSONObject json = new JSONObject();
    	json.putOpt("message", msg);
        return new JsonResult("200", json);
    }
    public static <T> JsonResult<T> success() {
    	JSONObject json = new JSONObject();
        return new JsonResult("200", json);
    }

    public static <T> JsonResult<T> accepted(T data) {
        return new JsonResult("202", data);
    }
    public static <T> JsonResult<T> noContented() {
        return new JsonResult("204",null);
    }
    public static <T> JsonResult<T> movedPermanently(T data) {
        return new JsonResult("301", data);
    }
    public static <T> JsonResult<T> found(T data) {
        return new JsonResult("302", data);
    }
    public static <T> JsonResult<T> paged(PageUtils data, Map<String, Object> params) {
        String str = StringUtil.objectToString(params.get("count"));
        if (null != str && CONSTANT_TRUE.equals(str)){
            MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            header.add("X-Total-Count", String.valueOf(data.getTotalCount()));
            // 因为浏览器的安全策略获取不到header信息,此处将X-Total-Count数据暴露出来
            header.add("Access-Control-Expose-Headers","X-Total-Count");
            return new JsonResult(data.getList(),header,"200");
        }else{
            return new JsonResult("200", data.getList());
        }
    }

    public static <T> JsonResult<T> paged(Map<String, Object> map, Map<String, Object> params) {
        String str = (String) params.get("count");
        if (null != str && CONSTANT_TRUE.equals(str)){
            MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            header.add("X-Total-Count", String.valueOf(map.get("total_count")));
            // 因为浏览器的安全策略获取不到header信息,此处将X-Total-Count数据暴露出来
            header.add("Access-Control-Expose-Headers","X-Total-Count");
            return new JsonResult((List)map.get("list"),header,"200");
        }else{
            return new JsonResult("200", (List)map.get("list"));
        }
    }


    public static <T> JsonResult<T> paged(PageUtils data, CngcPage model) {
        Boolean ifCount = model.isCount();
        if (null != ifCount && ifCount){
            MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            header.add("X-Total-Count", String.valueOf(data.getTotalCount()));
            return new JsonResult(data.getList(),header,"200");
        }else{
            return new JsonResult("200", data.getList());
        }

    }

    public static <T> JsonResult<T> unauthorized(String msg) {
    	JSONObject json = new JSONObject();
    	json.putOpt("message", msg);
        return new JsonResult("401", json);
    }
    public static <T> JsonResult<T> notFounded() {
        return new JsonResult("404", null);
    }
    public static <T> JsonResult<T> failMsg() {
        return new JsonResult("422", null);
    }
    public static <T> JsonResult<T> failMsg(String msg) {
    	JSONObject json = new JSONObject();
    	json.putOpt("message", msg);
        return new JsonResult("422", json);
    }
    public static <T> JsonResult<T> failMsg(String code ,String msg) {
    	JSONObject json = new JSONObject();
    	json.putOpt("message", msg);
        return new JsonResult(code, json);
    }
    public static <T> JsonResult<T> failMsg(T data) {
        return new JsonResult("422", data);
    }

    //2021-10-28 shiruojiang
    public static <T> JsonResult<T> qrcodeFail(){
        com.alibaba.fastjson.JSONObject obj = new com.alibaba.fastjson.JSONObject();
        obj.put("message", QR_CODE_FALSE);
        obj.put("qrcode", true);
        return new JsonResult("422", obj);
    }
    public static <T> JsonResult<T> loginForbidden(){
        com.alibaba.fastjson.JSONObject obj = new com.alibaba.fastjson.JSONObject();
        obj.put("message", LOGIN_FOBIDDEN);
        obj.put("qrcode", true);
        return new JsonResult("422", obj);
    }
    public static <T> JsonResult<T> userStatusUnusual(){
        com.alibaba.fastjson.JSONObject obj = new com.alibaba.fastjson.JSONObject();
        obj.put("message", USER_STATUS_UNUSUAL);
        return new JsonResult("422", obj);
    }
    public static <T> JsonResult<T> userDelFlag(){
        com.alibaba.fastjson.JSONObject obj = new com.alibaba.fastjson.JSONObject();
        obj.put("message", USER_DEL_FLAG);
        return new JsonResult("422", obj);
    }

    public static <T> JsonResult<T> changePwd(){
        com.alibaba.fastjson.JSONObject obj = new com.alibaba.fastjson.JSONObject();
        obj.put("message", CHANGE_PASSWORD);
        obj.put("changePassword",true);
        return new JsonResult("422", obj);
    }

}

class Message<T> {
    public static HttpStatus num2HttpStatus(String code) {
        HttpStatus status = HttpStatus.NOT_FOUND;
        for (HttpStatus httpStatus : HttpStatus.values()) {
            boolean b = Integer.parseInt(code) == httpStatus.value();
            if (b) {
                return httpStatus;
            }
        }
        return status;
    }

}