package com.example.livingai.pages.addprofile

import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.livingai.domain.model.AnimalDetails
import com.example.livingai.domain.usecases.ProfileEntry.ProfileEntryUseCase
import com.example.livingai.utils.CoroutineDispatchers
import com.example.livingai.utils.IdGenerator
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class AddProfileViewModel(
    private val profileEntryUseCase: ProfileEntryUseCase,
    private val dispatchers: CoroutineDispatchers,
    private val savedStateHandle: SavedStateHandle? = null
) : ViewModel() {

    companion object {
        private const val KEY_ANIMAL_ID = "animal_id"
    }

    private val _animalDetails = mutableStateOf<AnimalDetails?>(null)

    private val _currentAnimalId =
        mutableStateOf(savedStateHandle?.get<String>(KEY_ANIMAL_ID))
    val currentAnimalId: State<String?> = _currentAnimalId

    var species = mutableStateOf<String?>(null)
    var breed = mutableStateOf<String?>(null)
    var age = mutableStateOf("")
    var milkYield = mutableStateOf("")
    var calvingNumber = mutableStateOf("")
    var reproductiveStatus = mutableStateOf<String?>(null)
    var description = mutableStateOf("")

    var ageError = mutableStateOf<String?>(null)
    var milkYieldError = mutableStateOf<String?>(null)
    var calvingNumberError = mutableStateOf<String?>(null)
    var speciesError = mutableStateOf<String?>(null)
    var breedError = mutableStateOf<String?>(null)
    var reproductiveStatusError = mutableStateOf<String?>(null)

    private val _saveSuccess = mutableStateOf(false)

    val photos = mutableStateMapOf<String, String>()
    val segmentedImages = mutableStateMapOf<String, String>()
    private val _videoUri = mutableStateOf<String?>(null)
    val videoUri: State<String?> = _videoUri

    fun initializeNewProfileIfNeeded() {
        if (_currentAnimalId.value != null) return

        val id = IdGenerator.generateAnimalId()
        _currentAnimalId.value = id
        savedStateHandle?.let { it[KEY_ANIMAL_ID] = id }

        _animalDetails.value = null
        species.value = null
        breed.value = null
        age.value = ""
        milkYield.value = ""
        calvingNumber.value = ""
        reproductiveStatus.value = null
        description.value = ""
        clearErrors()
        photos.clear()
        segmentedImages.clear()
        _videoUri.value = null
    }

    fun loadAnimal(animalId: String) {
        if (_currentAnimalId.value == animalId) return

        _currentAnimalId.value = animalId
        savedStateHandle?.set(KEY_ANIMAL_ID, animalId)

        profileEntryUseCase.getAnimalDetails(animalId)
            .onEach { details ->
                details ?: return@onEach

                _animalDetails.value = details
                species.value = details.species.ifBlank { null }
                breed.value = details.breed.ifBlank { null }
                age.value = details.age.takeIf { it > 0 }?.toString() ?: ""
                milkYield.value = details.milkYield.takeIf { it > 0 }?.toString() ?: ""
                calvingNumber.value = details.calvingNumber.takeIf { it > 0 }?.toString() ?: ""
                reproductiveStatus.value = details.reproductiveStatus.ifBlank { null }
                description.value = details.description
                clearErrors()

                photos.clear()
                segmentedImages.clear()

                withContext(dispatchers.main) {
                    details.images.forEach { photos[it.key] = it.value }
                    details.segmentedImages.forEach { segmentedImages[it.key] = it.value }
                }

                _videoUri.value = details.video.ifBlank { null }
            }
            .launchIn(viewModelScope)
    }

    fun saveAnimalDetails(): Boolean {
        if (!validateInputs()) return false

        val id = _currentAnimalId.value ?: return false

        val details = AnimalDetails(
            animalId = id,
            species = species.value ?: "",
            breed = breed.value ?: "",
            age = age.value.toIntOrNull() ?: 0,
            milkYield = milkYield.value.toIntOrNull() ?: 0,
            calvingNumber = calvingNumber.value.toIntOrNull() ?: 0,
            reproductiveStatus = reproductiveStatus.value ?: "",
            description = description.value,
            images = photos,
            video = _videoUri.value ?: "",
            segmentedImages = segmentedImages,
            name = "",
            sex = "",
            weight = 0
        )

        viewModelScope.launch {
            profileEntryUseCase.setAnimalDetails(details)
            _saveSuccess.value = true
        }

        return true
    }

    private fun clearErrors() {
        ageError.value = null
        milkYieldError.value = null
        calvingNumberError.value = null
        speciesError.value = null
        breedError.value = null
        reproductiveStatusError.value = null
    }

    fun addPhoto(orientation: String, uri: String) {
        photos[orientation] = uri
    }

    fun addSegmentedImage(orientation: String, uri: String) {
        segmentedImages[orientation] = uri
    }

    fun setVideo(uri: String) {
        _videoUri.value = uri
    }

    private fun validateInputs(): Boolean {
        var isValid = true

        if (!validateSpeciesInputs()) isValid = false
        if (!validateBreedInputs()) isValid = false
        if (!validateAgeInputs()) isValid = false
        if (!validateMilkYieldInputs()) isValid = false
        if (!validateCalvingInputs()) isValid = false
        if (!validateReproductiveStatusInputs()) isValid = false

        return isValid
    }

    fun validateSpeciesInputs(s: String? = null): Boolean {
        if (s != null)
            species.value = s

        var isValid = true

        if (species.value.isNullOrBlank()) {
            speciesError.value = "Species is required"
            isValid = false
        } else {
            speciesError.value = null
        }
        return isValid
    }

    fun validateBreedInputs(b: String? = null): Boolean {
        if (b != null)
            breed.value = b

        var isValid = true

        if (breed.value.isNullOrBlank()) {
            breedError.value = "Breed is required"
            isValid = false
        } else {
            breedError.value = null
        }

        return isValid
    }

    fun validateReproductiveStatusInputs(r: String? = null): Boolean {
        if (r != null)
            reproductiveStatus.value = r

        var isValid = true

        if (reproductiveStatus.value.isNullOrBlank()) {
            reproductiveStatusError.value = "Status is required"
            isValid = false
        } else {
            reproductiveStatusError.value = null
        }
        return isValid
    }

    fun validateAgeInputs(a: String? = null): Boolean {
        if (a != null)
            age.value = a

        var isValid = true

        val ageInt = age.value.toIntOrNull()
        if (ageInt == null || ageInt <= 0 || ageInt > 20) {
            ageError.value = "Invalid age"
            isValid = false
        } else {
            ageError.value = null
        }

        return isValid
    }

    fun validateMilkYieldInputs(m: String? = null): Boolean {
        if (m != null)
            milkYield.value = m

        var isValid = true

        val milkInt = milkYield.value.toIntOrNull()
        if (milkInt == null || milkInt <= 0 || milkInt > 75) {
            milkYieldError.value = "Invalid milk yield"
            isValid = false
        } else {
            milkYieldError.value = null
        }

        return isValid
    }

    fun validateCalvingInputs(c: String? = null): Boolean {
        if (c != null)
            calvingNumber.value = c

        var isValid = true

        val calvingInt = calvingNumber.value.toIntOrNull()
        if (calvingInt == null || calvingInt < 0 || calvingInt > 12) {
            calvingNumberError.value = "Invalid calving number"
            isValid = false
        } else {
            calvingNumberError.value = null
        }

        return isValid
    }
}
