package com.bc_chat.im.activity

import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import android.text.SpannableStringBuilder
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.LinearLayout
import com.alibaba.android.arouter.launcher.ARouter
import com.bc_chat.bc_base.config.RouteConfig
import com.bc_chat.bc_base.contract.ChatContract
import com.bc_chat.bc_base.entity.ListModel
import com.bc_chat.bc_base.entity.User
import com.bc_chat.bc_base.entity.group.Group
import com.bc_chat.bc_base.entity.group.MemberBean
import com.bc_chat.bc_base.presenter.ChatPresenter
import com.bc_chat.bc_base.utils.Const
import com.bc_chat.bc_base.utils.gone
import com.bc_chat.bc_base.utils.visible
import com.bc_chat.im.R
import com.bc_chat.im.adapter.UserImageAdapter
import com.bc_chat.im.databinding.ActivityChatBinding
import com.bc_chat.im.fragment.ConversationFragmentEx
import com.bc_chat.im.fragment.GroupNoticeFragment
import com.bc_chat.im.fragment.TopConversationFragmentEx
import com.bc_chat.im.messages.vibration.RCVibrationMessage
import com.zhaohaoting.framework.abs.BaseActivity
import com.zhaohaoting.framework.utils.DensityUtil
import com.zhaohaoting.framework.utils.Preferences
import com.zhaohaoting.framework.utils.observer.Observer
import com.zhaohaoting.framework.utils.observer.ObserverManager
import io.rong.contactcard.message.ContactMessage
import io.rong.eventbus.EventBus
import io.rong.imkit.RongIM
import io.rong.imkit.emoticon.AndroidEmoji
import io.rong.imkit.model.Event
import io.rong.imlib.RongCommonDefine
import io.rong.imlib.RongIMClient
import io.rong.imlib.model.Conversation
import io.rong.imlib.model.Message
import io.rong.message.*
import org.jetbrains.anko.bundleOf
import java.util.*

/**
 * author：Created by zhaohaoting on 2019/2/27
 * email：526309416@qq.com
 * desc：聊天页面
 */
class ChatActivity : BaseActivity<ChatPresenter>(), ChatContract.View, Observer<String> {


    /**  跳转方式
     *   Uri uri = Uri.parse("rong://" + context.getApplicationInfo().processName)
     *   .buildUpon().appendPath("conversation")
     *   .appendPath(conversationType.getName().toLowerCase(Locale.US))
     *   .appendQueryParameter("targetId", targetId)
     *   .appendQueryParameter("title", title).build();
     *    context.startActivity(new Intent("android.intent.action.VIEW", uri));
     */
    private val mTargetId by lazy {
        intent.data?.getQueryParameter("targetId")
    }
    private val mTitle by lazy {
        intent.data?.getQueryParameter("title")
    }
    private val mConversationType: Conversation.ConversationType by lazy {
        Conversation.ConversationType.valueOf(intent.data?.lastPathSegment!!.toUpperCase(Locale.US))
    }

    private val binding: ActivityChatBinding by lazy {
        rootDataBinding as ActivityChatBinding
    }
    private var usersAdapter: UserImageAdapter? = null

    private var memberLord: MemberBean? = null

    private var groupInfo: Group? = null

    override fun initPresenter(): ChatPresenter = ChatPresenter(this)

    private val handler: Handler = Handler(Looper.getMainLooper())

    override fun getLayoutResId(): Int = R.layout.activity_chat

    private var topFragment: TopConversationFragmentEx? = null
    private var noticeFragment: GroupNoticeFragment? = null
    private var fragment: ConversationFragmentEx? = null


    override fun initialize() {
        title = mTitle
        isTouchHide = false
        topFragment = TopConversationFragmentEx()
        noticeFragment = GroupNoticeFragment()
        fragment = ConversationFragmentEx()
        val uri = Uri.parse("rong://" + applicationInfo.packageName).buildUpon()
                .appendPath("conversation").appendPath(mConversationType.getName().toLowerCase())
                .appendQueryParameter("targetId", mTargetId)
                .appendQueryParameter("title", mTitle)
                .build()
        fragment?.uri = uri
        if (mConversationType == Conversation.ConversationType.GROUP) {
            presenter.groupinfoTask(mTargetId!!)
            presenter.queryGroupMember(mTargetId!!, true)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.DISSOLUTION_GROUP, this)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.REFRESH_GROUP_INFO, this)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.EXIT_GROUP, this)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.REFRESH_GROUP_MEMBER, this)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.GROUP_KICKING, this)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.GROUP_NOTICE_REFRESH, this)
            EventBus.getDefault().register(this)
//            initUserList()
            initTopEvent()
            addFragment(fragment, R.id.fl_container)
            addTopFragment()
            getLaseMessage()
        } else if (mConversationType == Conversation.ConversationType.PRIVATE) {
            binding.llUserList.gone()
            addFragment(fragment, R.id.fl_container)
            presenter.userInfoTask(mTargetId!!)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.DELETE_FRIEND_LIST, this)
            ObserverManager.getInstance().registerObserver(Const.ObserverKey.UPDATE_FRIEND_INFO, this)
        } else {
            addFragment(fragment, R.id.fl_container)
            binding.llUserList.gone()
        }
        ObserverManager.getInstance().registerObserver(Const.ObserverKey.FORWARD_MESSAGE, this)
    }

    /**
     * 置顶消息
     */
    private fun initTopEvent() {
        binding.ivRetract.setOnClickListener {
            startAnimation(binding.topNoticeContainer, 300, 0f, -DensityUtil.dip2px(this, 200F - 36F).toFloat())
        }
        binding.tvLastMsg.setOnClickListener {
            startAnimation(binding.topNoticeContainer, 300, -DensityUtil.dip2px(this, 200F - 36F).toFloat(), 0f)
        }
    }

    /**
     * 群成员列表
     */
    private fun initUserList() {
        binding.userList.setHasFixedSize(true)
        binding.userList.itemAnimator = DefaultItemAnimator()
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
        binding.userList.layoutManager = layoutManager
        usersAdapter = UserImageAdapter(this)
        binding.userList.adapter = usersAdapter
    }

    override fun showLoading(vararg task: Any?) {
    }

    override fun queryGroupMemberSuccess(memberModel: ListModel<MemberBean>) {
        title = "$mTitle(${memberModel.list.size})"
        getMemberByLord(memberModel)
//        addFragment(fragment, R.id.fl_container)
        addTopFragment()
        getLaseMessage()
    }

    override fun queryGroupMemberFailure(exception: Exception) {
    }

    override fun groupinfoSuccess(groupInfo: Group) {
        this.groupInfo = groupInfo
        if ("1".equals(groupInfo.is_top)) {
            //群主消息置顶开启
            binding.topLayout.visible()
            addTopFragment()
        } else {
            //群主消息置顶关闭
            binding.topLayout.gone()
        }
        //群公告
        if (!groupInfo.notice.isNullOrEmpty()) {
            showGroupNotice(groupInfo.notice!!);
        }
    }

    fun showGroupNotice(notice: String) {
        binding.llGroupNotice.visible()
        binding.tvGroupNotice.setText(notice)
        binding.tvGroupNotice.isSelected = true
    }

    override fun groupinfoFailure(exception: Exception) {
    }

    override fun userInfoSuccess(user: User?) {
        title = user?.remark
    }

    override fun userInfoFailure(exception: Exception) {
    }

    /**
     * 添加置顶消息
     */
    private fun addTopFragment() {
        if (memberLord == null || groupInfo == null || !"1".equals(groupInfo?.is_top) || topFragment?.isAdded!!) return
        synchronized(ChatActivity::class.java) {
            val uri = Uri.parse("rong://" + applicationInfo.packageName).buildUpon()
                    .appendPath("conversation").appendPath(mConversationType.getName().toLowerCase())
                    .appendQueryParameter("targetId", mTargetId)
                    .appendQueryParameter("title", mTitle)
                    .build()
            topFragment?.uri = uri
            topFragment?.arguments = bundleOf("lordId" to memberLord!!.userId)
            val fragmentTransaction = fragmentManager.beginTransaction()
            fragmentTransaction.add(R.id.top_notice_container, topFragment!!).commitAllowingStateLoss()
        }
    }


    /**
     * 接收消息回调
     */
    public fun onEventMainThread(event: Event.OnReceiveMessageEvent) {
        val message = event.message
        setLordMessage(message)
    }

    /**
     * 发送消息回调
     */
    public fun onEventMainThread(message: Message) {
        setLordMessage(message)
    }

    /**
     * 设置群主消息
     */
    @SuppressLint("SetTextI18n")
    private fun setLordMessage(message: Message) {
        if (!message.senderUserId.equals(memberLord?.userId)) return
        when {
            message.content is TextMessage -> {
                val content = (message.content as TextMessage).content
                val builder = AndroidEmoji.replaceEmojiWithText(SpannableStringBuilder(content))
                AndroidEmoji.ensure(builder)
                if (builder.length > 500) {
                    handler.postDelayed({ binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:$builder" }, 50L)
                } else {
                    binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:$builder"
                }
            }
            message.content is VoiceMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[语音消息]"
            message.content is ImageMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[图片消息]"
            message.content is RichContentMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[图文消息]"
            message.content is FileMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[文件消息]"
            message.content is LocationMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[位置消息]"
            message.content is SightMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[视频消息]"
            message.content is ContactMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[名片消息]"
            message.content is RCVibrationMessage -> binding.tvLastMsg.text = "[群主]${memberLord?.nickname}:[震]"

        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        if (mConversationType == Conversation.ConversationType.PRIVATE) {
            if (Const.SERVICE_ID.contains(mTargetId!!)) return true
            menu.add("").setIcon(R.mipmap.ic_chat_menu).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
        } else if (mConversationType == Conversation.ConversationType.GROUP) {
            menu.add("").setIcon(R.mipmap.ic_chat_group_menu).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
        }
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        if (mConversationType == Conversation.ConversationType.PRIVATE) {
            ARouter.getInstance().build(RouteConfig.USER_INFO_DETAILS_ACTIVITY).withString("userId", mTargetId)
                    .navigation()
        } else if (mConversationType == Conversation.ConversationType.GROUP) {
            ARouter.getInstance().build(RouteConfig.GROUP_INFO_ACTIVITY).withString("groupId", mTargetId)
                    .navigation()
        }
        return true
    }

    override fun onEvent(key: String?, var1: String?) {
        when (key) {
            Const.ObserverKey.DISSOLUTION_GROUP, Const.ObserverKey.EXIT_GROUP -> { //解散//退出
                RongIM.getInstance().clearMessages(Conversation.ConversationType.GROUP, mTargetId, object : RongIMClient.ResultCallback<Boolean>() {
                    override fun onSuccess(aBoolean: Boolean?) {
                        RongIM.getInstance().removeConversation(Conversation.ConversationType.GROUP, mTargetId, null)
                    }

                    override fun onError(e: RongIMClient.ErrorCode) {

                    }
                })
                finish()
            }
            Const.ObserverKey.REFRESH_GROUP_INFO -> { //更新信息
                presenter.groupinfoTask(mTargetId!!)
            }
            Const.ObserverKey.FORWARD_MESSAGE -> { //转发
                if (!var1.equals(mTargetId)) {
                    finish()
                }
            }
            Const.ObserverKey.DELETE_FRIEND_LIST -> {
                if (var1.equals(mTargetId)) {
                    RongIM.getInstance().clearMessages(Conversation.ConversationType.PRIVATE, mTargetId, object : RongIMClient.ResultCallback<Boolean>() {
                        override fun onSuccess(aBoolean: Boolean?) {
                            RongIM.getInstance().removeConversation(Conversation.ConversationType.PRIVATE, mTargetId, null)
                        }

                        override fun onError(e: RongIMClient.ErrorCode) {

                        }
                    })
                    finish()
                }
            }
            Const.ObserverKey.UPDATE_FRIEND_INFO -> {
                if (var1.equals(mTargetId)) {
                    presenter.userInfoTask(mTargetId!!)
                }
            }
            Const.ObserverKey.REFRESH_GROUP_MEMBER -> {
                if (var1.equals(mTargetId)) {
                    presenter.queryGroupMember(mTargetId!!, false)
                }
            }
            Const.ObserverKey.GROUP_KICKING -> {
                if (var1.equals(mTargetId)) {
                    finish()
                }
            }
            Const.ObserverKey.GROUP_NOTICE_REFRESH -> {
                if (mTargetId.equals(var1)) {
                    //发送更新群公告消息
                    showGroupNotice(Preferences.getGroupNotice(mTargetId))
                }
            }
        }
    }

    /**
     * 获取群主
     */
    private fun getMemberByLord(memberModel: ListModel<MemberBean>) {
        memberModel.list?.forEach {
            if (it.type == Const.GROUP_ROLE.ROLE_GROUP_LORDE) {
                memberLord = it
            }
        }
    }

    /**
     * 获取最后一条信息
     */
    private fun getLaseMessage() {
        val objectNames = ArrayList<String>()
        objectNames.add("RC:TxtMsg")
        objectNames.add("RC:VcMsg")
        objectNames.add("RC:ImgMsg")
        objectNames.add("RC:ImgTextMsg")
        objectNames.add("RC:FileMsg")
        objectNames.add("RC:LBSMsg")
        objectNames.add("RC:SightMsg")
        objectNames.add("RC:PSImgTxtMsg")
        objectNames.add("RC:PSMultiImgTxtMsg")
        objectNames.add("RC:CardMsg")
        objectNames.add("RC:Vibration")
        RongIMClient.getInstance().getHistoryMessages(mConversationType, mTargetId, objectNames, 0, 100, RongCommonDefine.GetMessageDirection.FRONT, object : RongIMClient.ResultCallback<List<Message>>() {
            override fun onSuccess(p0: List<Message>?) {
                p0?.forEach {
                    if (it.senderUserId.equals(memberLord?.userId)) {
                        setLordMessage(it)
                        return
                    }
                }
            }

            override fun onError(p0: RongIMClient.ErrorCode?) {
            }
        })
    }

    /**
     * 置顶消息动画
     */
    private fun startAnimation(view: View, duration: Long, start: Float, next: Float) {
        binding.topNoticeContainer.visible()
        val anim = ObjectAnimator.ofFloat(view, "translationY", start, next).setDuration(duration)
        anim.start()
//        val height = binding.topLayout.height
        val height = DensityUtil.dip2px(this, 210F)
        anim.addUpdateListener { animation ->
            val value = animation?.getAnimatedValue("translationY") as Float
            val layoutParams = binding.topLayout.layoutParams as LinearLayout.LayoutParams
            layoutParams.height = height + value.toInt()
            binding.topLayout.layoutParams = layoutParams
        }
        handler.postDelayed({
            if (next > start) {
                binding.tvLastMsg.gone()
                binding.ivRetract.visible()
            } else {
                binding.tvLastMsg.visible()
                binding.ivRetract.gone()
            }
        }, duration)
    }


    override fun onDestroy() {
        super.onDestroy()
        handler.removeCallbacksAndMessages(null)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.DISSOLUTION_GROUP, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.REFRESH_GROUP_INFO, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.FORWARD_MESSAGE, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.DELETE_FRIEND_LIST, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.UPDATE_FRIEND_INFO, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.EXIT_GROUP, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.REFRESH_GROUP_MEMBER, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.GROUP_KICKING, this)
        ObserverManager.getInstance().unregisterObserver(Const.ObserverKey.GROUP_NOTICE_REFRESH, this)
        EventBus.getDefault().unregister(this)
    }
}