package com.adealink.weparty.room.chat

import android.annotation.SuppressLint
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.adealink.frame.aab.util.getCompatColor
import com.adealink.frame.base.fastLazy
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.view.viewBinding
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.text.setMaxLength
import com.adealink.weparty.commonui.widget.KeyboardBottomDialogFragment
import com.adealink.weparty.constant.IM_MESSAGE_MAX_LENGTH
import com.adealink.weparty.room.R
import com.adealink.weparty.room.chat.data.InputAction
import com.adealink.weparty.room.chat.data.InputState
import com.adealink.weparty.room.chat.viewmodel.ChatMessageViewModel
import com.adealink.weparty.room.chat.viewmodel.InputStateViewModel
import com.adealink.weparty.room.databinding.DialogChatMessageInputBinding
import com.adealink.weparty.room.viewmodel.RoomViewModelFactory
import com.adealink.weparty.util.QMUIKeyboardHelper
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.component.face.FaceFragment
import com.adealink.weparty.R as APP_R

class ChatInputDialog : KeyboardBottomDialogFragment(R.layout.dialog_chat_message_input) {

    companion object {
        const val TAG = "ChatInputDialog"
    }

    private val binding by viewBinding(DialogChatMessageInputBinding::bind)

    private var isTextSendEnable = false

    private val emotionFragment by fastLazy { FaceFragment() }
    private val inputStateViewModel by viewModels<InputStateViewModel>()

    private val chatMessageViewModel by activityViewModels<ChatMessageViewModel> { RoomViewModelFactory() }

    override fun initViews() {
        super.initViews()

        binding.vInputBar.btnEmoji.onClick {
            clickEmoji()
        }
        binding.vInputBar.btnSend.onClick {
            sendTextMessage()
        }
        initInputText()
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initInputText() {
        binding.vInputBar.etInputMessage.setMaxLength(IM_MESSAGE_MAX_LENGTH)
        binding.vInputBar.etInputMessage.setSelection(
            binding.vInputBar.etInputMessage.text?.length ?: 0
        )
        binding.vInputBar.etInputMessage.isClickable = true
        binding.vInputBar.etInputMessage.setOnTouchListener { _, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                inputStateViewModel.execute(InputAction.CLICK_INPUT)
            }
            false
        }
        binding.vInputBar.etInputMessage.setOnEditorActionListener { _, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_SEND
                || (actionId == EditorInfo.IME_ACTION_UNSPECIFIED && event != null && event.keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN)
            ) {
                sendTextMessage()
            }
            true
        }
        
        binding.vInputBar.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()
                isTextSendEnable = !input.isNullOrEmpty()
                
                if (binding.vInputBar.etInputMessage.lineCount > 1) {
                    //大于一行
                    binding.vInputBar.clInput.setBackgroundResource(APP_R.drawable.common_input_edit_bg)
                } else {
                    binding.vInputBar.clInput.setBackgroundResource(APP_R.drawable.common_input_single_edit_bg)
                }
                binding.vInputBar.btnSend.isEnabled = isTextSendEnable
            }
        })

        binding.vInputBar.btnSend.isEnabled = false
        QMUIKeyboardHelper.showKeyboard(binding.vInputBar.etInputMessage, true)
        binding.vInputBar.etInputMessage.requestFocus()
    }

    override fun observeViewModel() {
        super.observeViewModel()

        /**
         *  transition to {@link InputState.STATE_EMOJI_INPUT}
         */
        inputStateViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_SOFT_INPUT,
            action = InputAction.CLICK_EMOJI_BUTTON,
            nextState = InputState.STATE_EMOJI_INPUT
        ).event.observe(viewLifecycleOwner) {
            showEmotionPanel()
            hideSoftInput()
            binding.vInputBar.etInputMessage.requestFocus()
        }
        inputStateViewModel.registerTransaction(
            TAG,
            currentState = InputState.STATE_NONE,
            action = InputAction.CLICK_EMOJI_BUTTON,
            nextState = InputState.STATE_EMOJI_INPUT
        ).event.observe(viewLifecycleOwner) {
            showEmotionPanel()
        }

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

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

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

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

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

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

    private fun sendTextMessage() {
        if (!isTextSendEnable) {
            return
        }
        val inputText = binding.vInputBar.etInputMessage.text?.toString()
        if (inputText.isNullOrEmpty()) {
            return
        }
        chatMessageViewModel.sendTextMessage(inputText)
        dismiss()
    }

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

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

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

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

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

            override fun onSendClicked() {
                sendTextMessage()
            }

            override fun onFaceClicked(face: ChatFace) {
            }
        })
        hideSoftInput()
        binding.vInputBar.etInputMessage.requestFocus()
        binding.vInputBar.btnEmoji.setImageResource(APP_R.drawable.common_session_keyboard_ic)
        binding.flEmotion.show()
        childFragmentManager.beginTransaction().replace(binding.flEmotion.id, emotionFragment)
            .commitAllowingStateLoss()
    }

    private fun hideEmotionPanel() {
        binding.flEmotion.gone()
        binding.vInputBar.btnEmoji.setImageResource(APP_R.drawable.common_emoji_ic)
    }

    private fun resetInput() {
        binding.flEmotion.gone()
        hideEmotionPanel()
        hideSoftInput()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        hideSoftInput()
    }

}