package kr.co.vividnext.sodalive.main

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.gson.annotations.SerializedName
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.audio_content.AddAllPlaybackTrackingRequest
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
import kr.co.vividnext.sodalive.audio_content.PlaybackTrackingData
import kr.co.vividnext.sodalive.audio_content.PlaybackTrackingRepository
import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.settings.event.EventItem
import kr.co.vividnext.sodalive.settings.event.EventRepository
import kr.co.vividnext.sodalive.settings.notification.UpdateNotificationSettingRequest
import kr.co.vividnext.sodalive.user.UserRepository
import java.util.concurrent.Executors

class MainViewModel(
    private val userRepository: UserRepository,
    private val eventRepository: EventRepository,
    private val audioContentRepository: AudioContentRepository,
    private val playbackTrackingRepository: PlaybackTrackingRepository
) : BaseViewModel() {
    enum class CurrentTab {
        @SerializedName("CONTENT")
        CONTENT,

        @SerializedName("LIVE")
        LIVE,

        @SerializedName("EXPLORER")
        EXPLORER,

        @SerializedName("MESSAGE")
        MESSAGE,

        @SerializedName("MY")
        MY
    }

    private val _currentTab = MutableLiveData(CurrentTab.CONTENT)
    val currentTab: LiveData<CurrentTab>
        get() = _currentTab

    fun clickTab(tab: CurrentTab) {
        if (_currentTab.value != tab) {
            _currentTab.postValue(tab)
        }
    }

    fun updateNotificationSettings(
        isNotifiedLive: Boolean,
        isNotifiedUploadContent: Boolean,
        isNotifiedMessage: Boolean
    ) {
        compositeDisposable.add(
            userRepository.updateNotificationSettings(
                request = UpdateNotificationSettingRequest(
                    isNotifiedLive,
                    isNotifiedUploadContent,
                    isNotifiedMessage
                ),
                token = "Bearer ${SharedPreferenceManager.token}"
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({}, {})
        )
    }

    fun pushTokenUpdate(pushToken: String) {
        val request = PushTokenUpdateRequest(
            pushToken = pushToken
        )

        compositeDisposable.add(
            userRepository
                .updatePushToken(request, "Bearer ${SharedPreferenceManager.token}")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({}, {})
        )
    }

    fun getMemberInfo(showNotificationSettingsDialog: () -> Unit) {
        compositeDisposable.add(
            userRepository.getMemberInfo(token = "Bearer ${SharedPreferenceManager.token}")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        if (it.success && it.data != null) {
                            val data = it.data
                            SharedPreferenceManager.can = data.can
                            SharedPreferenceManager.role = data.role.name
                            SharedPreferenceManager.isAuth = data.isAuth
                            if (
                                data.followingChannelUploadContentNotice == null &&
                                data.followingChannelLiveNotice == null &&
                                data.messageNotice == null
                            ) {
                                showNotificationSettingsDialog()
                            }
                        }
                    },
                    {}
                )
        )
    }

    fun addAllPlaybackTracking() {
        val playbackTrackingList = playbackTrackingRepository.getAllPlaybackTracking()
        val trackingDataList = playbackTrackingList
            .filter { it.endPosition != null }
            .filter { it.endPosition!! - it.startPosition >= 12000 }
            .map {
                PlaybackTrackingData(it.contentId, it.playDateTime, it.isPreview)
            }

        if (trackingDataList.isNotEmpty()) {
            compositeDisposable.add(
                audioContentRepository.addAllPlaybackTracking(
                    request = AddAllPlaybackTrackingRequest(trackingDataList = trackingDataList),
                    token = "Bearer ${SharedPreferenceManager.token}"
                )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success) {
                                playbackTrackingRepository.removeAllPlaybackTracking()
                            }
                        },
                        {}
                    )
            )
        }
    }

    fun getEventPopup(onSuccess: (EventItem) -> Unit) {
        compositeDisposable.add(
            eventRepository.getEventPopup(token = "Bearer ${SharedPreferenceManager.token}")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        if (it.success && it.data != null) {
                            onSuccess(it.data)
                        }
                    },
                    {}
                )
        )
    }

    fun fetchAndUpdateGaid(context: Context) {
        Executors.newSingleThreadExecutor().execute {
            try {
                val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context)
                adInfo.id?.let { gaid ->
                    val request = GaidUpdateRequest(adid = gaid)
                    compositeDisposable.add(
                        userRepository.updateGaid(
                            request,
                            token = "Bearer ${SharedPreferenceManager.token}"
                        )
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe({}, {})
                    )
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}
