package com.adealink.weparty.im.session.comp

import android.annotation.SuppressLint
import android.net.Uri
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import android.widget.TextView.OnEditorActionListener
import androidx.core.net.toUri
import androidx.fragment.app.FragmentContainerView
import androidx.lifecycle.LifecycleOwner
import com.adealink.frame.aab.util.getCompatColor
import com.adealink.frame.base.fastLazy
import com.adealink.frame.data.json.froJsonErrorNull
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.view.ViewComponent
import com.adealink.frame.mvvm.viewmodel.activityViewModels
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.mediapicker.imageselect.comp.TakeFromAlbumComp
import com.adealink.weparty.commonui.mediapicker.imageselect.comp.TakePhotoComp
import com.adealink.weparty.commonui.text.setMaxLength
import com.adealink.weparty.constant.IM_MESSAGE_MAX_LENGTH
import com.adealink.weparty.im.R
import com.adealink.weparty.im.constant.TAG_IM_FLOW
import com.adealink.weparty.im.databinding.LayoutSessionBottomInputBarBinding
import com.adealink.weparty.im.session.comp.input.InputAction
import com.adealink.weparty.im.session.comp.input.InputState
import com.adealink.weparty.im.session.comp.viewmodel.SessionInputViewModel
import com.adealink.weparty.module.im.data.TAG_IM_SESSION
import com.adealink.weparty.util.QMUIKeyboardHelper
import com.adealink.weparty.util.isMultiWindowMode
import com.tencent.qcloud.tuikit.timcommon.bean.ChatFace
import com.tencent.qcloud.tuikit.timcommon.component.face.FaceManager
import com.tencent.qcloud.tuikit.timcommon.interfaces.OnFaceInputListener
import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo
import com.tencent.qcloud.tuikit.tuichat.component.face.FaceFragment
import com.tencent.qcloud.tuikit.tuichat.presenter.ChatPresenter
import com.tencent.qcloud.tuikit.tuichat.util.ChatMessageBuilder
import com.adealink.weparty.R as APP_R

class SessionBottomInputComp(
    lifecycleOwner: LifecycleOwner,
    val inputBar: LayoutSessionBottomInputBarBinding,
    val emotionContainer: FragmentContainerView,
    val chatInfo: ChatInfo? = null,
    val presenter: ChatPresenter? = null
) : ViewComponent(lifecycleOwner) {

    companion object {
        private const val TAG = "SessionBottomInputComp"
    }

    private lateinit var takePhotoComp: TakePhotoComp
    private lateinit var takeFromAlbumComp: TakeFromAlbumComp

    private val emotionFragment by fastLazy { FaceFragment() }
    private val sessionInputViewModel by activityViewModels<SessionInputViewModel>()

    private var isTextSendEnable = false
    override fun onCreate() {
        super.onCreate()
        initView()
        initComponent()
        observeViewModel()
    }

    override fun onPause() {
        super.onPause()
        saveDraft()
    }

    private fun initView() {
        inputBar.btnEmoji.onClick {
            clickEmoji()
        }
        inputBar.btnPhoto.onClick {
            clickPhoto()
        }
        inputBar.btnVoice.onClick {
            clickVoice()
        }
        initInputText()
    }

    private fun initComponent() {
        TakePhotoComp(
            fragment ?: requireActivity(),
            clipParamData = null,
            onPhotoSelect = { path, uri ->
                if (path.isNullOrEmpty() || uri.isNullOrEmpty()) {
                    return@TakePhotoComp
                }
                sendPhotoVideoMessage(uri.toUri(), null)
            }
        ).also {
            takePhotoComp = it
        }.attach()
        TakeFromAlbumComp(
            fragment ?: requireActivity(),
            clipParamData = null,
            onSelect = { path, uri ->
                if (path.isNullOrEmpty() || uri.isNullOrEmpty()) {
                    return@TakeFromAlbumComp
                }
                sendPhotoVideoMessage(uri.toUri(), null)
            }
        ).also {
            takeFromAlbumComp = it
        }.attach()
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initInputText() {
        var inputContent: String? = null

        val draftInfo = chatInfo?.getDraft()
        if (draftInfo != null && !draftInfo.draftText.isNullOrEmpty()) {
            try {
                val draftJsonMap = froJsonErrorNull<HashMap<*, *>>(draftInfo.draftText)
                if (draftJsonMap != null) {
                    inputContent = draftJsonMap["content"] as String?
//                    val replayStr = draftJsonMap["reply"] as String?
//                    val replayPreview = froJsonErrorNull(replayStr, ReplyPreviewBean::class.java)
//                    if (replayPreview != null) {
//                        showReplyPreview(replayPreview)
//                    }
                }
            } catch (e: Exception) {
                Log.e(TAG_IM_SESSION, " getCustomJsonMap error:${e.message}", e)
            }
        }
        inputBar.etInputMessage.setMaxLength(IM_MESSAGE_MAX_LENGTH)
        inputBar.etInputMessage.setText(inputContent)
        inputBar.etInputMessage.setSelection(inputBar.etInputMessage.getText()?.length ?: 0)
//        isTextInput = !inputBar.etInputMessage.text.isNullOrEmpty()
//        setTextInputMode()

        inputBar.etInputMessage.isClickable = true
        inputBar.etInputMessage.setOnTouchListener { view, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                sessionInputViewModel.execute(InputAction.CLICK_INPUT)
            }
            false
        }
        inputBar.etInputMessage.setOnEditorActionListener(object : OnEditorActionListener {
            override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
                if (actionId == EditorInfo.IME_ACTION_SEND
                    || (actionId == EditorInfo.IME_ACTION_UNSPECIFIED && event != null && event.keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN)
                ) {
                    sendTextMessage()
                }
                return true
            }
        })
        inputBar.etInputMessage.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(
                s: CharSequence?,
                start: Int,
                count: Int,
                after: Int
            ) {
            }

            override fun onTextChanged(
                s: CharSequence?,
                start: Int,
                before: Int,
                count: Int
            ) {
            }

            override fun afterTextChanged(s: Editable?) {
                val input = s?.toString()?.trim()
                if (input.isNullOrEmpty()) {
                    isTextSendEnable = false
                } else {
                    isTextSendEnable = true
                }
                if (inputBar.etInputMessage.lineCount > 1) {
                    //大于一行
                    inputBar.clInput.setBackgroundResource(R.drawable.im_session_input_multi_line_bg)
                } else {
                    inputBar.clInput.setBackgroundResource(R.drawable.im_session_input_bg)
                }
            }
        })
    }


    fun saveDraft() {
        if (chatInfo == null) {
            Log.e(TAG_IM_SESSION, "set drafts error :  chatInfo is null")
            return
        }

        var draftText = inputBar.etInputMessage.getText().toString()
//        if ((isQuoteModel || isReplyModel) && replyPreviewBean != null) {
//            val gson = Gson()
//            val draftMap: MutableMap<String?, String?> = java.util.HashMap<String?, String?>()
//            draftMap.put("content", draftText)
//            draftMap.put("reply", gson.toJson(replyPreviewBean))
//            draftText = gson.toJson(draftMap)
//        }
        presenter?.setDraft(draftText)

    }

    private fun observeViewModel() {
        /**
         *  transition to {@link InputState.STATE_EMOJI_INPUT}
         */
        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_SOFT_INPUT,
            action = InputAction.CLICK_EMOJI_BUTTON,
            nextState = InputState.STATE_EMOJI_INPUT
        ).event.observe(viewLifecycleOwner) {
            showEmotionPanel()
            hideSoftInput()
            inputBar.etInputMessage.requestFocus()
        }
        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_NONE,
            action = InputAction.CLICK_EMOJI_BUTTON,
            nextState = InputState.STATE_EMOJI_INPUT
        ).event.observe(viewLifecycleOwner) {
            showEmotionPanel()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_EMOJI_INPUT,
            action = InputAction.EMPTY_CLICKED,
            nextState = InputState.STATE_NONE
        ).event.observe(viewLifecycleOwner) {
            hideEmotionPanel()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_NONE,
            action = InputAction.CLICK_INPUT,
            nextState = InputState.STATE_SOFT_INPUT
        ).event.observe(viewLifecycleOwner) {
            showSoftInput()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_EMOJI_INPUT,
            action = InputAction.CLICK_INPUT,
            nextState = InputState.STATE_SOFT_INPUT
        ).event.observe(viewLifecycleOwner) {
            hideEmotionPanel()
            showSoftInput()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_EMOJI_INPUT,
            action = InputAction.CLICK_EMOJI_BUTTON,
            nextState = InputState.STATE_SOFT_INPUT
        ).event.observe(viewLifecycleOwner) {
            hideEmotionPanel()
            showSoftInput()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_EMOJI_INPUT,
            action = InputAction.EMPTY_CLICKED,
            nextState = InputState.STATE_NONE
        ).event.observe(viewLifecycleOwner) {
            resetInput()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_SOFT_INPUT,
            action = InputAction.EMPTY_CLICKED,
            nextState = InputState.STATE_NONE
        ).event.observe(viewLifecycleOwner) {
            resetInput()
        }

        sessionInputViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_AUDIO_INPUT,
            action = InputAction.EMPTY_CLICKED,
            nextState = InputState.STATE_NONE
        ).event.observe(viewLifecycleOwner) {
            resetInput()
        }

        sessionInputViewModel.inputStateLD.observe(viewLifecycleOwner) { state ->
            when (state.currentState) {
                InputState.STATE_SOFT_INPUT,
                InputState.STATE_EMOJI_INPUT,
                InputState.STATE_IMAGE_INPUT -> {
                    inputBar.btnVoice.setImageResource(R.drawable.im_session_message_send_ic)
                    inputBar.btnVoice.onClick {
                        sendTextMessage()
                    }
                }

                InputState.STATE_NONE,
                InputState.STATE_AUDIO_INPUT -> {
                    inputBar.btnVoice.setImageResource(R.drawable.im_session_voice_ic)
                    inputBar.btnVoice.onClick {
                        clickVoice()
                    }
                }
            }
        }

        //处理非全屏窗口底部输入栏
        sessionInputViewModel.bottomImeVisibleLD.observe(viewLifecycleOwner) { visible ->
            if (!activity.isMultiWindowMode() && !visible) {
                val currentState = sessionInputViewModel.inputStateLD.value?.currentState
                if (currentState != null && !currentState.isInTextEditMode() && currentState != InputState.STATE_NONE) {
                    sessionInputViewModel.execute(InputAction.EMPTY_CLICKED)
                }
            }
        }
    }

    private fun clickEmoji() {
        sessionInputViewModel.execute(InputAction.CLICK_EMOJI_BUTTON)
    }

    private fun clickPhoto() {
        //takePhotoComp.takePhoto()
        takeFromAlbumComp.takeFromAlbum()
    }

    private fun clickVoice() {
        sessionInputViewModel.execute(InputAction.CLICK_AUDIO)
    }

    private fun sendTextMessage() {
        if (!isTextSendEnable) {
            return
        }
        sessionInputViewModel.sendMessage(ChatMessageBuilder.buildTextMessage(inputBar.etInputMessage.text?.toString()))
        inputBar.etInputMessage.setText(null)
    }

    private fun sendPhotoVideoMessage(original: Uri?, transcodeUri: Uri?) {
        sessionInputViewModel.sendPhotoVideoMessage(original, transcodeUri)
        QMUIKeyboardHelper.hideKeyboard(inputBar.etInputMessage)
    }

    private fun showSoftInput() {
        QMUIKeyboardHelper.showKeyboard(inputBar.etInputMessage, true)
        inputBar.etInputMessage.requestFocus()
    }

    private fun hideSoftInput() {
        inputBar.etInputMessage.clearFocus()
        QMUIKeyboardHelper.hideKeyboard(inputBar.etInputMessage)
    }

    private fun showEmotionPanel() {
        Log.i(TAG_IM_FLOW, "showFaceViewGroup")
        emotionFragment.setTabIndicatorColor(getCompatColor(APP_R.color.white))
        emotionFragment.setListener(object : OnFaceInputListener {
            override fun onEmojiClicked(emojiKey: String?) {
                val index: Int = inputBar.etInputMessage.selectionStart
                val editable = inputBar.etInputMessage.text
                editable?.insert(index, emojiKey)
                FaceManager.handlerEmojiText(inputBar.etInputMessage, editable, true)
            }

            override fun onDeleteClicked() {
                inputBar.etInputMessage.inputConnection?.sendKeyEvent(
                    KeyEvent(
                        KeyEvent.ACTION_DOWN,
                        KeyEvent.KEYCODE_DEL
                    )
                )
            }

            override fun onSendClicked() {
                sendTextMessage()
            }

            override fun onFaceClicked(face: ChatFace) {
                val messageBean = ChatMessageBuilder.buildFaceMessage(
                    face.faceGroup.groupID,
                    face.faceKey
                )
                sessionInputViewModel.sendMessage(messageBean)
            }
        })
        hideSoftInput()
        inputBar.etInputMessage.requestFocus()
        inputBar.btnEmoji.setImageResource(APP_R.drawable.common_session_keyboard_ic)
        emotionContainer.show()
        fragmentManager.beginTransaction().replace(emotionContainer.id, emotionFragment)
            .commitAllowingStateLoss()
    }

    private fun hideEmotionPanel() {
        emotionContainer.gone()
        inputBar.btnEmoji.setImageResource(APP_R.drawable.common_emoji_ic)
    }

    private fun resetInput() {
        emotionContainer.gone()
        hideEmotionPanel()
        hideSoftInput()
    }

}