package com.seer.teach.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.seer.teach.common.enums.ResultCodeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 全局响应封装类，统一API返回格式
 *
 * @param <T> 返回数据的泛型类型
 * @author Captain
 * @version 1.0
 * @since 2022-11-03
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(description =  "全局返回类，封装接口返回数据格式")
public class ResultBean<T> {

    @Schema(description = "状态码")
    private int code;

    @Schema(description = "描述信息")
    private String msg;

    @Schema(description = "返回数据")
    private T data;

    /**
     * 构建无数据的成功响应
     *
     * @param <T> 泛型类型
     * @return 通用成功响应对象
     */
    public static <T> ResultBean<T> success() {
        return new ResultBean<>(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMsg(), null);
    }

    /**
     * 构建含数据的成功响应
     *
     * @param data 需要返回的数据对象
     * @param <T>  泛型类型
     * @return 包含数据的成功响应对象
     */
    public static <T> ResultBean<T> success(T data) {
        return new ResultBean<>(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMsg(), data);
    }

    /**
     * 构建默认错误响应（内部服务器错误）
     *
     * @param <T> 泛型类型
     * @return 默认错误响应对象
     */
    public static <T> ResultBean<T> error() {
        return new ResultBean<>(ResultCodeEnum.INTERNAL_SERVER_ERROR.getCode(), ResultCodeEnum.INTERNAL_SERVER_ERROR.getMsg(), null);
    }

    /**
     * 构建自定义错误响应
     *
     * @param code 错误码
     * @param msg  错误描述
     * @param <T>  泛型类型
     * @return 自定义错误响应对象
     */
    public static <T> ResultBean<T> error(int code, String msg) {
        return new ResultBean<>(code, msg, null);
    }

    /**
     * 构建基于枚举的错误响应
     *
     * @param resultCodeEnum 错误码枚举对象
     * @param <T>            泛型类型
     * @return 枚举定义的错误响应对象
     */
    public static <T> ResultBean<T> error(ResultCodeEnum resultCodeEnum) {
        return new ResultBean<>(resultCodeEnum.getCode(), resultCodeEnum.getMsg(), null);
    }

    @JsonIgnore
    public boolean isSuccess() {
        return this.code == 200;
    }
}
