package com.sambath.kunkhmer.screen.news

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.sambath.kunkhmer.app.getErrorCode
import com.sambath.kunkhmer.base.BaseViewModel
import com.sambath.kunkhmer.remote.CreateHighlightRequest
import com.sambath.kunkhmer.remote.CreateNewsRequest
import com.sambath.kunkhmer.remote.CreatedNews
import com.sambath.kunkhmer.remote.HighlightData
import com.sambath.kunkhmer.remote.NewsData
import com.sambath.kunkhmer.remote.service.ApiService
import com.sambath.kunkhmer.util.PrefHelper
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException

data class NewsViewState(
    val initial: Boolean = false, val isProgress: Boolean = false, val isLoginSuccess: Boolean = false, val error: String? = null, val newsData: NewsData? = null, val highlightData: HighlightData? = null, val createdNewsData: CreatedNews? = null
)

class NewsViewModel(val apiService: ApiService, val prefHelper: PrefHelper) : BaseViewModel() {
    private val _state = MutableLiveData(NewsViewState())
    val state: LiveData<NewsViewState> = _state
    private fun prev() = _state.value!!

    fun getNews() {
        if (_state.value!!.isProgress) return
        _state.value = prev().copy(isProgress = true)

        disposables.add(
            apiService.getNews().timeout(10, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({
                if (it.resultCode == 1) {
                    _state.value = prev().copy(isProgress = false, isLoginSuccess = true, newsData = it.data!!)
                } else {
                    _state.value = prev().copy(isProgress = false, error = "[${it.message.description}]")
                }
            }, {
                val message: String = "ប្រតិបត្តិការមិនជោគជ័យ " + it.getErrorCode()
                _state.value = prev().copy(isProgress = false, error = message)
            })
        )
    }

    fun getHighlight() {
        if (_state.value!!.isProgress) return
        _state.value = prev().copy(isProgress = true)

        disposables.add(
            apiService.getHighlights().timeout(10, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({
                if (it.resultCode == 1) {
                    _state.value = prev().copy(isProgress = false, isLoginSuccess = true, highlightData = it.data!!)
                } else {
                    _state.value = prev().copy(isProgress = false, error = "[${it.message.description}]")
                }
            }, {
                val message: String = "ប្រតិបត្តិការមិនជោគជ័យ " + it.getErrorCode()
                _state.value = prev().copy(isProgress = false, error = message)
            })
        )
    }

    fun createHighlight(title: String, date: String, url: String) {
        if (_state.value!!.isProgress) return
        val request = CreateHighlightRequest(title, date, url)
        _state.value = prev().copy(isProgress = true)

        disposables.add(
            apiService.createHighlight(request).timeout(60, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    Log.d("login", it.toString())
                    if (it.resultCode == 1) {
                        _state.value = prev().copy(isProgress = false, isLoginSuccess = true)
                    } else {
                        _state.value = prev().copy(isProgress = false, error = "[${it.message.description}]")
                    }
                }, {
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ " + it.getErrorCode()
                    _state.value = prev().copy(isProgress = false, error = message)
                })
        )
    }

    fun createNews(title: String, desc: String, upload: String) {
        if (_state.value!!.isProgress) return
        val request = CreateNewsRequest(title, desc, upload)

        val titlePart = request.title.toRequestBody("text/plain".toMediaTypeOrNull())
        val descPart = request.desc.toRequestBody("text/plain".toMediaTypeOrNull())

        if (!upload.isNullOrEmpty()) {
            // Assuming 'upload' is a file path, you may need to modify this part based on your actual requirements
            val file = File(request.upload)
            val filePart = MultipartBody.Part.createFormData("upload", file.name, file.asRequestBody("image/jpg".toMediaTypeOrNull()))
            _state.value = prev().copy(isProgress = true)

            disposables.add(
                apiService.createNews(titlePart, descPart, filePart).timeout(60, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({
                    Log.d("login", it.toString())
                    if (it.resultCode == 1) {
                        _state.value = prev().copy(isProgress = false, isLoginSuccess = true)
                    } else {
                        _state.value = prev().copy(isProgress = false, error = "[${it.message.description}]")
                    }
                }, {
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ " + it.getErrorCode()
                    _state.value = prev().copy(isProgress = false, error = message)
                })
            )
        } else {
            _state.value = prev().copy(isProgress = true)

            disposables.add(apiService.createNews(titlePart, descPart).timeout(10, TimeUnit.SECONDS).doOnSubscribe { Log.d("Network", "Request started") }.doOnSuccess { Log.d("Network", "Request succeeded: $it") }.doOnError { Log.e("Network", "Request failed", it) }.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe({
                    Log.d("login", it.toString())
                    if (it.resultCode == 1) {
                        _state.value = prev().copy(isProgress = false, isLoginSuccess = true)
                    } else {
                        _state.value = prev().copy(isProgress = false, error = "[${it.message.description}]")
                    }
                }, {
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ " + it.getErrorCode()
                    _state.value = prev().copy(isProgress = false, error = message)
                })
            )
        }
    }
}