package com.placeholder.sherpai2.ui.utilities.stats

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.placeholder.sherpai2.data.local.dao.*
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * StatsViewModel - Photo collection statistics
 *
 * Features:
 * 1. Photo count timeline (daily/monthly/yearly)
 * 2. Year-by-year breakdown
 * 3. System tag statistics
 * 4. Burst detection stats
 * 5. Usage patterns (day of week, hour of day)
 */
@HiltViewModel
class StatsViewModel @Inject constructor(
    private val imageDao: ImageDao,
    private val tagDao: TagDao,
    private val imageTagDao: ImageTagDao,
    private val personDao: PersonDao,
    private val photoFaceTagDao: PhotoFaceTagDao
) : ViewModel() {

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

    private val _timelineGranularity = MutableStateFlow(TimelineGranularity.MONTHLY)
    val timelineGranularity: StateFlow<TimelineGranularity> = _timelineGranularity.asStateFlow()

    init {
        loadStats()
    }

    fun loadStats() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                _uiState.value = StatsUiState.Loading

                // Load all stats in parallel
                val totalCount = imageDao.getImageCount()
                val yearCounts = imageDao.getPhotoCountsByYear()
                val monthlyCounts = imageDao.getPhotoCountsByMonth()
                val dailyCounts = imageDao.getPhotoCountsByDate()
                val systemTagStats = tagDao.getSystemTagStats()
                val burstStats = imageTagDao.getBurstStats()
                val dateRange = imageDao.getPhotoDateRange()
                val avgPerDay = imageDao.getAveragePhotosPerDay()
                val dayOfWeekCounts = imageDao.getPhotoCountsByDayOfWeek()
                val hourCounts = imageDao.getPhotoCountsByHour()

                // Face recognition stats
                val personCount = personDao.getPersonCount()
                val taggedFaceCount = photoFaceTagDao.getUnverifiedTagCount()

                _uiState.value = StatsUiState.Success(
                    totalPhotos = totalCount,
                    yearCounts = yearCounts,
                    monthlyCounts = monthlyCounts,
                    dailyCounts = dailyCounts,
                    systemTagStats = systemTagStats,
                    burstStats = burstStats,
                    dateRange = dateRange,
                    averagePerDay = avgPerDay ?: 0f,
                    dayOfWeekCounts = dayOfWeekCounts,
                    hourCounts = hourCounts,
                    personCount = personCount,
                    taggedFaceCount = taggedFaceCount
                )

            } catch (e: Exception) {
                _uiState.value = StatsUiState.Error(
                    e.message ?: "Failed to load statistics"
                )
            }
        }
    }

    fun setTimelineGranularity(granularity: TimelineGranularity) {
        _timelineGranularity.value = granularity
    }

    fun refresh() {
        loadStats()
    }
}

/**
 * UI State for stats screen
 */
sealed class StatsUiState {
    object Loading : StatsUiState()

    data class Success(
        val totalPhotos: Int,
        val yearCounts: List<YearCount>,
        val monthlyCounts: List<MonthCount>,
        val dailyCounts: List<DateCount>,
        val systemTagStats: List<TagStat>,
        val burstStats: BurstStats?,
        val dateRange: PhotoDateRange?,
        val averagePerDay: Float,
        val dayOfWeekCounts: List<DayOfWeekCount>,
        val hourCounts: List<HourCount>,
        val personCount: Int,
        val taggedFaceCount: Int
    ) : StatsUiState()

    data class Error(val message: String) : StatsUiState()
}

/**
 * Timeline granularity options
 */
enum class TimelineGranularity {
    DAILY,
    MONTHLY,
    YEARLY
}