/*
 * Copyright 2019-2029 geekidea(https://github.com/geekidea)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.geekidea.springbootplus.framework.common.api;

import io.geekidea.springbootplus.framework.config.il8n.I18nMessageUtil;
import io.geekidea.springbootplus.framework.config.il8n.LanguageEnum;
import io.geekidea.springbootplus.framework.util.HttpServletRequestUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * REST API 返回结果
 * 国际化message封装
 * </p>
 *
 * @author geekidea
 * @since 2018-11-08
 */
@Data
@Accessors(chain = true)
@Builder
@AllArgsConstructor
public class ApiResult<T> implements Serializable {
    private static final long serialVersionUID = 8004487252556526569L;

    /**
     * 响应码
     */
    private int code;
//
//    /**
//     * 是否成功
//     */
//    private boolean success;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应数据
     */
    private T data;

//    /**
//     * 响应时间
//     */
//    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//    private Date time;

    public ApiResult() {
//        time = new Date();
    }

    public static ApiResult<Boolean> result(boolean flag) {
        if (flag) {
            return ok();
        }
        return fail();
    }

    public static ApiResult<Boolean> result(boolean flag, String language) {
        if (flag) {
            return ok(null, language);
        }
        return fail(language);
    }

    public static ApiResult<Boolean> result(ApiCode apiCode) {
        return result(apiCode, null);
    }

    public static <T> ApiResult<T> result(ApiCode apiCode, T data) {
        return result(apiCode, null, data, null);
    }

    public static <T> ApiResult<T> result(ApiCode apiCode, T data, String language) {
        return result(apiCode, null, data, language);
    }


    public static <T> ApiResult<T> result(ApiCode apiCode, String message, T data, String language) {
//        boolean success = false;
//        if (apiCode.getCode() == ApiCode.SUCCESS.getCode()) {
//            success = true;
//        }

        // 多语言国际化,根据http上下文, 取得heard中的language语言属性,实现不用在业务代码中传递语言字段
        HttpServletRequest request = HttpServletRequestUtil.getRequest();
        language = request.getHeader("language");

        String success = "SUCCESS";
        try {
            message = I18nMessageUtil.getMessage(LanguageEnum.getLanguageType(language), apiCode.getMessage(), success);
        } catch (IOException e) {
            message = success;
        }


        return (ApiResult<T>) ApiResult.builder()
                .code(apiCode.getCode())
                .message(message)
                .data(data)
//                .success(success)
//                .time(new Date())
                .build();
    }

    public static ApiResult<Boolean> ok() {
        return ok(null);
    }

    public static <T> ApiResult<T> ok(T data) {
        return result(ApiCode.SUCCESS, data);
    }

    public static <T> ApiResult<T> ok(T data, String language) {
        return result(ApiCode.SUCCESS, data, language);
    }

//    public static <T> ApiResult<T> ok(T data, String message) {
//        return result(ApiCode.SUCCESS, message, data);
//    }

//    public static ApiResult<Map<String, Object>> okMap(String key, Object value) {
//        Map<String, Object> map = new HashMap<>(1);
//        map.put(key, value);
//        return ok(map);
//    }

    public static ApiResult<Boolean> fail(ApiCode apiCode) {
        return result(apiCode, null);
    }

    public static <T> ApiResult<T> fail(ApiCode apiCode, String language) {
        return result(apiCode, null, language);
    }


//    public static ApiResult<String> fail(String message) {
//        return result(ApiCode.FAIL, message, null);
//    }

    public static <T> ApiResult<T> fail(ApiCode apiCode, T data) {
        if (ApiCode.SUCCESS == apiCode) {
            throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode());
        }
        return result(apiCode, data);
    }

    public static <T> ApiResult<T> fail(ApiCode apiCode, T data, String language) {
        if (ApiCode.SUCCESS == apiCode) {
            throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode());
        }
        return result(apiCode, data, language);
    }

    public static ApiResult<String> fail(Integer errorCode, String message) {
        return new ApiResult<String>()
//                .setSuccess(false)
                .setCode(errorCode)
                .setMessage(message);
    }

    public static ApiResult<Map<String, Object>> fail(String key, Object value) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(key, value);
        return result(ApiCode.FAIL, map);
    }

    public static ApiResult<Boolean> fail() {
        return fail(ApiCode.FAIL);
    }

    public static ApiResult<Boolean> fail(String language) {
        return fail(ApiCode.FAIL, language);
    }
}