package com.ama.core.architecture.basebean

import com.google.gson.annotations.SerializedName


open class ResponseNew<T>(
    @SerializedName(value = "data")
    val data: ResponseData<T>? = null,
    open val code: Int = -1,
    open val message: String = "",
) {

    companion object {
        const val SuccessCode = 200

        /**
         * zip打包的错误error封装
         * new
         */
        inline fun <reified T> createZipFailResponse(vararg data: ResponseNew<*>): ApiFailedResponse<T> {
            val failedResponse = ApiFailedResponse<T>()
            for (t in data) {
                if (!t.isApiSuccess) {
                    failedResponse.code = t.code
                    failedResponse.message = t.message
                    break
                }
            }
            return failedResponse
        }
    }

    val isOk: Boolean
        get() = code == SuccessCode

    val isApiSuccess: Boolean
        get() =
            this is ApiSuccessResponse || this is ApiEmptyResponse

    /**
     * 将返回结果分为成功和失败2个高阶函数
     *
     * 使用inline修饰，使2个参数可以调用外部函数return
     */
    inline fun transformResult(apiSuccessCallback: ((T?) -> Unit) = {}, apiFailedCallback: ((ResponseNew<T>) -> Unit) = {}): ResponseNew<T> {
        if (isApiSuccess) {
            apiSuccessCallback.invoke(data?.rows)
        } else {
            apiFailedCallback.invoke(this)
        }
        return this
    }
}

inline fun <reified T> ResponseNew<T>.parseData(listenerBuilder: (ResultBuilder<T>.() -> Unit), showToast: Boolean = false) {
    val listener = ResultBuilder<T>().also(listenerBuilder)
    when (this) {
        is ApiSuccessResponse -> listener.onSuccess(response?.rows)
        is ApiEmptyResponse -> listener.onSuccess(null)
        is ApiFailedResponse -> {
            listener.onFailed(this.code, this.message)
            listener.onFailedWithData(data?.rows)
            if (showToast) {
                //CommonApplicationProxy.application.toast()
            }
        }
    }
    listener.onComplete()
}

class ResultBuilder<T> {
    var onSuccess: (data: T?) -> Unit = {}
    var onFailed: (errorCode: Int, errorMsg: String) -> Unit = { _, _ ->
    }
    var onFailedWithData: (errorData: T?) -> Unit = {}
    var onComplete: () -> Unit = {}
}

data class ApiSuccessResponse<T>(val response: ResponseData<T>? = null) : ResponseNew<T>(data = response)

class ApiEmptyResponse<T> : ResponseNew<T>()

data class ApiFailedResponse<T>(override var code: Int = -1, override var message: String = "") :
    ResponseNew<T>(code = code, message = message)

