package de.trainingstagebuch.app.utils

import de.trainingstagebuch.app.repository.TrainingDayStatsItem
import java.time.LocalDate
import java.time.format.TextStyle
import java.util.Locale

object TrainingStatsMetrics {
    enum class Period {
        CurrentMonth,
        LastMonth,
        QuarterWithMostTrainings,
        HalfYear,
        Year
    }

    fun averageParticipation(days: List<TrainingDayStatsItem>, period: Period, now: LocalDate = LocalDate.now()): Double {
        if (days.isEmpty()) return 0.0
        val filtered = filterForPeriod(days, period, now)
        if (filtered.isEmpty()) return 0.0
        val totalParticipants = filtered.sumOf { it.participantCount }
        return totalParticipants.toDouble() / filtered.size.toDouble()
    }

    fun weekdayLabel(date: String?, locale: Locale = Locale.GERMAN): String {
        val parsed = parseDate(date) ?: return "-"
        return parsed.dayOfWeek.getDisplayName(TextStyle.FULL, locale)
    }

    fun parseDate(date: String?): LocalDate? {
        if (date.isNullOrBlank()) return null
        return DateTimeUtils.parseIsoDateOrNull(date.take(10))
    }

    private fun filterForPeriod(
        days: List<TrainingDayStatsItem>,
        period: Period,
        now: LocalDate
    ): List<TrainingDayStatsItem> {
        return when (period) {
            Period.CurrentMonth -> days.filter { day ->
                val date = parseDate(day.date) ?: return@filter false
                date.year == now.year && date.monthValue == now.monthValue
            }

            Period.LastMonth -> {
                val last = now.minusMonths(1)
                days.filter { day ->
                    val date = parseDate(day.date) ?: return@filter false
                    date.year == last.year && date.monthValue == last.monthValue
                }
            }

            Period.QuarterWithMostTrainings -> {
                val grouped = days.mapNotNull { day ->
                    val date = parseDate(day.date) ?: return@mapNotNull null
                    val quarter = (date.monthValue - 1) / 3
                    Triple(date.year, quarter, day)
                }.groupBy { (year, quarter, _) -> "$year-$quarter" }
                val best = grouped.maxByOrNull { it.value.size }?.key ?: return emptyList()
                grouped[best].orEmpty().map { it.third }
            }

            Period.HalfYear -> {
                val start = now.minusMonths(6)
                days.filter { day ->
                    val date = parseDate(day.date) ?: return@filter false
                    !date.isBefore(start) && !date.isAfter(now)
                }
            }

            Period.Year -> days.filter { day ->
                val date = parseDate(day.date) ?: return@filter false
                date.year == now.year
            }
        }
    }
}
