package com.miya.fastcashier.net

import android.util.Log
import com.miya.fastcashier.BaseApplication.Companion.getApplication
import com.miya.fastcashier.R
import com.miya.fastcashier.utils.isNetworkConnected
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.net.SocketTimeoutException

/**
 * 类描述：通用请求返回
 * 创建人：zpxiang
 * 创建时间：
 * 修改人：
 * 修改时间：
 */
abstract class CommonCallback<T> : Callback<BaseResponse<T>?> {

    companion object {
        private const val RESPONSE_MSG_UNKNOW = "未知异常"
        private const val CALLBACK_SUCCEED_CODE = "200"
    }

    internal interface ErrorType {
        companion object {
            const val ERROR_TYPE_CUSTOM = 0
            const val ERROR_TYPE_HTTP = 1
            const val ERROR_TYPE_EXCEPTION = 2
        }
    }

    internal interface ResponseCode {
        companion object {
            val RESPONSE_CODE_FAILED: String = "-1" // 返回数据失败
            val RESPONSE_CODE_NETWORK_DISCONNECT: String = "-2" // 无网络
            val RESPONSE_CODE_NETWORK_TIMEOUT: String = "-3" // 超时
        }
    }

    override fun onResponse(call: Call<BaseResponse<T>?>, response: Response<BaseResponse<T>?>) {
        if (response.isSuccessful && response.body() != null) {
            val responseCode = response.body()!!.code // 业务自定义Code
            if (CALLBACK_SUCCEED_CODE == responseCode) {
                onSuccess(response.body()!!.data)
            } else {
                onFailure(
                    ErrorType.ERROR_TYPE_CUSTOM,
                    responseCode,
                    response.body()!!.getError()
                )
            }
        } else if (response.errorBody() != null) {
            onFailure(
                ErrorType.ERROR_TYPE_HTTP, response.code().toString(),
                response.errorBody().toString()
            )
        } else {
            onFailure(// 理论上不会存在此种情况
                ErrorType.ERROR_TYPE_HTTP,
                ResponseCode.RESPONSE_CODE_FAILED,
                RESPONSE_MSG_UNKNOW
            )
        }
    }

    override fun onFailure(call: Call<BaseResponse<T>?>, t: Throwable) {
        val temp = t.message
        Log.e("#### HttpLog", "请求失败：$temp")
        val errorMessage: String
        if (!isNetworkConnected(getApplication())) {
            errorMessage = getApplication().getString(R.string.common_prompt_network_error)
            onFailure(
                ErrorType.ERROR_TYPE_EXCEPTION,
                ResponseCode.RESPONSE_CODE_NETWORK_DISCONNECT,
                errorMessage
            )
            return
        }
        if (t is SocketTimeoutException) {
            errorMessage = getApplication().getString(R.string.common_prompt_network_timeout)
            onFailure(
                ErrorType.ERROR_TYPE_EXCEPTION,
                ResponseCode.RESPONSE_CODE_NETWORK_TIMEOUT,
                errorMessage
            )
        } else {
            errorMessage = getApplication().getString(R.string.common_prompt_data_error)
            onFailure(
                ErrorType.ERROR_TYPE_EXCEPTION,
                ResponseCode.RESPONSE_CODE_FAILED,
                errorMessage
            )
        }
    }

    abstract fun onSuccess(data: T)
    abstract fun onFailure(errorType: Int, errorCode: String?, errorMessage: String?)
}