package com.example.myapplication.database.entities.composeui.edit

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.myapplication.database.entities.model.Bike
import com.example.myapplication.database.entities.model.BikeWithItems
import com.example.myapplication.database.entities.model.ItemFromBike
import com.example.myapplication.database.entities.repository.BikeRepository
import kotlinx.coroutines.launch

class BikeEditViewModel(
    savedStateHandle: SavedStateHandle,
    private val bikeRepository: BikeRepository
) : ViewModel() {
    var bikeUiState by mutableStateOf(BikeUiState())
        private set

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

    init {
        viewModelScope.launch {
            if (bikeUid > 0) {
                bikeUiState = bikeRepository.getBike(bikeUid)
                    .toUiState(true)
            }
        }
    }

    fun updateUiState(bikeDetails: BikeDetails) {
        bikeUiState = BikeUiState(
            bikeDetails = bikeDetails,
            isEntryValid = validateInput(bikeDetails)
        )
    }

    suspend fun saveBike() {
        if (validateInput()) {
            if (bikeUid > 0) {
                bikeRepository.updateBike(bikeUiState.bikeDetails.toBike(bikeUid))
            } else {
                bikeRepository.insertBike(bikeUiState.bikeDetails.toBike())
            }
        }
    }

    private fun validateInput(uiState: BikeDetails = bikeUiState.bikeDetails): Boolean {
        return with(uiState) {
            name.isNotBlank()
                    && description.isNotBlank()
        }
    }
}

data class BikeUiState(
    val bikeDetails: BikeDetails = BikeDetails(),
    val isEntryValid: Boolean = false
)

data class BikeDetails(
    val name: String = "",
    val description: String = "",
    val image: ByteArray? = byteArrayOf(),
    val items: List<ItemFromBike> = emptyList()
)

fun BikeDetails.toBike(uid: Int = 0): Bike = Bike(
    uid = uid,
    name = name,
    description = description,
    image = image
)

fun BikeWithItems.toDetails(): BikeDetails {
    val bike = this.bike
    val items = this.items

    return BikeDetails(
        name = bike.name,
        description = bike.description,
        image = bike.image,
        items = items
    )
}

fun BikeWithItems.toUiState(isEntryValid: Boolean = false): BikeUiState = BikeUiState(
    bikeDetails = this.toDetails(),
    isEntryValid = isEntryValid
)