package com.yidianling.im.helper

import android.annotation.SuppressLint
import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.text.TextUtils
import android.view.View
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.data.http.RxUtils.applySchedulers
import com.ydl.ydlcommon.data.http.UpLoadLogUtils.upLoadLog
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.ui.LoadingDialogFragment
import com.ydl.ydlcommon.ui.LoadingDialogFragment.Companion.newInstance
import com.ydl.ydlcommon.utils.NetworkParamsUtils
import com.ydl.ydlcommon.utils.UserInfoCache
import com.ydl.ydlcommon.utils.remind.HttpErrorUtils.Companion.handleError
import com.ydl.ydlcommon.view.dialog.CommonDialog
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.R
import com.yidianling.im.api.bean.IMExpertBuild
import com.yidianling.im.bean.DoctorAssistantRespDtoBean
import com.yidianling.im.bean.GetExpert
import com.yidianling.im.bean.UserTypeBean
import com.yidianling.im.bridge.P2PCustomActionHandlerImpl
import com.yidianling.im.config.constants.ImConstants
import com.yidianling.im.http.ImRetrofitApi.Companion.getImJavaApi
import com.yidianling.im.http.ImRetrofitApi.Companion.getImRetrofitApi
import com.yidianling.im.router.ImIn
import com.yidianling.im.router.ImIn.isLogin
import com.yidianling.im.session.SessionHelper
import com.yidianling.im.ui.page.fragment.bean.ChatItemBean
import com.yidianling.uikit.business.session.fragment.YDLMessageFragment
import com.yidianling.uikit.business.session.helper.ChatStatusCacheHelper
import com.yidianling.uikit.custom.bridge.ActionHandlerStorage
import com.yidianling.uikit.custom.bridge.IP2PCustomActionHandler
import com.yidianling.uikit.custom.http.ServiceImpl.Companion.instance
import com.yidianling.uikit.custom.http.response.ChatStatusBean
import com.yidianling.uikit.custom.http.response.RecommendExpertBean
import com.yidianling.uikit.custom.widget.TitleBarBottom
import com.yidianling.user.api.service.IUserService
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import java.net.URLEncoder

/**
 * 私聊页面相关接口封装
 */
object IMChatUtil {
    private var loadingDialog: LoadingDialogFragment? = null
    private const val USER_TYPE_EXPERT=2//专家
    private const val USER_TYPE_ASSISTANT=3//助理
    private const val USER_TYPE_USER=1//用户
    /**
     * 接口数据请求完成回调
     */
    interface ChatDataRequestListener {
        fun onSuccess(expertInfo: IMExpertBuild)
    }

    /**
     * 客服专用
     */
    fun startKefuChat(context: AppCompatActivity?) {
        SessionHelper.startP2PSession(
            context,
            -1,
            ImConstants.KEFUXIAOYI,
            null,
            P2PCustomActionHandlerImpl(ImConstants.KEFUXIAOYI, "客服小壹", ImConstants.KEFUXIAOYI)
        )
    }

    /**
     * 私聊列表进入，后置数据请求
     *
     * @param context
     * @param chatItemBean
     */
    fun startChat(context: AppCompatActivity?, chatItemBean: ChatItemBean) {
        SessionHelper.startP2PSession(
            context,
            chatItemBean.utype,
            chatItemBean.toUid.toString(),
            null,
            P2PCustomActionHandlerImpl(chatItemBean)
        )
    }

    /**
     * 非私聊列表进入，前置数据请求
     *
     * @param context
     * @param toUid
     * @param isFromQingShu     用于判断是否从倾诉流程跳转私聊：1：是   其他：不是    从倾述流程跳转私聊，需要发送自定义消息
     */
    @SuppressLint("CheckResult")
    fun startChat(context: AppCompatActivity, toUid: String, isFromQingShu: Int) {
        if (!isLogin(context, true)) {
            return
        }
        if (loadingDialog == null) {
            loadingDialog = newInstance(null)
        }
        if (context.supportFragmentManager != null && !context.isDestroyed) {
            loadingDialog?.show(context.supportFragmentManager, null)
        }
        getImJavaApi().getUserType(toUid)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ res: BaseResponse<UserTypeBean> ->
                if (res.code == 200 && res.data != null) {
                    if (res.data!!.chatEvent) { //和助理私聊需要打开常用语弹窗
                        ChatStatusCacheHelper.setStatusCache(
                            "chatEvent",
                            res.data!!.chatEvent
                        )
                    }
                    if (res.data!!.collectEvent) { //和助理私聊需要打开信息采集弹窗
                        ChatStatusCacheHelper.setStatusCache(
                            "collectEvent",
                            res.data!!.collectEvent
                        )
                    }
                    if (TextUtils.equals(res.data!!.userType, USER_TYPE_EXPERT.toString())) { //专家
                        //在uid用户类型确定为专家的情况下，根据uid调用接口判断是进入专家私聊还是助理私聊
                        getImJavaApi().getChatUid(toUid)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe({ resp: BaseAPIResponse<DoctorAssistantRespDtoBean> ->
                                val bean = resp.data
                                val toUid = bean.chatUid
                                prepareChatData(context, toUid, object :
                                    ChatDataRequestListener {
                                    override fun onSuccess(expertInfo: IMExpertBuild) {
                                        startChatSession(toUid, expertInfo, isFromQingShu, context)
                                    }
                                })
                            }) { t: Throwable? ->
                                handleError(context, t!!)
                            }
                    } else {
                        prepareAssistantChatData(context, toUid, object : ChatDataRequestListener {
                            override fun onSuccess(expertInfo: IMExpertBuild) {
                                startChatSession(toUid, expertInfo, isFromQingShu, context)
                            }
                        })
                    }
                } else {
                    if (loadingDialog != null && loadingDialog!!.isVisible) {
                        loadingDialog?.dismissAllowingStateLoss()
                    }
                    ToastUtil.toastShort(res.msg)
                }
            }, { throwable: Throwable? ->
                if (loadingDialog != null && loadingDialog!!.isVisible) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                handleError(context, throwable!!)
            }
            )
    }


    fun startChatCloseReplaceChat(context: AppCompatActivity, toUid: String) {
        if (!isLogin(context, true)) {
            return
        }
        if (loadingDialog == null) {
            loadingDialog = newInstance(null)
        }
        if (context.supportFragmentManager != null && !context.isDestroyed) {
            loadingDialog?.show(context.supportFragmentManager, null)
        }
        prepareChatData(context, toUid, object :
            ChatDataRequestListener {
            override fun onSuccess(expertInfo: IMExpertBuild) {
                startChatSession(toUid, expertInfo, 0, context)
            }
        })
    }

    /**
     * 开启聊天会话
     */
    private fun startChatSession(
        toUid: String,
        expertInfo: IMExpertBuild,
        isFromQingShu: Int,
        context: AppCompatActivity
    ) {
        val p2PCustomActionHandlerImpl = P2PCustomActionHandlerImpl(toUid, expertInfo)
        p2PCustomActionHandlerImpl.isFromQingShu = isFromQingShu
        SessionHelper.startP2PSession(
            context,
            expertInfo.shareData.user_type,
            toUid,
            null,
            p2PCustomActionHandlerImpl
        )
    }

    //====================准备私聊数据====================
    /**
     * 初始化聊天数据
     */
    fun prepareChatData(
        context: AppCompatActivity,
        toUid: String,
        listener: ChatDataRequestListener
    ) {
        if (!isLogin(context, true)) {
            return
        }
        val dis = getImJavaApi().getUserType(toUid)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ res: BaseResponse<UserTypeBean> ->
                if (res.code == 200 && res.data != null) {
                    if (res.data!!.chatEvent) { //和助理私聊需要打开常用语弹窗
                        ChatStatusCacheHelper.setStatusCache("chatEvent", res.data!!.chatEvent)
                    }
                    if (res.data!!.collectEvent) { //和助理私聊需要打开信息采集弹窗
                        ChatStatusCacheHelper.setStatusCache(
                            "collectEvent",
                            res.data!!.collectEvent
                        )
                    }
                    if (TextUtils.equals(res.data!!.userType, "2")) {
                        //接口返回值是专家，java接口
                        prepareExpertChatData(context, toUid, listener)
                    } else { //非专家 php接口
                        prepareAssistantChatData(context, toUid, listener)
                    }
                } else {
                    if (loadingDialog != null && loadingDialog!!.isVisible) {
                        loadingDialog?.dismissAllowingStateLoss()
                    }
                    ToastUtil.toastShort(res.msg)
                }
            }, { throwable: Throwable? ->
                if (loadingDialog != null && loadingDialog!!.isVisible) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                handleError(context, throwable!!)
            }
            )
    }

    /**
     * 专家私聊数据请求
     */
    fun prepareExpertChatData(
        context: AppCompatActivity,
        toUid: String?,
        listener: ChatDataRequestListener
    ) {
        val disposable = getImJavaApi().getPersonalChat(toUid!!)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ resp: BaseResponse<IMExpertBuild> ->
                if (null != loadingDialog && loadingDialog?.isVisible!!) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                if (resp.code == 200) {
                    val expert = resp.data
                    UserInfoCache.getInstance().saveYDLUser(
                        expert.shareData.toUid,
                        expert.shareData.doctorName,
                        expert.shareData.cover
                    )
                    listener.onSuccess(expert)
                } else {
                    upLoadLog("consult/get-expert", resp.code, resp.msg)
                    if (resp.code == ImConstants.HTTP_CODE_UNLOGIN) {
                        ImIn.loginByOneKeyLogin(context,true)
                        ToastUtil.toastShort(resp.msg)
                    } else if (resp.code == ImConstants.SILENCED_CODE) { //禁言
                        showSilencedDialog(context, resp.data.tips, resp.data.url)
                    } else {
                        ToastUtil.toastShort(resp.msg)
                    }
                }
            }
            ) { throwable: Throwable ->
                if (null != loadingDialog && loadingDialog!!.isVisible) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                handleError(context, throwable)
                if (throwable is HttpException) {
                    upLoadLog("consult/get-expert", throwable.code(), throwable.message!!)
                }
            }
    }

    /**
     * 助理私聊数据请求
     */
    fun prepareAssistantChatData(
        context: AppCompatActivity,
        toUid: String,
        listener: ChatDataRequestListener
    ) {
        val cmd = GetExpert(toUid.toInt(), 0)
        val disposable =
            getImRetrofitApi().getExpert(NetworkParamsUtils.getMaps(cmd))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ resp: BaseResponse<IMExpertBuild> ->
                    if (null != loadingDialog && loadingDialog!!.isVisible) {
                        loadingDialog?.dismissAllowingStateLoss()
                    }
                    if (resp.code == 0) {
                        val expert = resp.data
                        UserInfoCache.getInstance().saveYDLUser(
                            expert.shareData.toUid,
                            expert.shareData.doctorName,
                            expert.shareData.cover
                        )
                        listener.onSuccess(expert)
                    } else {
                        upLoadLog("consult/get-expert", resp.code, resp.msg)
                        if (resp.code == ImConstants.HTTP_CODE_UNLOGIN) {
                            ImIn.loginByOneKeyLogin(context,true)
                            ToastUtil.toastShort(resp.msg)
                        } else if (resp.code == ImConstants.SILENCED_CODE) { //禁言
                            showSilencedDialog(context, resp.data.tips, resp.data.url)
                        } else {
                            ToastUtil.toastShort(resp.msg)
                        }
                    }
                }
                ) { throwable: Throwable ->
                    if (null != loadingDialog && loadingDialog?.isVisible!!) {
                        loadingDialog?.dismissAllowingStateLoss()
                    }
                    handleError(context, throwable)
                    if (throwable is HttpException) {
                        upLoadLog("consult/get-expert", throwable.code(), throwable.message!!)
                    }
                }
    }

    //====================私聊页面 初始化操作====================
    /**
     * 初始化在线状态接口
     *
     * 只有专家显示在线、离线标识，其他用户Type隐藏在线、离线标识
     */
    fun initChatOnlineState(
        tb: TitleBarBottom,
        context: Context,
        toUid: String,
        messageFragment: YDLMessageFragment
    ) {
        val actionHandler = ActionHandlerStorage.getL(toUid)
        //获取私聊对方在线状态
        if (null != actionHandler) {
            val docInfo = actionHandler.info
            docInfo.doctorBriefInfoFeedbackRate
            if (null != docInfo && (ImConstants.KEFUXIAOYI == docInfo.toUid || "4108805" == docInfo.toUid)) { //小壹客服  不显示是否在线
                tb.setmMinTitleVisiable(View.GONE)
            } else {
                //对方是用户，自己是助理
                if (actionHandler.userType == USER_TYPE_USER && ModularServiceManager.provide(IUserService::class.java)
                        .getUserInfo()?.user_type == USER_TYPE_ASSISTANT
                ) {
                    tb.setTitleTextRightIcon(R.drawable.user_info_icon) {
                        messageFragment.showUserInfoDialog()
                    }
                }
                if (actionHandler.userType == USER_TYPE_EXPERT) { // 专家
                    tb.setmMinTitleVisiable(View.VISIBLE)
                    // 调取接口获取专家状态
                    val dis = instance
                        .getDoctorChatStatus(actionHandler.info.toUid.toLong())
                        .compose(applySchedulers())
                        .subscribe(
                            { chatStatusBean: BaseAPIResponse<ChatStatusBean> ->
                                if (actionHandler != null) {
                                    val status = chatStatusBean.data.status
                                    actionHandler.setDoctorStatus(status)
                                    actionHandler.setDoctorBusyNum(chatStatusBean.data.busyTotal)
                                    //1.在线，2.离线，3.忙碌 4咨询中， 5倾述中  6咨询前准备
                                    if (status == 2) { //离线
                                        tb.setMinTitleText("离线")
                                        tb.setMinTitleColor(
                                            ContextCompat.getColor(
                                                context,
                                                R.color.platform_color_666666
                                            )
                                        )
                                        tb.setMinTitleDrawable(
                                            ContextCompat.getDrawable(
                                                context,
                                                R.drawable.im_background_chat_top_status_off_line
                                            )
                                        )
                                    } else if (status == 4 || status == 5) { //服务中
                                        tb.setMinTitleText("服务中")
                                        tb.setMinTitleColor(
                                            ContextCompat.getColor(
                                                context,
                                                R.color.platform_color_666666
                                            )
                                        )
                                        tb.setMinTitleDrawable(
                                            ContextCompat.getDrawable(
                                                context,
                                                R.drawable.im_background_chat_top_status_online_server
                                            )
                                        )
                                    } else { //在线  1，3，6..
                                        tb.setMinTitleText("在线")
                                        tb.setMinTitleColor(
                                            ContextCompat.getColor(
                                                context,
                                                R.color.platform_color_666666
                                            )
                                        )
                                        tb.setMinTitleDrawable(
                                            ContextCompat.getDrawable(
                                                context,
                                                R.drawable.im_background_chat_top_status_online
                                            )
                                        )
                                    }
                                    initSystemMessage(
                                        chatStatusBean.data.promptRule,
                                        status,
                                        toUid,
                                        actionHandler
                                    )
                                }
                            }
                        ) { throwable: Throwable ->
                            LogUtil.i("getDoctorChatStatus throwable:$throwable")
                        }
                } else if (actionHandler.userType == USER_TYPE_ASSISTANT) { // 助理
                    tb.setmMinTitleVisiable(View.GONE)
                    // 调取接口获取助理状态
                    instance.getAssistantChatStatus(
                        actionHandler.info.toUid.toLong()
                    )
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe({ res: BaseAPIResponse<Int> ->
                            if (actionHandler != null) {
                                if (res.data == 1) { //在线
                                    /*tb.setMinTitleText("在线")
                                    tb.setMinTitleColor(context.resources.getColor(R.color.platform_color_666666))
                                    tb.setMinTitleDrawable(context.resources.getDrawable(R.drawable.im_background_chat_top_status_online))*/
                                } else { //离线
                                    /* tb.setMinTitleText("离线")
                                     tb.setMinTitleColor(context.resources.getColor(R.color.platform_color_666666))
                                     tb.setMinTitleDrawable(context.resources.getDrawable(R.drawable.im_background_chat_top_status_off_line))*/
                                }
                            }
                        }
                        ) { throwable: Throwable? -> }
                } else {
                    tb.setmMinTitleVisiable(View.GONE)
                }
            }
        }
    }

    // promptRule 判断是否推荐专家  4，5直接不走文本提示和推荐逻辑，1，3不走推荐逻辑
    //初始化 根据专家在线状态来发送提示消息或者推荐消息
    private fun initSystemMessage(
        promptRule: Int,
        status: Int,
        toUid: String,
        actionHandler: IP2PCustomActionHandler
    ) {
        if (!(promptRule == 4 || promptRule == 5)) {
            val showExpertList = !(promptRule == 1 || promptRule == 3)
            if (actionHandler.userType == USER_TYPE_EXPERT && status == 2) { //当该专家离线时
                sendRecommendExpertListMessage(1, showExpertList, toUid, actionHandler)
            } else if (actionHandler.userType == USER_TYPE_EXPERT&& status >= 3) { //当该专家忙碌时
                sendRecommendExpertListMessage(2, showExpertList, toUid, actionHandler)
            }
        }
    }

    /**
     * 发送推荐专家列表
     */
    @SuppressLint("CheckResult")
    fun sendRecommendExpertListMessage(
        type: Int,
        showExpertList: Boolean,
        toUid: String,
        actionHandler: IP2PCustomActionHandler
    ) { // 调取接口获取推荐专家列表
        instance.getRecommendExpertList(
            actionHandler.info.toUid.toLong(),
            URLEncoder.encode(actionHandler.info.tag1),
            3
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ res: BaseAPIResponse<ArrayList<RecommendExpertBean>> ->
                //发送推荐专家列表消息
                actionHandler.sendRecommendExpertListMessage(toUid, res.data, type, showExpertList)
            }, { throwable: Throwable -> ToastUtil.toastShort(throwable.toString()) })
    }

    //====================展示提示====================
    fun showSilencedDialog(context: Context, tips: String?, url: String?) {
        CommonDialog.create(context)
            .setMessage(tips)
            .setCancelAble(false)
            .setLeftOnclick(
                context.getString(R.string.im_details)
            ) {
                val realUrl = if (TextUtils.isEmpty(url)) ImConstants.HELP_URL else url!!
                val params = H5Params(realUrl, "")
                NewH5Activity.start(context, params)
            }
            .setRightClick(context.getString(R.string.im_approval), null)
            .show()
    }
}