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

import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.adealink.frame.base.IError
import com.adealink.frame.base.Rlt
import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.weparty.im.session.comp.input.InputAction
import com.adealink.weparty.im.session.comp.input.InputMachineTransaction
import com.adealink.weparty.im.session.comp.input.InputState
import com.adealink.weparty.im.session.comp.input.SessionInputMachine
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback
import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo
import com.tencent.qcloud.tuikit.tuichat.component.progress.ProgressPresenter
import com.tencent.qcloud.tuikit.tuichat.presenter.ChatPresenter
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine


data class SessionInputState(
    val lastState: InputState,
    val currentState: InputState
)

class SessionInputViewModel : BaseViewModel() {

    val transactionLD = ExtMutableLiveData<InputMachineTransaction>()
    val inputStateLD = MutableLiveData<SessionInputState>()
    private val stateMachine: SessionInputMachine =
        SessionInputMachine(
            InputState.STATE_NONE,
            mutableListOf(
                /**
                 * transition to [InputState.STATE_NONE]
                 */
                InputMachineTransaction(
                    "",
                    currentState = InputState.STATE_NONE,
                    action = InputAction.EMPTY_CLICKED,
                    nextState = InputState.STATE_NONE
                ),
            ),
            { transaction ->
                transactionLD.send(transaction)
            },
            { last, current ->
                inputStateLD.send(SessionInputState(last, current))
            }
        )


    /**
     * 参考:InputAction
     */
    fun execute(action: InputAction) {
        stateMachine.execute(action)
    }

    fun registerTransaction(
        page: String,
        currentState: InputState,
        action: InputAction,
        nextState: InputState
    ): InputMachineTransaction {
        return stateMachine.registerTransaction(page, currentState, action, nextState)
    }


    private var chatInfo: ChatInfo? = null
    private var presenter: ChatPresenter? = null

    val sendMessageResultLD = ExtMutableLiveData<Rlt<TUIMessageBean?>>()

    fun init(
        chatInfo: ChatInfo? = null,
        presenter: ChatPresenter? = null
    ) {
        this.chatInfo = chatInfo
        this.presenter = presenter
    }

    fun sendMessage(message: TUIMessageBean) {
        sendMessage(message, false, null)
    }

    fun sendMessage(
        message: TUIMessageBean,
        retry: Boolean,
        callback: IUIKitCallback<TUIMessageBean>?
    ): LiveData<String?> {
        val liveData = OnceMutableLiveData<String>()
        viewModelScope.launch {
            val presenter = presenter
            if (presenter == null) {
                liveData.send(null)
                return@launch
            }
            val msgId = sendMessage(presenter, message, retry, callback)
            liveData.send(msgId)
        }
        return liveData
    }

    private suspend fun sendMessage(
        presenter: ChatPresenter,
        message: TUIMessageBean,
        retry: Boolean,
        callback: IUIKitCallback<TUIMessageBean>?
    ): String? {
        return suspendCancellableCoroutine { continuation ->
            presenter.sendMessage(
                message,
                retry,
                false,
                object : IUIKitCallback<TUIMessageBean?>() {
                    override fun onSuccess(data: TUIMessageBean?) {
                        callback?.onSuccess(data)
                        sendMessageResultLD.send(Rlt.Success(data))
                    }

                    override fun onError(module: String?, errCode: Int, errMsg: String?) {
                        callback?.onError(errCode, errMsg, message)
                        sendMessageResultLD.send(
                            Rlt.Failed(
                                IError(
                                    serverCode = errCode,
                                    msg = errMsg ?: ""
                                )
                            )
                        )
//                        var toastMsg = errMsg
//                        if (errCode == TUIConstants.BuyingFeature.ERR_SDK_INTERFACE_NOT_SUPPORT) {
//                            showNotSupportDialog()
//                            if (msg.isNeedReadReceipt()) {
//                                toastMsg =
//                                    (getResources().getString(R.string.chat_message_read_receipt)
//                                            + getResources().getString(R.string.TUIKitErrorUnsupporInterfaceSuffix))
//                            }
//                        }
//                        ToastUtil.toastLongMessage(toastMsg)
                    }

                    override fun onProgress(data: Any?) {
                        val progress = (data as? Int) ?: 0
                        callback?.onProgress(progress)
                        ProgressPresenter.updateProgress(message.id, progress)
                    }
                })
        }
    }

    fun sendPhotoVideoMessage(original: Uri?, transcodeUri: Uri? = null) {
        presenter?.sendPhotoVideoMessages(original, transcodeUri)
    }


}