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

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
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.explorer.profile.creator_community.CreatorCommunityRepository
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
import kr.co.vividnext.sodalive.explorer.profile.creator_community.modify.ModifyCommunityPostRequest
import kr.co.vividnext.sodalive.report.ReportRepository
import kr.co.vividnext.sodalive.report.ReportRequest
import kr.co.vividnext.sodalive.report.ReportType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody

class CreatorCommunityAllViewModel(
    private val repository: CreatorCommunityRepository,
    private val reportRepository: ReportRepository
) : 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 _communityPostListLiveData = MutableLiveData<List<GetCommunityPostListResponse>>()
    val communityPostListLiveData: LiveData<List<GetCommunityPostListResponse>>
        get() = _communityPostListLiveData

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

    var creatorId = 0L

    fun getCommunityPostList() {
        if (!_isLoading.value!! && !isLast) {
            _isLoading.value = true
            compositeDisposable.add(
                repository
                    .getCommunityPostList(
                        creatorId = creatorId,
                        page = page,
                        size = pageSize,
                        token = "Bearer ${SharedPreferenceManager.token}"
                    )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success && it.data != null) {
                                if (it.data.isNotEmpty()) {
                                    page += 1
                                    _communityPostListLiveData.postValue(it.data!!)
                                } else {
                                    isLast = true
                                }
                            } else {
                                if (it.message != null) {
                                    _toastLiveData.postValue(it.message)
                                } else {
                                    _toastLiveData.postValue(
                                        "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                    )
                                }
                            }

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

    fun deleteCommunityPostList(postId: Long) {
        if (!_isLoading.value!!) {
            _isLoading.value = true

            val request = ModifyCommunityPostRequest(
                creatorCommunityId = postId,
                isActive = false
            )

            val requestJson = Gson().toJson(request)

            compositeDisposable.add(
                repository.modifyCommunityPost(
                    null,
                    request = requestJson.toRequestBody("text/plain".toMediaType()),
                    token = "Bearer ${SharedPreferenceManager.token}"
                )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            _isLoading.value = false
                            if (it.success) {
                                page = 1
                                isLast = false
                                getCommunityPostList()
                            } 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 communityPostLike(postId: Long) {
        compositeDisposable.add(
            repository.communityPostLike(
                postId = postId,
                token = "Bearer ${SharedPreferenceManager.token}"
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({}, {})
        )

    }

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

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

                        if (it.success) {
                            page = 1
                            isLast = false
                            getCommunityPostList()
                        } 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 report(communityPostId: Long, reason: String) {
        _isLoading.value = true
        val request = ReportRequest(
            type = ReportType.COMMUNITY_POST,
            reason = reason,
            communityPostId = communityPostId
        )

        compositeDisposable.add(
            reportRepository.report(
                request = request,
                token = "Bearer ${SharedPreferenceManager.token}"
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        if (it.message != null) {
                            _toastLiveData.postValue(it.message)
                        } else {
                            _toastLiveData.postValue(
                                "신고가 접수되었습니다."
                            )
                        }

                        _isLoading.value = false
                    },
                    {
                        _isLoading.value = false
                        it.message?.let { message -> Logger.e(message) }
                        _toastLiveData.postValue("신고가 접수되었습니다.")
                    }
                )
        )
    }

    fun purchaseCommunityPost(postId: Long, onSuccess: (GetCommunityPostListResponse) -> Unit) {
        if (!_isLoading.value!!) {
            _isLoading.value = true
            compositeDisposable.add(
                repository
                    .purchaseCommunityPost(
                        postId = postId,
                        token = "Bearer ${SharedPreferenceManager.token}"
                    )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success && it.data != null) {
                                onSuccess(it.data)
                            } else {
                                if (it.message != null) {
                                    _toastLiveData.postValue(it.message)
                                } else {
                                    _toastLiveData.postValue(
                                        "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                    )
                                }
                            }

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