package com.framework.mvvm.model.data

/**
 * from  获取数据
 *  to   保存数据
 * error 出错信息
 */
suspend fun <T> request(
    from: suspend () -> Model<T>,
    to: suspend (T) -> Unit,
    error: ((String) -> Unit)? = null
): Boolean {
    var result = false
    runCatching {
        from()
    }.onSuccess {
        if (it.code == "00000") {
            to(it.data)
            result = true
        }
    }.onFailure {
        error?.invoke(it.message ?: "you know nothing")
    }
    return result
}

/**
 * 发起网络请求, 封装返回结果
 *
 * @param         block : 实际请求数据的函数, 是挂起函数
 * @return  Response<T> : 封装 block() 结果
 * */
suspend fun <T> request(block: suspend () -> Model<T>): Response<T> {
    var result: Response<T> = EmptyResponse()
    runCatching {
        block()
    }.onSuccess {
        // "00000" 代表数据请求成功
        result = if (it.code == "00000" || it.message == "success") {
            Response.create(it.data)
        } else {
            Response.create(it.message ?: "http request Ok, but don't have data")
        }
    }.onFailure {
        result = Response.create(it.message ?: "you know nothing")
    }
    return result
}

/**
 * ② Http 数据容器
 */
sealed class Response<T> {
    companion object {
        fun <T> create(message: String): FailureResponse<T> {
            return FailureResponse(message)
        }

        fun <T> create(data: T): Response<T> {
            return SuccessResponse(data)
        }

        fun <T> create(): Response<T> = EmptyResponse()
    }
}

class EmptyResponse<T> : Response<T>()
data class SuccessResponse<T>(val data: T) : Response<T>()
data class FailureResponse<T>(val msg: String) : Response<T>()