package com.example.system.common;

import lombok.Data;
import lombok.NoArgsConstructor;

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

/**
 * 统一返回结果类
 */
@Data
@NoArgsConstructor
public class R<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    private Integer status;

    /**
     * 返回消息
     */
    private String msg;

    /**
     * 返回数据
     */
    private T data;

    /**
     * 附加数据
     */
    private Map<String, Object> additionalData = new HashMap<>();

    /**
     * 通用返回成功
     */
    public static <T> R<T> success() {
        R<T> result = new R<>();
        result.setStatus(ResultCode.SUCCESS.getCode());
        result.setMsg(ResultCode.SUCCESS.getMessage());
        return result;
    }

    /**
     * 返回成功消息
     */
    public static <T> R<T> success(String message) {
        R<T> result = new R<>();
        result.setStatus(ResultCode.SUCCESS.getCode());
        result.setMsg(message);
        return result;
    }

    /**
     * 返回成功数据
     */
    public static <T> R<T> success(T data) {
        R<T> result = new R<>();
        result.setStatus(ResultCode.SUCCESS.getCode());
        result.setMsg(ResultCode.SUCCESS.getMessage());
        result.setData(data);
        return result;
    }

    /**
     * 返回成功消息和数据
     */
    public static <T> R<T> success(String message, T data) {
        R<T> result = new R<>();
        result.setStatus(ResultCode.SUCCESS.getCode());
        result.setMsg(message);
        result.setData(data);
        return result;
    }

    /**
     * 通用返回失败
     */
    public static <T> R<T> error() {
        R<T> result = new R<>();
        result.setStatus(ResultCode.ERROR.getCode());
        result.setMsg(ResultCode.ERROR.getMessage());
        return result;
    }

    /**
     * 返回失败消息
     */
    public static <T> R<T> error(String message) {
        R<T> result = new R<>();
        result.setStatus(ResultCode.ERROR.getCode());
        result.setMsg(message);
        return result;
    }

    /**
     * 返回失败状态码和消息
     */
    public static <T> R<T> error(int code, String message) {
        R<T> result = new R<>();
        result.setStatus(code);
        result.setMsg(message);
        return result;
    }

    /**
     * 添加附加数据
     */
    public R<T> add(String key, Object value) {
        this.additionalData.put(key, value);
        return this;
    }

    /**
     * 返回结果状态码枚举
     */
    public enum ResultCode {
        SUCCESS(200, "操作成功"),
        ERROR(500, "操作失败"),
        VALIDATE_FAILED(400, "参数校验失败"),
        UNAUTHORIZED(401, "暂未登录或token已经过期"),
        FORBIDDEN(403, "没有相关权限");

        private final int code;
        private final String message;

        ResultCode(int code, String message) {
            this.code = code;
            this.message = message;
        }

        public int getCode() {
            return code;
        }

        public String getMessage() {
            return message;
        }
    }
}