package com.weather.vo;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.weather.common.constant.ApiConstant;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author feng
 * @desc : API返回结果统一封装类
 * @update : 修改说明
 * @date : 2020/2/26-01:13
 * @version: 1.0
 * @email : 459638186@qq.com
 * @company: yuannongye
 */
@ApiModel(value = "API返回结果统一封装类")
@Data
public class ApiResult<T> implements Serializable {

    private static final long serialVersionUID = -1750618305134261021L;

    /**
     * 状态码
     */
    @ApiModelProperty(value = "状态码")
    private Integer code;

    /**
     * 提示消息
     */
    @ApiModelProperty(value = "提示消息")
    private String message;

    /**
     * 时间戳
     */
    @ApiModelProperty(value = "时间戳")
    private Long timeStamp;

    /**
     * 分页信息：总页数,分页才显示
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @ApiModelProperty(value = "分页的时候总的页数,分页加载才有")
    private Long totalPage;

    /**
     * 分页信息：总记录数,分页才显示
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @ApiModelProperty(value = "分页的时候总的记录数,分页加载才有")
    private Long totalCount;

    /**
     * 分页信息：当前页数,分页才显示
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @ApiModelProperty(value = "当前请求页数,分页加载才有")
    private Long page;

    /**
     * 分页信息：每页数量,分页才显示
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @ApiModelProperty(value = "当前请求每页数量,分页加载才有")
    private Long limit;

    /**
     * 数据 data:{} 永远是对象，
     * 即：如果给定的data是数组，则必须再包裹一层，结果为 data:{data:[]}
     */
    @ApiModelProperty(value = "返回值说明，data:可能是字符串、对象、数组")
    private T data;

    public ApiResult() {
    }
    public ApiResult(String message, T data) {
        this(ApiConstant.CODE_SUCCESS,  message,  null,  null,  null,  null, data);
    }

    public ApiResult(Integer code, String message, T data) {
        this( code,  message,  null,  null,  null,  null, data);
    }

    public ApiResult(Integer code, String message, Long totalPage, Long totalCount, Long page, Long limit, T data) {
        this.code = code;
        this.message = message;
        this.timeStamp = System.currentTimeMillis();
        this.totalPage = totalPage;
        this.totalCount = totalCount;
        this.page = page;
        this.limit = limit;

        this.data = data;
    }

    public static ApiResult success(){
        return  ApiResult.success("操作成功");
    }

    public static ApiResult success(String message){
        return  ApiResult.success(message,"");
    }
    public static ApiResult success(Object data){
        return  ApiResult.success("操作成功",data);
    }


    public static ApiResult success(String message, Object data){
        return  ApiResult.success(ApiConstant.CODE_SUCCESS,message,data);
    }

    public static ApiResult success(int code, String message, Object data){
        return new ApiResult(code,message,data);
    }

    public static ApiResult success(String message, Object data, Long page, Long limit, Long totalCount, Long totalPage){
        return new ApiResult(ApiConstant.CODE_SUCCESS,message,totalPage,totalCount,page,limit,data);
    }
    public static ApiResult success(Object data, IPage page){
        return new ApiResult(ApiConstant.CODE_SUCCESS,"加载成功",page.getPages(),page.getTotal(),page.getCurrent(),page.getSize(),data);
    }

    /**
     * 适用于没有特殊转换的字段
     * @param page 结果集
     * @param clz 响应对象字节码
     * @param <T> 响应泛型
     * @param <E> 查询泛型
     * @return
     */
    public static <T,E> ApiResult successPage(IPage<E> page,Class<? extends T> clz) {

        if (page.getTotal()<=0){
            return ApiResult.noData();
        }
        List<E> records = page.getRecords();
        List<T> resList = new ArrayList<>();
        T model;
        for (E record : records) {
            try {
                model = clz.newInstance();
            } catch (InstantiationException e) {
                return ApiResult.error("类实例化失败",e.getMessage());
            } catch (IllegalAccessException e) {
                return ApiResult.error("类实例化失败",e.getMessage());
            }
            BeanUtils.copyProperties(record, model);
            resList.add(model);
        }
        return ApiResult.success( resList, page);
    }
    public static <T,E> ApiResult successList(List<E> list,Class<? extends T> clz) {

        if (list==null||list.size()<=0){
            return ApiResult.noData();
        }
        List<T> resList = new ArrayList<>();
        T model;
        for (E record : list) {
            try {
                model = clz.newInstance();
            } catch (InstantiationException e) {
                return ApiResult.error("类实例化失败",e.getMessage());
            } catch (IllegalAccessException e) {
                return ApiResult.error("类实例化失败",e.getMessage());
            }
            BeanUtils.copyProperties(record, model);
            resList.add(model);
        }
        return ApiResult.success( resList);
    }

    public static ApiResult error(){
        return  ApiResult.error("操作失败",null);
    }
    public static ApiResult error(String message){
        return  ApiResult.error(message,null);
    }
    public static ApiResult error(String message, Object data){
        return  ApiResult.error(ApiConstant.CODE_BAD_REQUEST,message,data);
    }
    public static ApiResult error(int code, String message, Object data){
        return new ApiResult(code,message,data);
    }


    public static ApiResult errorToken(){
        return new ApiResult(ApiConstant.CODE_ERROR_TOKEN,"登录已过期",null);
    }

    public static ApiResult noData(){
        return noData("暂无数据");
    }
    public static ApiResult noData(String message){
        return new ApiResult(ApiConstant.CODE_SUCCESS_NODATA,message,null);
    }
    public static ApiResult errorParam(){
        return new ApiResult(ApiConstant.CODE_ERROR_PARAM,"参数错误",null);
    }
    public static ApiResult errorSign(){
        return new ApiResult(ApiConstant.CODE_ERROR_SIGN,"签名错误",null);
    }

    public static ApiResult errorLogin(){
        return new ApiResult(ApiConstant.CODE_ERROR_TOKEN,"登录已过期",null);
    }

    /**
     * 未实现方法错误信息
     * @return
     */
    public static ApiResult noAchieve(){
        return  ApiResult.error("还未实现该方法",null);
    }


    public static ApiResult toBooleanRes(boolean res,Object data) {
        if (res){
            return ApiResult.success("操作成功",data);
        }
        return ApiResult.error();
    }

    public static ApiResult toBooleanRes(int res,Object data) {
        if (res>=1){
            return ApiResult.success("操作成功",data);
        }
        return ApiResult.error();
    }

}
