package com.system.framework.core.response;

import com.system.framework.core.constant.GlobalConstants;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Objects;

/**
 * 全局返回对象
 *
 * @param <T>
 */
@ApiModel(value="全局返回对象",description="接口返回对象")
public class StarBosResult<T> implements Serializable {
    private static final Logger log = LoggerFactory.getLogger(StarBosResult.class);
    private static final long serialVersionUID = 1L;

    /**
     * 成功
     */
    public static final int SUCCESS = GlobalConstants.SUCCESS;

    /**
     * 失败
     */
    public static final int FAIL = GlobalConstants.FAIL;
    @ApiModelProperty(value = "状态码")
    private int code;
    @ApiModelProperty(value = "返回处理消息")
    private String msg;
    @ApiModelProperty(value = "数据")
    private T data;

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public static <T> StarBosResult<T> ok() {
        return restStarBosResultesult(null, SUCCESS, null);
    }

    public static <T> StarBosResult<T> ok(T data) {
        return restStarBosResultesult(data, SUCCESS, null);
    }

    public static <T> StarBosResult<T> ok(T data, String msg) {
        return restStarBosResultesult(data, SUCCESS, msg);
    }

    public static <T> StarBosResult<T> fail() {
        return restStarBosResultesult(null, FAIL, null);
    }

    public static <T> StarBosResult<T> fail(String msg) {
        return restStarBosResultesult(null, FAIL, msg);
    }

    public static <T> StarBosResult<T> fail(T data) {
        return restStarBosResultesult(data, FAIL, null);
    }

    public static <T> StarBosResult<T> fail(T data, String msg) {
        return restStarBosResultesult(data, FAIL, msg);
    }

    public static <T> StarBosResult<T> fail(int code, String msg) {
        return restStarBosResultesult(null, code, msg);
    }

    private static <T> StarBosResult<T> restStarBosResultesult(T data, int code, String msg) {
        StarBosResult<T> apiStarBosResultesult = new StarBosResult<>();
        apiStarBosResultesult.setCode(code);
        apiStarBosResultesult.setData(data);
        apiStarBosResultesult.setMsg(msg);
        return apiStarBosResultesult;
    }

    public StarBosResult<T> error500(String message) {
        this.msg = message;
        this.code = GlobalConstants.FAIL;

        return this;
    }
    public StarBosResult<T> success(String message) {
        this.msg = message;
        this.code = SUCCESS;
        return this;
    }

    public static <T> StarBosResult<T> success(T data) {
        StarBosResult<T> serverResponseEntity = new StarBosResult<>();
        serverResponseEntity.setData(data);
        serverResponseEntity.setCode(StarBosResultEnum.OK.value());
        return serverResponseEntity;
    }

    public static <T> StarBosResult<T> success() {
        StarBosResult<T> serverResponseEntity = new StarBosResult<>();
        serverResponseEntity.setCode(StarBosResultEnum.OK.value());
        serverResponseEntity.setMsg(StarBosResultEnum.OK.getMsg());
        return serverResponseEntity;
    }
    public StarBosResult<T> error500(String message, T data) {
        this.msg = message;
        this.code = GlobalConstants.FAIL;
        this.data = data;
        return this;
    }
    public StarBosResult<T> successOk(String message, T data) {
        this.msg = message;
        this.code = StarBosResultEnum.OK.value();
        this.data = data;
        return this;
    }
    public StarBosResult<T> successOk( T data) {
        this.code = StarBosResultEnum.OK.value();
        this.data = data;
        return this;
    }
    public boolean isSuccess() {
        return Objects.equals(StarBosResultEnum.OK.value(), this.code);
    }

    public static <T> StarBosResult<T> fail(StarBosResultEnum starBosResultEnum) {
        log.error(starBosResultEnum.toString());
        StarBosResult<T> starBosResult = new StarBosResult<>();
        starBosResult.setMsg(starBosResultEnum.getMsg());
        starBosResult.setCode(starBosResultEnum.value());
        return starBosResult;
    }

    public static <T> StarBosResult<T> fail(StarBosResultEnum starBosResultEnum, T data) {
        log.error(starBosResultEnum.toString());
        StarBosResult<T> starBosResult = new StarBosResult<>();
        starBosResult.setMsg(starBosResultEnum.getMsg());
        starBosResult.setCode(starBosResultEnum.value());
        starBosResult.setData(data);
        return starBosResult;
    }

    public static <T> StarBosResult<T> transform(StarBosResult<?> oldStarBosResult) {
        StarBosResult<T> starBosResult = new StarBosResult<>();
        starBosResult.setMsg(oldStarBosResult.getMsg());
        starBosResult.setCode(oldStarBosResult.getCode());
        log.error(starBosResult.toString());
        return starBosResult;
    }

    public static Object badArgument() {
        return fail(401, "参数不对");
    }

    public static Object badArgumentValue() {
        return fail(402, "参数值不对");
    }

    public static Object updatedDateExpired() {
        return fail(504, "更新数据已经失效");
    }

    public static Object updatedDataFailed() {
        return fail(505, "更新数据失败");
    }

    public int getCode() {
        return code;
    }


}
