package com.yidianling.im.modular.service

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.annotation.Route
import com.netease.nimlib.sdk.NIMClient
import com.netease.nimlib.sdk.RequestCallback
import com.netease.nimlib.sdk.auth.AuthService
import com.netease.nimlib.sdk.auth.LoginInfo
import com.netease.nimlib.sdk.msg.MessageBuilder
import com.netease.nimlib.sdk.msg.MsgService
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum
import com.netease.nimlib.sdk.msg.model.CustomNotification
import com.netease.nimlib.sdk.msg.model.CustomNotificationConfig
import com.tencent.mmkv.MMKV
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.router.YdlCommonOut
import com.ydl.ydlcommon.utils.StringUtils
import com.ydl.ydlcommon.utils.remind.HttpErrorUtils
import com.yidianling.avchatkit.common.util.NetworkUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.R
import com.yidianling.im.api.bean.*
import com.yidianling.im.api.listener.ApiStringResponseCallback
import com.yidianling.im.api.service.IImService
import com.yidianling.im.bridge.P2PCustomActionHandlerImpl
import com.yidianling.im.config.NimApplication
import com.yidianling.im.config.constants.ImConstants
import com.yidianling.im.helper.IMChatUtil
import com.yidianling.im.helper.ImObserversHelper
import com.yidianling.im.helper.LogoutHelper
import com.yidianling.im.helper.MsgReceiveHelper
import com.yidianling.im.http.ImRetrofitApi
import com.yidianling.im.preference.IMCache
import com.yidianling.im.router.ImIn
import com.yidianling.im.session.SessionHelper
import com.yidianling.im.session.extension.CustomAttachModifyTime
import com.yidianling.im.session.extension.CustomAttachSubScriptTime
import com.yidianling.im.session.extension.CustomAttachmentTest
import com.yidianling.im.ui.page.NewMultiMessageFragment
import com.yidianling.nimbase.common.media.picker.PickImageHelper
import com.yidianling.uikit.api.NimUIKit
import com.yidianling.uikit.business.session.helper.MessageListPanelHelper
import com.yidianling.uikit.custom.widget.expertConsultService.view.ExpertConsultServiceListDialog2
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers

/**
 * Created by haorui on 2019-12-11 .
 * Des:
 */
@Route(path = "/im/ImService")
class IMServiceImpl : IImService {

    private var expertConsultServiceListDialog2: ExpertConsultServiceListDialog2 ?= null

    override fun isHasUnread(): Boolean {
        return MsgReceiveHelper.isHasUnread
    }

    override fun init(context: Context?) {

    }

    override fun startP2PSession(context: Activity, toUid: String) {

        IMChatUtil.startCms(context as AppCompatActivity, toUid, 0)
    }

    override fun startP2PSession(context: Activity, location: Int, ffrom2: String?) {
        IMChatUtil.startCms(context,location,ffrom2)
    }
    override fun startChatBySessionId(context: Activity, toUid: String) {
        IMChatUtil.startChatBySessionId(context as AppCompatActivity,toUid)
    }

    override fun startP2PXiaoYi(context: Context) {
        if (!ImIn.loginByOneKeyLogin(context,true)) {
            return
        }
        SessionHelper.startP2PSession(context, -1, ImConstants.KEFUXIAOYI, null, P2PCustomActionHandlerImpl("14", "客服小壹", "https://static.ydlcdn.com/mobile/images/avatar_girl_app.png"))
    }

    override fun imLogin(info: IMLoginInfo) {
        NimUIKit.setAccount(info.account)
        try {
            NIMClient.getService(AuthService::class.java).login(LoginInfo(info.account, info.passWord))
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun login(info: IMLoginInfo, callback: IMRequestCallback<IMLoginInfo>?) {
        NimUIKit.login(LoginInfo(info.account, info.passWord), object : RequestCallback<LoginInfo> {
            override fun onSuccess(param: LoginInfo?) {
                if (param != null) {
                    val newParam = IMLoginInfo(param.account, param.token)
                    callback?.onSuccess(newParam)
                }
            }

            override fun onFailed(code: Int) {
                callback?.onFailed(code)
            }

            override fun onException(exception: Throwable?) {
                callback?.onException(exception)
            }
        })
    }

    override fun setAccount(account: String) {
        NimUIKit.setAccount(account)
    }

    override fun setChattingAccountAll() {
        NIMClient.getService(MsgService::class.java).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_ALL, SessionTypeEnum.None)
    }

    override fun setChattingAccountNone() {
        NIMClient.getService(MsgService::class.java).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE, SessionTypeEnum.None)
    }

    override fun logout() {
        NIMClient.getService(AuthService::class.java).logout()
    }

    override fun clear() {
        NimUIKit.logout()
        IMCache.clear()
    }

    override fun createTextMessage(sessionId: String?, content: String, callback: IMRequestCallback<Void>) {
        val message = MessageBuilder.createTextMessage(sessionId, SessionTypeEnum.P2P, content)
        NIMClient.getService(MsgService::class.java).sendMessage(message, false).setCallback(object : RequestCallback<Void> {
            override fun onSuccess(param: Void?) {
                callback.onSuccess(param)
                MessageListPanelHelper.getInstance().notifyAddMessage(message)
            }

            override fun onException(exception: Throwable?) {
                callback.onException(exception)
            }

            override fun onFailed(code: Int) {
                callback.onFailed(code)
            }
        })
    }

    override fun sendSubscriptionTimeMessage(sessionId: String?, content: String, callback: IMRequestCallback<Void>) {
        val customTime = CustomAttachSubScriptTime(content)
        val message = MessageBuilder.createCustomMessage(sessionId, SessionTypeEnum.P2P, content, customTime)
        NIMClient.getService(MsgService::class.java).sendMessage(message, false).setCallback(object : RequestCallback<Void> {
            override fun onSuccess(param: Void?) {
                callback.onSuccess(param)
                MessageListPanelHelper.getInstance().notifyAddMessage(message)
            }

            override fun onException(exception: Throwable?) {
                callback.onException(exception)
            }

            override fun onFailed(code: Int) {
                callback.onFailed(code)
            }
        })

    }

    override fun showSelector(activity: Activity, requestCode: Int) {
        val option = PickImageHelper.PickImageOption()
        option.titleResId = R.string.im_input_panel_photo
        option.multiSelect = true
        option.multiSelectMaxCount = 9
        option.crop = false
        option.cropOutputImageWidth = 720
        option.cropOutputImageHeight = 720
        //        option.outputPath = StorageUtil.getWritePath(StringUtils.get32UUID() + ".jpg", StorageType.TYPE_TEMP)
        option.outputPath = YdlCommonOut.getApp().externalCacheDir.absolutePath + "/" + StringUtils.get32UUID() + ".jpg"
        PickImageHelper.pickImage(activity, requestCode, option)
    }

    override fun sendTestResultMessage(uid: String, content: String, title: String?, head: String?, url: String?, id: Int, share_url: String?, callback: IMRequestCallback<Void>) {
        val customAttachmentTest = CustomAttachmentTest(CustomAttachmentTest.FLAG_RESULT, title, head, url, id, share_url)
        val message = MessageBuilder.createCustomMessage(uid, SessionTypeEnum.P2P, "测试结果", customAttachmentTest)

        NIMClient.getService(MsgService::class.java).sendMessage(message, false).setCallback(object : RequestCallback<Void> {
            override fun onSuccess(param: Void?) {
                callback.onSuccess(param)
                MessageListPanelHelper.getInstance().notifyAddMessage(message)
            }

            override fun onFailed(code: Int) {
                callback.onFailed(code)
            }

            override fun onException(exception: Throwable?) {
                callback.onException(exception)
            }
        })

    }

    /**
     * 跳转私聊界面
     */
    override fun startChat(context: Activity, toUid: String, flag: Int, canTalk: Int) {
        //这里虽然是倾述流程进入私聊，但不需要发送自定义消息
        IMChatUtil.startChat(context as AppCompatActivity, toUid,0)
    }

    override fun startChat(context: Activity, toUid: String, flag: Int, canTalk: Int, isFramQingsu: Int, isFromMessageList: Boolean) {
        //这里虽然是倾述流程进入私聊，但不需要发送自定义消息
        IMChatUtil.startChat(context as AppCompatActivity, toUid,isFramQingsu)
    }

    override fun startChatCloseReplaceChat(context: Activity, toUid: String) {
        IMChatUtil.startChatCloseReplaceChat(context as AppCompatActivity,toUid)
    }

    override fun getUnReadByUid(uid: String): Int {
        return MsgReceiveHelper.getUnNum(uid)
    }

    override fun getAllUnReadNum(): Int {
        return MsgReceiveHelper.getAllUnNum()
    }

    /**
     * 发送自定义通知: 不推送、不计入未读消息
     */
    override fun sendCustomNotification(toUid: String, content: String, callback: IMSendCustomNotificationResultCallBack) {
        val config = CustomNotificationConfig()
        config.enablePush = false
        config.enablePushNick = false
        config.enableUnreadCount = false
        val customNotification = CustomNotification()
        customNotification.sessionType = SessionTypeEnum.P2P
        customNotification.sessionId = toUid
        customNotification.config = config
        customNotification.content = content
        customNotification.isSendToOnlineUserOnly = true
        NIMClient.getService(MsgService::class.java).sendCustomNotification(customNotification).setCallback(object : RequestCallback<Void?> {
            override fun onSuccess(param: Void?) {
                callback.onSuccess()
            }

            override fun onFailed(code: Int) {
                callback.onFailed(code)
            }

            override fun onException(exception: Throwable) {
                callback.onException(exception)
            }
        })
    }

    override fun registerObserveCustomNotification(callback: IMRegisterObserverCustomNotificationCallBack) {
        ImObserversHelper.getInstance().imCustomNotificationCallBack.add(callback)
    }

    override fun unregisterObserveCustomNotification(callback: IMRegisterObserverCustomNotificationCallBack) {
        ImObserversHelper.getInstance().imCustomNotificationCallBack.remove(callback)
    }

    override fun getMultiMessageFragment(): Fragment {
        return NewMultiMessageFragment()
    }

    override fun nextUnreadItem(fragment: Fragment): Boolean {
        if (fragment is NewMultiMessageFragment) {
            fragment.nextUnReadItem()
            return true
        }
        return false
    }

    override fun isChatFragment(fragment: Fragment): Boolean {
        if (fragment is NewMultiMessageFragment) {
            return true
        }
        return false
    }

    override fun isImLogin(): Boolean {
        return ImIn.isLogin()
    }

    override fun requestTopUnReadNumber(fragment: Fragment) {
        if (fragment is NewMultiMessageFragment) {
            fragment.requestTopUnReadNumber()
        }
    }

    override fun loginIm(uid: String?, hxPwd: String?) {
        ImIn.loginIm(uid?:"", hxPwd?:"")
    }

    override fun logoutAll() {
        LogoutHelper.logout()
    }

    override fun initImCache(mContext: Context) {
        IMCache.setContext(mContext)
    }

    override fun startKefuChat(context: Context, toUid: String, flag: Int, canTalk: Int) {
        IMChatUtil.startKefuChat(context as AppCompatActivity)
    }

    override fun startP2PSession(mContext: Context, userType: Int, account: String, toChatUsername: String, toName: String, head: String) {
        SessionHelper.startP2PSession(mContext, userType, account, null,
            P2PCustomActionHandlerImpl(toChatUsername, toName, head))
    }

    override fun updateUserHead(head: String?) {
        ImIn.updateUserHead(head?:"")
    }

    override fun updateUserName(name: String?) {
        ImIn.updateUserName(name?:"")
    }

    override fun imInSetRing(bool: Boolean) {
        ImIn.setRing(bool)
    }

    override fun imInSetVibrate(bool: Boolean) {
        ImIn.setVibrate(bool)
    }

    override fun getUserInfoDescription(): String? {
        return ImIn.getUserInfo()!!.description
    }

    override fun getEarModeCloseType(): String {
        return NimApplication.EAR_MODE_CLOSE
    }

    override fun getEarModeKey(): String {
        return NimApplication.EAR_MODE_KEY
    }

    override fun getEarModeOpenType(): String {
        return NimApplication.EAR_MODE_OPEN
    }

    override fun getEarModeIsOpen(): Boolean {
        return ImIn.getEarModeIsOpen()
    }

    override fun updateEarMode(bool: Boolean) {
        ImIn.updateEarMode(bool)
    }

    @SuppressLint("CheckResult")
    override fun getChatUid(context: Context?, uid: String, callback: ApiStringResponseCallback) {
        ImRetrofitApi.getImJavaApi().getChatUid(uid)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ resp ->
                callback.onUidCallback(resp.data.getChatUid())

            }, { t ->
                context?.let {
                    HttpErrorUtils.handleError(context, t)
                }
            })
    }

    override fun chatScheule(context: Activity, userUrl: String, docUrl: String, dsmId: Int, title: String, toUid: Int) {
        val customAttachModifyTime = CustomAttachModifyTime(
            userUrl,
            docUrl,
            dsmId,
            title
        )

        val message = MessageBuilder.createCustomMessage(
            toUid.toString(),
            SessionTypeEnum.P2P,
            customAttachModifyTime
        )

        NIMClient.getService(MsgService::class.java).sendMessage(message, false)
            .setCallback(object : RequestCallback<Void?> {
                override fun onSuccess(param: Void?) {
                    MessageListPanelHelper.getInstance().notifyAddMessage(message)
                    startChat(context, toUid.toString(), 0x001, 0)
                }

                override fun onFailed(code: Int) {
                    ToastUtil.toastShort("加载失败")
                }

                override fun onException(exception: Throwable) {
                    ToastUtil.toastShort("加载失败")
                }
            })

    }

    override fun initIm(
        app: Application,
        activity: Class<out Activity>,
        imInitBean: IMInitConfigBean
    ) {
        NimApplication.getInstance().initIm(app, activity, imInitBean)
    }

    override fun isWifiOr3G(activity: Activity): Boolean {
        return NetworkUtil.isWifiOr3G(activity)
    }

    override fun showConsultServiceDialog(activity: Activity, toUid: String, doctorId: String) {

        // 获取专家是否在繁忙状态
        if (activity != null) {
            expertConsultServiceListDialog2 =
                ExpertConsultServiceListDialog2(
                    activity, null, false, toUid,
                    doctorId
                )
            expertConsultServiceListDialog2?.show()
        }
    }

    override fun dismissConsultServiceDialog() {
        expertConsultServiceListDialog2?.changeItem()
    }

    override fun startTeamSession(activity: Activity, tid: String, doctorId: String) {
        SessionHelper.startTeamSession(
            activity,
            tid + "",
            null,
            P2PCustomActionHandlerImpl(doctorId + "")
        )
    }

    @SuppressLint("CheckResult")
    override fun getSystemConfig(key: String) {
        ImRetrofitApi.getImRetrofitApi()
            .getSystemConfigByKeyword(key)
            .compose(RxUtils.resultJavaData())
            .subscribeOn(Schedulers.io())
            .subscribe {
                MMKV.defaultMMKV().putString(key, it.value1)
            }
    }
}