package com.yidian.bcommon.http

import android.annotation.SuppressLint
import com.google.gson.JsonParseException
import com.yidian.bcommon.app.YdBaseApplication
import com.yidian.bcommon.constant.ResultCode
import com.yidian.bcommon.constant.XEventConfig
import com.yidian.bcommon.constant.XRouterPathConstants
import com.yidian.bcommon.sdk.ClientType
import com.yidian.bcommon.sdk.JudgeClientUtils
import com.yidian.bcommon.services.ZapServiceActionConstants
import com.yidian.bcommon.services.ZapServiceNameConstants
import com.yidian.utils.ToastUtil
import com.yidian.xarc.xevent.XBaseEvent
import com.yidian.xarc.xevent.XEventManager
import com.yidian.xpage.XPageManager
import com.yidian.yac.core.zap.ZapTicket
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import org.json.JSONObject
import java.lang.reflect.ParameterizedType

abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false) : Observer<HttpResult<Any?>> {
  private var isShowErrorMsg = true

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

    }
  }

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

    }
  }

  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(res: HttpResult<Any?>) {
    when (res.code) {
      ResultCode.SUCCESS -> {
        val type = (this.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
        val decodeResult = HttpParamsUtils.rsaDecryptResult<T>(res, type)
        onRequestSuccess(decodeResult)
      }
      ResultCode.INVALID -> {
        // 登录失效 B端跳转登录页 C端登录成功后跳转管理中心
        if (JudgeClientUtils.judgeClient(YdBaseApplication.context.packageName) == ClientType.MERCHANT_B) {
          XPageManager.push(XRouterPathConstants.LOGIN_LIFE_CIRCLE, null)
        } else {
          ZapTicket(ZapServiceNameConstants.ClientInfoService).withAction(ZapServiceActionConstants.ActionGetLoginStatus).onResult {
            val result = (it.result as JSONObject).optBoolean("loginStatus")
            if (result) {
              XPageManager.popTo(XRouterPathConstants.MERCHANT_CENTER, null)
              // 通知登录成功
              XEventManager.post(XBaseEvent(XEventConfig.CLIENT_C_LOGIN_SUCCESS, null))
            }
          }.ship()
        }
      }
      else -> {
        val decodeResult = HttpResult<T>()
        decodeResult.code = res.code
        decodeResult.reason = res.reason
        decodeResult.status = res.status
        onFailure(decodeResult)
        ToastUtil.showToast(YdBaseApplication.context, res.reason)
      }
    }
  }

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

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

  @SuppressLint("NewApi")
  fun onRequestSuccess(result: HttpResult<T>?) {
    onSuccess(result)
  }
}
