package com.template.model.result;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.template.common.result.Code;
import com.template.common.result.ResponseStatusEnum;

import java.io.Serializable;
import java.util.Map;

/**
 * @Author: codingliang
 * @Description: 接口统一返回
 * @Date: 2021-04-29 12:10
 * @Version: V1.0
 **/

@JsonInclude(JsonInclude.Include.NON_NULL)
public class CommonResult<T> extends BaseResult implements Serializable {


    private Integer status;
    // 调用是否成功
    private Boolean success;
    // 响应消息，可以为成功或者失败的消息
    private String msg;

    private T data;

    private static final long serialVersionUID = 3616484754899974346L;


    public static CommonResult ok() {
        return ok(Integer.toString(ResponseStatusEnum.SUCCESS.getStatus()), ResponseStatusEnum.SUCCESS.getMsg());
    }

    public static <T> CommonResult<T> ok(T data) {
        CommonResult<T> result = new CommonResult<T>(data);
        return result;
    }

    public static <T> CommonResult<T> ok(String msg) {
        return baseCreate(Integer.toString(ResponseStatusEnum.SUCCESS.getStatus()), msg, true);
    }

    public static <T> CommonResult<T> ok(String code, String msg) {
        return baseCreate(code, msg, true);
    }

    public static <T> CommonResult<T> ok(String msg, T data) {
        return baseCreate(Integer.toString(ResponseStatusEnum.SUCCESS.getStatus()), msg, true, data);
    }

    public static <T> CommonResult<T> ok(String code, String msg, T data) {
        return baseCreate(code, msg, true, data);
    }

    public static CommonResult fail() {
        return fail(Integer.toString(ResponseStatusEnum.FAILED.getStatus()), ResponseStatusEnum.FAILED.getMsg());
    }

    public static CommonResult fail(String code, String msg) {
        return baseCreate(code, msg, false);
    }

    public static CommonResult fail(String msg) {
        return baseCreate(Integer.toString(ResponseStatusEnum.FAILED.getStatus()), msg, false);
    }

    public static CommonResult fail(ResponseStatusEnum EnumCode){
        return baseCreate(Integer.toString(EnumCode.getStatus()), EnumCode.getMsg(), false);
    }

    public CommonResult() {}

    /**
     * 用Code自定义返回信息
     * 并把数据返回
     */
    public CommonResult(Code code, T data) {
        this.status = code.getStatus();
        this.msg = code.getMsg();
        this.success = code.getSuccess();
        this.data = data;
    }

    /**
     * 成功的返回信息
     */
    public CommonResult(T data) {
        this.setCode(Integer.toString(ResponseStatusEnum.SUCCESS.status()));
        this.setMessage(ResponseStatusEnum.SUCCESS.msg());
        this.setSuccess(ResponseStatusEnum.SUCCESS.success());
        this.setData(data);
    }

    /**
     * 自定义错误返回信息
     * @param EnumCode 枚举错误信息
     * @return
     */
    public CommonResult(ResponseStatusEnum EnumCode) {
        this.setCode(Integer.toString(EnumCode.status()));
        this.setMessage(EnumCode.msg());
        this.setSuccess(EnumCode.success());
    }


    private static <T> CommonResult<T> baseCreate(String code, String msg, boolean success) {
        CommonResult result = new CommonResult();
        result.setCode(code);
        result.setSuccess(success);
        result.setMessage(msg);
        return result;
    }

    private static <T> CommonResult<T> baseCreate(String code, String msg, boolean success, T data) {
        CommonResult result = new CommonResult();
        result.setCode(code);
        result.setSuccess(success);
        result.setMessage(msg);
        result.setData(data);
        return result;
    }

    public static CommonResult resultValue(ResponseStatusEnum responseStatus) {
        return new CommonResult(responseStatus);
    }

    /**
     * 错误返回，map中包含了多条错误信息，可以用于表单验证，把错误统一的全部返回出去
     *
     * @param map
     * @return
     */
    public static CommonResult errorMap(Map map) {
        return new CommonResult(ResponseStatusEnum.FAILED, map);
    }

    /**
     * 错误返回，直接返回错误的消息
     *
     * @param msg 提示信息
     * @return
     */
    public static CommonResult errorMsg(String msg) {
        return new CommonResult(ResponseStatusEnum.FAILED, msg);
    }

    public CommonResult<T> setResult(T data) {
        this.setData(data);
        return this;
    }

    @Override
    public T getData() {
        return (T) super.getData();
    }
}
