package com.yidian.bcommon.http

import com.google.gson.Gson
import com.google.gson.JsonParseException
import com.yidian.bcommon.app.YdBaseApplication
import com.yidian.bcommon.constant.ResultCode
import com.yidian.bcommon.sdk.BCommonManager
import com.yidian.utils.ToastUtil
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import timber.log.Timber

/**
 * author: yinjiacheng
 * date: 7/13/21 9:00 AM
 * description: 网路请求解析
 * 非加密接口使用
 */
abstract class HttpResultObserver<T> : Observer<HttpResult<T>> {
  private val gson by lazy { Gson() }
  private var isShowErrorMsg = true

  override fun onSubscribe(d: Disposable) { //网络请求之前

  }

  override fun onComplete() { //网络请求完成

  }

  override fun onError(e: Throwable) {
    if (e.toString().contains("ConnectException") || e.toString().contains("Unable to resolve host")) {
      if (isShowErrorMsg) {
        ToastUtil.showToast(YdBaseApplication.context, "当前网络链接不畅，请检查您的网络情况")
      }
    } else if ("connect timed out" == e.message) {
      if (isShowErrorMsg) {
        ToastUtil.showToast(YdBaseApplication.context, "服务器连接超时")
      }
    } else if (e is JsonParseException || e.toString().contains("Json") || e.toString().contains("Gson")) {
      if (isShowErrorMsg) {
        ToastUtil.showToast(YdBaseApplication.context, "数据解析异常")
      }
    } else {
      if (isShowErrorMsg) {
        ToastUtil.showToast(YdBaseApplication.context, "网络请求失败，请检查您的网络设置")
      }
    }
    onRequestFailure(Exception(e.toString()))
  }

  override fun onNext(result: HttpResult<T>) {
    when (result.code) {
      ResultCode.SUCCESS -> {
        Timber.tag(BCommonManager.TAG_HTTP).d("response result: ${gson.toJson(result.result)}")
        onRequestSuccess(result)
      }
      else -> {
        onFailure(result)
        ToastUtil.showToast(YdBaseApplication.context, result.reason ?: "网络请求失败")
      }
    }
  }

  abstract fun onSuccess(result: HttpResult<T>?)
  abstract fun onFailure(result: HttpResult<T>?)

  /**
   * 可根据实际情况选择是否复写此方法
   */
  open fun onNetworkFailure(result: HttpResult<T>?) {}

  private fun onRequestFailure(e: Throwable?) {
    val result: HttpResult<T> = HttpResult()
    result.code = -100
    result.reason = e?.message
    result.status = "failed"
    onNetworkFailure(result)
  }

  private fun onRequestSuccess(result: HttpResult<T>) {
    onSuccess(result)
  }
}
