package kr.co.vividnext.sodalive.message.voice

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.orhanobut.logger.Logger
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.message.GetVoiceMessageResponse
import kr.co.vividnext.sodalive.message.MessageBox
import kr.co.vividnext.sodalive.message.MessageRepository

class VoiceMessageViewModel(private val repository: MessageRepository) : BaseViewModel() {
    private val _messageBoxLiveData = MutableLiveData(MessageBox.RECEIVE)
    val messageBoxLiveData: LiveData<MessageBox>
        get() = _messageBoxLiveData

    private val _getMessagesLiveData =
        MutableLiveData<List<GetVoiceMessageResponse.VoiceMessageItem>>()
    val getMessagesLiveData: LiveData<List<GetVoiceMessageResponse.VoiceMessageItem>>
        get() = _getMessagesLiveData

    private val _toastLiveData = MutableLiveData<String?>()
    val toastLiveData: LiveData<String?>
        get() = _toastLiveData

    var page = 1
    var pageSize = 10
    private var isLast = false

    private var _isLoading = MutableLiveData(false)
    val isLoading: LiveData<Boolean>
        get() = _isLoading

    fun selectMessageBox(messageBox: MessageBox) {
        if (messageBox != _messageBoxLiveData.value!!) {
            isLast = false
            page = 1
            _messageBoxLiveData.postValue(messageBox)
            getMessages(messageBox)
        }
    }

    fun getMessages(messageBox: MessageBox = _messageBoxLiveData.value!!) {
        if (!_isLoading.value!! && !isLast) {
            _isLoading.postValue(true)
            val messageBoxObservable = when (messageBox) {
                MessageBox.SENT -> {
                    repository.getSentVoiceMessage(
                        page - 1,
                        pageSize,
                        "Bearer ${SharedPreferenceManager.token}"
                    )
                }

                MessageBox.RECEIVE -> {
                    repository.getReceivedVoiceMessage(
                        page - 1,
                        pageSize,
                        "Bearer ${SharedPreferenceManager.token}"
                    )
                }

                MessageBox.KEEP -> {
                    repository.getKeepVoiceMessage(
                        page - 1,
                        pageSize,
                        "Bearer ${SharedPreferenceManager.token}"
                    )
                }
            }

            compositeDisposable.add(
                messageBoxObservable
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success && it.data != null) {
                                page += 1
                                if (it.data.items.isNotEmpty()) {
                                    _getMessagesLiveData.postValue(it.data.items)
                                } else {
                                    isLast = true
                                    _getMessagesLiveData.postValue(listOf())
                                }
                            } else {
                                if (it.message != null) {
                                    _toastLiveData.postValue(it.message)
                                } else {
                                    _toastLiveData.postValue(
                                        "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                    )
                                }
                            }
                            _isLoading.postValue(false)
                        },
                        {
                            it.message?.let { message -> Logger.e(message) }
                            _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                            _isLoading.postValue(false)
                        }
                    )
            )
        }
    }

    fun deleteMessage(messageId: Long, onSuccess: () -> Unit) {
        if (messageId <= 0) {
            _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
            return
        }

        compositeDisposable.add(
            repository.deleteMessage(
                messageId = messageId,
                token = "Bearer ${SharedPreferenceManager.token}"
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        if (it.success) {
                            onSuccess()
                        } else {
                            if (it.message != null) {
                                _toastLiveData.postValue(it.message)
                            } else {
                                _toastLiveData.postValue(
                                    "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                )
                            }
                        }
                    },
                    {
                        it.message?.let { message -> Logger.e(message) }
                        _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                    }
                )
        )
    }

    fun keepVoiceMessage(messageId: Long) {
        if (messageId <= 0) {
            _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
            return
        }

        _isLoading.value = true
        compositeDisposable.add(
            repository.keepVoiceMessage(
                messageId = messageId,
                token = "Bearer ${SharedPreferenceManager.token}"
            ).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        _isLoading.value = false
                        if (it.success) {
                            _toastLiveData.postValue(
                                "보관되었습니다."
                            )
                        } else {
                            if (it.message != null) {
                                _toastLiveData.postValue(it.message)
                            } else {
                                _toastLiveData.postValue(
                                    "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                )
                            }
                        }
                    },
                    {
                        it.message?.let { message -> Logger.e(message) }
                        _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                        _isLoading.value = false
                    }
                )
        )
    }
}
