package com.sunzones.ui.main

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sunzones.data.repository.LocationRepository
import com.sunzones.domain.model.MonthDaylight
import com.sunzones.domain.model.SunLocation
import com.sunzones.domain.usecase.CalculateYearlyDaylightUseCase
import com.sunzones.domain.usecase.GetLocationsUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

data class MainUiState(
    val locations: List<SunLocation> = emptyList(),
    val yearlyDaylight: Map<Long, List<MonthDaylight>> = emptyMap(),
    val isLoading: Boolean = true
)

@HiltViewModel
class MainViewModel @Inject constructor(
    private val getLocationsUseCase: GetLocationsUseCase,
    private val calculateYearlyDaylight: CalculateYearlyDaylightUseCase,
    private val repository: LocationRepository
) : ViewModel() {

    private val _uiState = MutableStateFlow(MainUiState())
    val uiState: StateFlow<MainUiState> = _uiState.asStateFlow()

    private var cachedLocationKeys = emptySet<Long>()

    init {
        observeLocations()
        startPeriodicRefresh()
    }

    private fun observeLocations() {
        viewModelScope.launch {
            getLocationsUseCase().collectLatest { locations ->
                _uiState.value = _uiState.value.copy(
                    locations = locations,
                    isLoading = false
                )
                computeYearlyIfNeeded(locations)
            }
        }
    }

    private suspend fun computeYearlyIfNeeded(locations: List<SunLocation>) {
        val currentKeys = locations.map { it.id }.toSet()
        if (currentKeys == cachedLocationKeys) return
        cachedLocationKeys = currentKeys

        val yearlyMap = withContext(Dispatchers.Default) {
            locations.associate { loc ->
                loc.id to calculateYearlyDaylight(
                    latitude = loc.latitude,
                    longitude = loc.longitude,
                    timezoneId = loc.timezoneId.id
                )
            }
        }
        _uiState.value = _uiState.value.copy(yearlyDaylight = yearlyMap)
    }

    private fun startPeriodicRefresh() {
        viewModelScope.launch {
            while (isActive) {
                delay(60_000L) // refresh every minute for sun progress updates
                getLocationsUseCase().collectLatest { locations ->
                    _uiState.value = _uiState.value.copy(locations = locations)
                }
            }
        }
    }

    fun deleteLocation(id: Long) {
        viewModelScope.launch {
            repository.deleteLocation(id)
        }
    }
}
