package com.example.myapplication.database.room.viewmodel.item

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.example.myapplication.database.room.model.item.Item
import com.example.myapplication.database.room.repository.online.ItemRepository
import com.example.myapplication.database.room.viewmodel.LoadingViewModel
import kotlinx.coroutines.launch
import org.threeten.bp.LocalDateTime

class ItemEditViewModel(
    savedStateHandle: SavedStateHandle,
    private val itemRepository: ItemRepository
) : LoadingViewModel() {
    var itemUiState by mutableStateOf(ItemUiState())
        private set

    private val itemUid: Int = checkNotNull(savedStateHandle["id"])
    private val bikeUid: Int = checkNotNull(savedStateHandle["bikeId"])

    init {
        viewModelScope.launch {
            if (itemUid > 0) {
                itemUiState = itemRepository.getItem(itemUid)
                    .toUiState(true)
            }
        }
    }

    fun updateUiState(itemDetails: ItemDetails) {
        itemUiState = ItemUiState(
            itemDetails = itemDetails,
            isEntryValid = validateInput(itemDetails)
        )
    }

    suspend fun saveItem() {
        if (validateInput()) {
            if (bikeUid > 0)
                if (itemUid > 0) {
                    itemRepository.updateItem(
                        itemUiState.itemDetails
                            .toItem(uid = itemUid, bikeUid = bikeUid)
                    )
                } else {
                    itemRepository.insertItem(
                        itemUiState.itemDetails.toItem(
                            bikeUid = bikeUid
                        )
                    )
                }
        }
    }

    private fun validateInput(uiState: ItemDetails = itemUiState.itemDetails): Boolean {
        return with(uiState) {
            dateTime != LocalDateTime.MIN
                    && isValidDouble(weight)
                    && maxCount > 0
                    && bikeUid > 0
        }
    }
}

val regex = """^-?\d+(.\d+)?+(,\d+)?$""".toRegex()

fun isValidDouble(input: String): Boolean {
    return regex.matches(input)
}

data class ItemUiState(
    val itemDetails: ItemDetails = ItemDetails(),
    val isEntryValid: Boolean = false
)

data class ItemDetails(
    val uid: Int = 0,
    val dateTime: LocalDateTime = LocalDateTime.MIN,
    val weight: String = "0",
    val radius: String = "0",
    val colorbike: String = "0",
    val maxCount: Int = 0,
    val bikeId: Int = 0
)

fun ItemDetails.toItem(uid: Int = 0, bikeUid: Int = 0): Item = Item(
    uid = uid,
    dateTime = dateTime,
    weight = weight.toDoubleOrNull() ?: 0.0,
    radius = radius.toDoubleOrNull() ?: 0.0,
    colorbike = colorbike,
    maxCount = maxCount,
    bikeId = bikeUid
)

fun Item.toDetails(): ItemDetails = ItemDetails(
    uid = uid,
    dateTime = dateTime,
    weight = weight.toString(),
    radius = radius.toString(),
    colorbike = colorbike,
    maxCount = maxCount,
    bikeId = bikeId
)

fun Item.toUiState(isEntryValid: Boolean = false): ItemUiState = ItemUiState(
    itemDetails = this.toDetails(),
    isEntryValid = isEntryValid
)