package com.common.commonlib.net

import android.net.ParseException
import android.util.Log
import com.common.commonlib.log.Logger
import com.common.commonlib.net.callback.RequestCallBack
import com.google.gson.JsonParseException
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.Interceptor
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import javax.net.ssl.SSLHandshakeException

/**
 * 请求基类
 *
 * @author wangym
 * @since 2021/7/28
 */
open class BaseObserve<T> {
    var api: T

    constructor(clazz: Class<T>) {
        api = RequestManager.create(clazz)
    }

    constructor(clazz: Class<T>, interceptors: List<Interceptor>) {
        api = RequestManager.create(clazz, interceptors)
    }

    /**
     * 提供方法给外部获取API
     */
    fun getAPI(): T {
        return api
    }

    /**
     * 初始化服务类
     */
    fun initService(clazz: Class<T>): T {
        return RequestManager.create(clazz)
    }

    /**
     * 初始化服务类
     */
    fun initService(clazz: Class<T>, interceptors: List<Interceptor>): T {
        return RequestManager.create(clazz, interceptors)
    }

    /**
     * 调用接口
     * @param observable 可订阅
     * @param callBack 请求回调
     */
    fun <R> observe(observable: Observable<R>?, callBack: RequestCallBack<R>?) {
        if (observable == null) {
            Logger.e("BaseObserve", "observe observable is null")
            return
        }
        observable
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<R> {
                override fun onSubscribe(d: Disposable) {
                }

                override fun onNext(t: R) {
                    callBack?.onResult(t)
                }

                override fun onError(e: Throwable) {
                    e.message?.let { Log.e(TAG, it) }
                    callBack?.onError(dealError(e))
                }

                override fun onComplete() {
                    callBack?.onComplete()
                }
            })
    }

    /**
     * 处理错误
     * @param e 异常
     */
    private fun dealError(e: Throwable): String? {
        if (e is HttpException) {
            return when (e.code()) {
                UNAUTHORIZED -> "登录验证过期"
                INTERNAL_SERVER_ERROR -> "服务器错误"
                FORBIDDEN, NOT_FOUND -> "无效的请求"
                REQUEST_TIMEOUT, GATEWAY_TIMEOUT, BAD_GATEWAY, SERVICE_UNAVAILABLE -> e.message()
                else -> e.message()
            }
        } else if (e is ConnectException) {
            return "网络连接异常，请检查您的网络状态"
        } else if (e is SocketTimeoutException) {
            return "网络连接超时，请检查您的网络状态，稍后重试"
        } else if (e is UnknownHostException) {
            return "网络异常，请检查您的网络状态"
        } else if (e is JsonParseException || e is JSONException || e is ParseException) {
            return "数据解析错误"
        } else if (e is SSLHandshakeException) {
            return "网络异常，请检查您的网络状态"
        } else if (e is RuntimeException) {
            return "运行时异常"
        }
        return e.message
    }

    companion object {
        const val TAG: String = "BaseLoader"
        const val UNAUTHORIZED = 401
        const val FORBIDDEN = 403
        const val NOT_FOUND = 404
        const val REQUEST_TIMEOUT = 408
        const val INTERNAL_SERVER_ERROR = 500
        const val BAD_GATEWAY = 502
        const val SERVICE_UNAVAILABLE = 503
        const val GATEWAY_TIMEOUT = 504
    }
}