package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment

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.audio_content.comment.ModifyCommentRequest
import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem

class CreatorCommunityCommentListViewModel(
    private val repository: CreatorCommunityRepository
) : BaseViewModel() {
    private val _toastLiveData = MutableLiveData<String?>()
    val toastLiveData: LiveData<String?>
        get() = _toastLiveData

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

    private var _commentList = MutableLiveData<List<GetCommunityPostCommentListItem>>()
    val commentList: LiveData<List<GetCommunityPostCommentListItem>>
        get() = _commentList

    private var _totalCommentCount = MutableLiveData(0)
    val totalCommentCount: LiveData<Int>
        get() = _totalCommentCount

    var page = 1
    private var isLast = false
    private val size = 10

    fun getCommentList(postId: Long, onFailure: (() -> Unit)? = null) {
        if (!_isLoading.value!! && !isLast) {
            _isLoading.value = true
            compositeDisposable.add(
                repository.getCommunityPostCommentList(
                    postId = postId,
                    page = page - 1,
                    size = size,
                    token = "Bearer ${SharedPreferenceManager.token}"
                )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success && it.data != null) {
                                _totalCommentCount.postValue(it.data.totalCount)

                                page += 1
                                if (it.data.items.isNotEmpty()) {
                                    _commentList.postValue(it.data.items)
                                } else {
                                    isLast = true
                                    _commentList.postValue(listOf())
                                }
                            } else {
                                if (it.message != null) {
                                    _toastLiveData.postValue(it.message)
                                } else {
                                    _toastLiveData.postValue(
                                        "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                    )
                                }

                                if (onFailure != null) {
                                    onFailure()
                                }
                            }

                            _isLoading.value = false
                        },
                        {
                            _isLoading.value = false
                            it.message?.let { message -> Logger.e(message) }
                            _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                            if (onFailure != null) {
                                onFailure()
                            }
                        }
                    )
            )
        }
    }

    fun registerComment(postId: Long, comment: String, commentId: Long? = null) {
        if (!_isLoading.value!!) {
            _isLoading.value = true
        }

        compositeDisposable.add(
            repository.registerComment(
                postId = postId,
                comment = comment,
                parentId = commentId,
                token = "Bearer ${SharedPreferenceManager.token}"
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        _isLoading.value = false

                        if (it.success) {
                            page = 1
                            isLast = false
                            if (commentId != null) {
                                getCommentReplyList(commentId = commentId)
                            } else {
                                getCommentList(postId)
                            }
                        } else {
                            if (it.message != null) {
                                _toastLiveData.postValue(it.message)
                            } else {
                                _toastLiveData.postValue(
                                    "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                )
                            }
                        }
                    },
                    {
                        _isLoading.value = false
                        it.message?.let { message -> Logger.e(message) }
                        _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                    }
                )
        )
    }

    fun modifyComment(
        commentId: Long,
        postId: Long,
        parentCommentId: Long? = null,
        comment: String? = null,
        isActive: Boolean? = null
    ) {
        if (comment == null && isActive == null) {
            _toastLiveData.postValue("변경사항이 없습니다.")
            return
        }

        if (comment != null && comment.isBlank()) {
            _toastLiveData.postValue("내용을 입력하세요")
            return
        }

        _isLoading.value = true

        val request = ModifyCommentRequest(commentId = commentId)

        if (comment != null) {
            request.comment = comment
        }

        if (isActive != null) {
            request.isActive = isActive
        }

        compositeDisposable.add(
            repository.modifyComment(
                request = request,
                token = "Bearer ${SharedPreferenceManager.token}"
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        _isLoading.value = false

                        if (it.success) {
                            page = 1
                            isLast = false

                            if (parentCommentId != null) {
                                getCommentReplyList(parentCommentId)
                            } else {
                                getCommentList(postId)
                            }
                        } else {
                            val message = it.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                            _toastLiveData.postValue(message)
                        }
                    },
                    {
                        _isLoading.value = false
                        it.message?.let { message -> Logger.e(message) }
                        _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                    }
                )
        )
    }

    fun getCommentReplyList(commentId: Long, onFailure: (() -> Unit)? = null) {
        if (!_isLoading.value!! && !isLast) {
            _isLoading.value = true
            compositeDisposable.add(
                repository.getCommentReplyList(
                    commentId = commentId,
                    page = page - 1,
                    size = size,
                    token = "Bearer ${SharedPreferenceManager.token}"
                )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success && it.data != null) {
                                page += 1
                                if (it.data.items.isNotEmpty()) {
                                    _commentList.postValue(it.data.items)
                                } else {
                                    isLast = true
                                    _commentList.postValue(listOf())
                                }
                            } else {
                                if (it.message != null) {
                                    _toastLiveData.postValue(it.message)
                                } else {
                                    _toastLiveData.postValue(
                                        "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                    )
                                }

                                if (onFailure != null) {
                                    onFailure()
                                }
                            }

                            _isLoading.value = false
                        },
                        {
                            _isLoading.value = false
                            it.message?.let { message -> Logger.e(message) }
                            _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                            if (onFailure != null) {
                                onFailure()
                            }
                        }
                    )
            )
        }
    }
}
