package com.yidianling.medical.im

import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.WindowManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.jcodecraeer.xrecyclerview.CustomFooterViewCallBack
import com.jcodecraeer.xrecyclerview.XRecyclerView
import com.ydl.ydlcommon.base.BaseFragment
import com.ydl.ydlcommon.data.http.RxUtils
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.R
import com.yidianling.im.api.event.ImLogoutEvent
import com.yidianling.im.api.event.UpdateBottomBarUnreadNumEvent
import com.yidianling.im.event.ReQureyUnreadNum
import com.yidianling.im.event.UpdateTabUnreadNumEvent
import com.yidianling.im.helper.MsgReceiveHelper
import com.yidianling.im.http.ImHttpImpl
import com.yidianling.im.router.ImIn
import com.yidianling.im.ui.page.dialog.MessageChatSettingDialog
import com.yidianling.im.ui.page.fragment.bean.ChatItemBean
import com.yidianling.im.ui.page.fragment.bean.ChatModelBean
import com.yidianling.im.ui.page.fragment.bean.UnreadMessageBean
import com.yidianling.im.ui.page.fragment.view.ChatFooterItemView
import com.yidianling.im.ui.page.widget.ChatUnusualView
import com.yidianling.im.ui.param.ChatParam
import com.yidianling.im.ui.param.ClearMessageParam
import com.yidianling.im.ui.param.UnreadParam
import com.yidianling.medical.im.adapter.MedicalChatAdapter
import com.yidianling.medical.popwindow.MedicalChatSettingPopupWindow
import de.greenrobot.event.EventBus
import kotlinx.android.synthetic.main.medical_im_chat_fragment_layout.*

/**
 * 私聊消息列表页面
 * Created by xj on 2019/9/20.
 */
@Route(path = "/im/medicalim")
class MeidicalChatFragment : BaseFragment(), XRecyclerView.LoadingListener {

    private lateinit var mContext: Context
    private var chatAdapter: MedicalChatAdapter? = null
    private var allChatData: ChatModelBean = ChatModelBean() //全部数据
    private var showData: ArrayList<ChatItemBean> = ArrayList() // 最终展示的数据
    private var chatSettingPopupWindow: MedicalChatSettingPopupWindow? = null  //右上角弹框
    private var messageChatSettingtDialog: MessageChatSettingDialog? = null //全部已读弹框

    private var threeWeekItem: ChatItemBean =
        ChatItemBean(0, 0, "", 0, 0, "", 0, 0, 0, 0, 0, "", 0, "", "", 0, 0, 0, "", 1, "", true)


    private val mCompare: Comparator<ChatItemBean> = Comparator { o1, o2 ->
        val res = o1.timestamp.compareTo(o2.timestamp)
        when {
            res == 0 -> 0
            res > 0 -> -1
            else -> 1
        }
    }

    override fun layoutResId(): Int {
        return R.layout.medical_im_chat_fragment_layout
    }

    override fun initDataAndEvent() {
        mContext = requireContext()
        EventBus.getDefault().register(this)

        setShowData()
        resetPageShow()
        initListData()

        ll_more.setOnClickListener {
            if (!ImIn.isLogin()) {
                ToastUtil.toastShort("请登录后再试")
            } else {
                chatSettingPopupWindow = MedicalChatSettingPopupWindow(mContext,
                    object : MedicalChatSettingPopupWindow.OnChatSettingClickListener {
                        override fun onAllReadClick() {
                            messageChatSettingtDialog = MessageChatSettingDialog(
                                mContext,
                                object : MessageChatSettingDialog.OnMessageChatSettingDialog {
                                    override fun onSure() {
                                        markAllMessageRead()
                                        messageChatSettingtDialog?.dismiss()
                                    }

                                    override fun onCancel() {
                                        messageChatSettingtDialog?.dismiss()
                                    }
                                })
                            messageChatSettingtDialog?.show()
                        }

                        override fun onChatSettingClick() {
                            ARouter.getInstance().build("/user/notifysetting").navigation()
                        }

                        override fun onDismissAction() {
                            setWindowBg(1f)
                        }
                    })


                chatSettingPopupWindow?.contentView?.measure(
                    View.MeasureSpec.UNSPECIFIED,
                    View.MeasureSpec.UNSPECIFIED
                )

                //这句代码必须要才能获得正确的popupwindow的宽度
                val popupWindowWidth = chatSettingPopupWindow?.contentView!!.measuredWidth
                setWindowBg(0.4f)
                chatSettingPopupWindow?.showAsDropDown(
                    ll_more,
                    -(popupWindowWidth - ll_more.measuredWidth + 20),
                    0
                )
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
    }

    override fun initDataAndEventLazy() {
    }

    @SuppressLint("CheckResult")
    fun getChatMessageData() {
        if (ImIn.getUserInfo()?.uid != "0") {
            ImHttpImpl.getInstance()
                .getAllChatMessage(ChatParam("${ImIn.getUserInfo()?.uid}", "${0}"))
                .compose(RxUtils.applySchedulers(this))
                .compose<ChatModelBean>(RxUtils.resultJavaData())
                .subscribe({
                    if (it.before.data.size != 0 || it.nomal.data.size != 0) {
                        setData(it)
                    }
                    chat_recyclerview?.let {
                        chat_recyclerview.refreshComplete()
                    }
                }, { t ->
                    t.printStackTrace()
                    ToastUtil.toastShort("您的网络出现了问题")
                    chat_recyclerview?.let {
                        chat_recyclerview.refreshComplete()
                    }
                })
        }

    }


    override fun onLoadMore() {
        chat_recyclerview.setNoMore(true)
    }

    override fun onRefresh() {
        requestTopUnReadNumber()

        getChatMessageData()
    }

    /**
     * 设置全部数据
     */
    fun setData(data: ChatModelBean) {
        allChatData = data

        setShowData()
    }

    /**
     * 设置最终显示得数据，（优先置顶，再最近数据，再三周前的消息item，再三周前，其余按照时间排序）
     */
    private fun setShowData() {
        showData.clear()
        chatAdapter?.notifyDataSetChanged()
        selectTopData()
        // 全部
        val item = ChatItemBean(
            type = 1,
            title = "暂无新消息",
            timeStr = "",
            unReadNum = 0
        )
        showData.add(item)
        showData.addAll(allChatData.topData.data.sortedWith(mCompare))

        showData.addAll(allChatData.nomal.data.filter { it.is_top == 0 }.sortedWith(mCompare))

        if (allChatData.before.data.any { it.is_top == 0 }) {
            showData.add(threeWeekItem)
            showData.addAll(allChatData.before.data.filter { it.is_top == 0 }.sortedWith(mCompare))
        }
        systemUnReadCount()


        // 重置消息未读数
        MsgReceiveHelper.reQueryUnreadNumber {
            showData.forEachIndexed { index, _ ->
                showData[index].unReadNum =
                    MsgReceiveHelper.getUnNum(showData[index].toUid.toString())
            }
            chatAdapter?.notifyDataSetChanged()
            resetPageShow()
        }
    }

    /**
     * 将before数据和nomal数据里面的置顶数据筛选出来放入topData里面
     */
    private fun selectTopData() {
        allChatData.topData.data.clear()
        allChatData.topData.data.addAll(allChatData.before.data.filter { it.is_top == 1 })
        allChatData.topData.data.addAll(allChatData.nomal.data.filter { it.is_top == 1 })
    }

    private fun initListData() {

        chatAdapter = MedicalChatAdapter(mContext, showData, this)
        chatAdapter?.setlistener(object : MedicalChatAdapter.ChatRecyclerViewCallback {
            override fun onRefresh() {
                getChatMessageData()
            }
        })
        chat_recyclerview.layoutManager = LinearLayoutManager(context)
        chat_recyclerview.adapter = chatAdapter
        chat_recyclerview.setLoadingListener(this)
        chat_recyclerview.setFootView(
            ChatFooterItemView(mContext),
            object : CustomFooterViewCallBack {
                override fun onSetNoMore(p0: View?, p1: Boolean) {
                }

                override fun onLoadingMore(p0: View?) {
                }

                override fun onLoadMoreComplete(p0: View?) {
                }
            })
        getChatMessageData()
    }

    override fun onResume() {
        super.onResume()
        resetPageShow()
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isVisibleToUser && getIsViewCreated()) {
            systemUnReadCount()
            resetPageShow()
        }
    }

    /**
     * 获取系统消息
     * */
    @SuppressLint("CheckResult")
    private fun systemUnReadCount() {
        ImHttpImpl.getInstance().systemUnReadCount()
            .compose(RxUtils.applySchedulers(this))
            .compose(RxUtils.resultJavaData())
            .subscribe({ bean ->
                if (showData.size > 0 && showData[0].type == 1) {
                    showData[0].title = bean.title
                    showData[0].timeStr = bean.createTime
                    showData[0].unReadNum = bean.unReadTotalCount
                }
                chatAdapter?.notifyDataSetChanged()
            }, { t ->
                t.printStackTrace()
            })
        ImHttpImpl.getInstance().systemReadAll()
            .compose(RxUtils.applySchedulers(this))
            .compose(RxUtils.resultJavaData())
            .subscribe {
                systemUnReadCount()
            }
    }

    fun clearData() {
        showData.clear()
        chatAdapter?.notifyDataSetChanged()
        resetPageShow()
    }

    /**
     * 页面展示状态逻辑
     */
    private fun resetPageShow() {
        ll_chat_unusual_view?.let {
            if (ImIn.isLogin()) {
                //登录状态
                if (showData.size != 0) {
                    //数据不为空
                    chat_recyclerview.visibility = View.VISIBLE
                    ll_chat_unusual_view.visibility = View.GONE
                } else {
                    chat_recyclerview.visibility = View.GONE
                    ll_chat_unusual_view.visibility = View.VISIBLE
                    ll_chat_unusual_view.setUnusualType(ChatUnusualView.TYPE_CHAT_ALL_NO_DATA)

                    ll_chat_unusual_view.setListener(object : ChatUnusualView.ChatUnusualListener {
                        override fun onButtonClick() {
                            startActivity(
                                ImIn.getConsultService()
                                    .expertSearchIntent(activity!!, "0", 0, false)
                            )
                        }
                    })
                }
            } else {
                //未登录状态
                chat_recyclerview.visibility = View.GONE
                ll_chat_unusual_view.visibility = View.VISIBLE
                ll_chat_unusual_view.setUnusualType(ChatUnusualView.TYPE_UNLOGIN)
                ll_chat_unusual_view.setListener(object : ChatUnusualView.ChatUnusualListener {
                    override fun onButtonClick() {
                        ImIn.loginByOneKeyLogin(mContext, true)
                    }
                })
            }
        }
    }

    /**
     * 全部已读（私聊是单独处理的）
     */
    @SuppressLint("CheckResult")
    fun markAllMessageRead() {
        ImHttpImpl.getInstance().clearMessage(ClearMessageParam("${ImIn.getUserInfo()?.uid}", "1"))
            .compose(RxUtils.applySchedulers(this))
            .subscribe({
                if (it.data) {
                    //清除私聊群聊未读数
                    MsgReceiveHelper.markAllRead()
                    getMsgData()
                    ToastUtil.toastShort("已全部标记为已读")
                } else {
                    ToastUtil.toastShort("标记失败")
                }
            }, { t ->
                t.printStackTrace()
                ToastUtil.toastShort("您的网络出现了问题")
            })

    }

    /**
     * 刷新当前展示的消息列表的数据，刷新顶部三个消息未读数，刷新底部消息未读数
     */
    private fun getMsgData() {
        /**
         * 登录状态
         */
        if (ImIn.isLogin()) {
            getChatMessageData()
        }
        requestTopUnReadNumber()
    }

    /**
     * 刷新顶部未读数量（接口返回成功后调用的方法中会触发事件刷新底部导航栏的角标）
     */
    @SuppressLint("CheckResult")
    fun requestTopUnReadNumber() {
        if (ImIn.getUserInfo()?.uid != "0") {
            ImHttpImpl.getInstance().getUnreadMessage(UnreadParam("${ImIn.getUserInfo()?.uid}"))
                .compose<UnreadMessageBean>(RxUtils.resultJavaData())
                .compose(RxUtils.applySchedulers(this))
                .subscribe({
                    resetTopUnReadNumber()
                }, { t ->
                    t.printStackTrace()
                    ToastUtil.toastShort("您的网络出现了问题")
                })
        } else {
            //退出登录情况下，全部不显示
            EventBus.getDefault().post(UpdateBottomBarUnreadNumEvent(0))
        }
    }

    /**
     * 重置顶部未读数量
     */
    private fun resetTopUnReadNumber() {
        val chatUnreadNum = ImIn.getInUnreadNum()//私聊未读数移动端自己读取云信

        MsgReceiveHelper.isHasUnread = chatUnreadNum > 0
        // 同步底部导航栏的角标数量
        EventBus.getDefault().post(
            UpdateBottomBarUnreadNumEvent(chatUnreadNum)
        )
    }

    private fun onEvent(event: ReQureyUnreadNum) {
        getMsgData()
    }

    /**
     * 私聊未读数变化触发的事件，不进行互动和通知未读数的更新
     */
    fun onEvent(event: UpdateTabUnreadNumEvent) {
        try {
            val chatUnreadNum = ImIn.getInUnreadNum() //私聊未读数移动端自己读取云信

            // 刷新私聊列表
            getChatMessageData()
            // 同步底部导航栏的角标数量
            EventBus.getDefault().post(UpdateBottomBarUnreadNumEvent(chatUnreadNum))
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    /**
     * 云信登出
     */
    fun onEvent(event: ImLogoutEvent) {
        clearData()
    }

    /**
     * 设置页面背景色
     */
    private fun setWindowBg(alpha: Float) {
        val lp = activity?.window!!.attributes
        lp.alpha = alpha
        activity?.window!!.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
        activity?.window!!.attributes = lp
    }
}