package com.anytypeio.anytype.presentation.types

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.analytics.base.EventsDictionary.librarySetTypeName
import com.anytypeio.anytype.analytics.base.sendEvent
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_utils.ext.orNull
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.presentation.mapper.objectIcon
import com.anytypeio.anytype.presentation.navigation.NavigationViewModel
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import javax.inject.Inject
import javax.inject.Qualifier
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn

@Deprecated("Before Primitives, to delete")
class TypeEditViewModel(
    private val urlBuilder: UrlBuilder,
    private val id: Id,
    private val name: String,
    private val icon: String,
    private val analytics: Analytics
) : NavigationViewModel<TypeEditViewModel.Navigation>() {

    private val unicodeIconFlow = MutableStateFlow(icon)
    private val originalNameFlow = MutableStateFlow(name)

    private var isReadOnly = false

    val uiState: StateFlow<TypeEditState> = combine(
        unicodeIconFlow,
        originalNameFlow
    ) { icon, name ->
        val objectIcon = icon.orNull()?.let {
            val obj = ObjectWrapper.Basic(
                mapOf(
                    Relations.ICON_EMOJI to icon,
                    Relations.LAYOUT to ObjectType.Layout.OBJECT_TYPE.code.toDouble()
                )
            )
            obj.objectIcon(urlBuilder)
        }
        TypeEditState.Data(
            typeName = name,
            emojiUnicode = icon,
            objectIcon = objectIcon ?: ObjectIcon.None
        )
    }.stateIn(
        viewModelScope,
        SharingStarted.WhileSubscribed(STOP_SUBSCRIPTION_TIMEOUT),
        TypeEditState.Idle
    )

    fun onStart(isReadOnly: Boolean) {
        this.isReadOnly = isReadOnly
    }

    fun openEmojiPicker() {
        if (isReadOnly) return
        navigate(Navigation.SelectEmoji)
    }

    fun setEmoji(emojiUnicode: String) {
        unicodeIconFlow.value = emojiUnicode
    }

    fun removeEmoji() {
        unicodeIconFlow.value = ""
    }

    fun uninstallType() {
        navigate(Navigation.BackWithUninstall(id))
    }

    fun updateObjectDetails(name: String) {
        viewModelScope.sendEvent(analytics = analytics, eventName = librarySetTypeName)
        navigate(Navigation.BackWithModify(id, name, unicodeIconFlow.value))
    }

    sealed class Navigation {
        object Back : Navigation()
        object SelectEmoji : Navigation()
        class BackWithUninstall(val typeId: String): Navigation()
        class BackWithModify(
            val typeId: String,
            val typeName: String,
            val typeIcon: String
        ): Navigation()
    }

    class Factory @Inject constructor(
        private val urlBuilder: UrlBuilder,
        @TypeId private val id: Id,
        @TypeName private val name: String,
        @TypeIcon private val icon: String,
        private val analytics: Analytics
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return TypeEditViewModel(
                urlBuilder = urlBuilder,
                id = id,
                name = name,
                icon = icon,
                analytics = analytics
            ) as T
        }
    }

}

sealed class TypeEditState {
    data class Data(
        val typeName: String,
        val emojiUnicode: String? = null,
        val objectIcon: ObjectIcon = ObjectIcon.None
    ): TypeEditState()
    object Idle: TypeEditState()
}

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class TypeId

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class TypeName

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class TypeIcon



private const val STOP_SUBSCRIPTION_TIMEOUT = 1_000L