package com.vgmlr.kiln
import androidx.compose.ui.graphics.Color
import java.time.LocalDate
import java.time.temporal.ChronoUnit
import kotlin.math.roundToInt
object KilnGradientPalette {
const val PRE_MENSTRUAL_BUCKET = 2
fun hueFor(date: LocalDate, lastStart: LocalDate?, cycle: Int, moodShift: Float = 0f): Float {
if (lastStart == null) return 120f
val phase = Math.floorMod(
ChronoUnit.DAYS.between(lastStart, date), cycle.toLong()
).toFloat()
val greenPeak = 7f
val redStart = (cycle - 6f).coerceAtLeast(greenPeak)
val redEnd = cycle - 1f
val base = when {
phase in greenPeak..redStart ->
120f * (1f - (phase - greenPeak) / (redStart - greenPeak))
phase > redStart && phase < redEnd -> 0f
else -> {
val fromRed = if (phase >= redEnd) phase - redEnd else phase + (cycle - redEnd)
120f * (fromRed / ((cycle - redEnd) + greenPeak))
}
}
return (base + moodShift).coerceIn(0f, 120f)
}
fun colorFor(hue: Float): Color = Color.hsv(hue, 0.50f, 0.95f)
fun bucket(hue: Float): Int = ((hue / 120f) * 7f).roundToInt().coerceIn(0, 7)
fun isPreMenstrual(hue: Float): Boolean = bucket(hue) <= PRE_MENSTRUAL_BUCKET
fun lookup(
records: List<KilnDayRecord>,
buttons: KilnButtonSet,
starts: List<LocalDate>,
cycle: Int
): (LocalDate) -> Float = { date ->
val last = starts.lastOrNull { !it.isAfter(date) } ?: starts.firstOrNull()
hueFor(date, last, cycle, KilnMoodInfluence.hueShift(records, buttons, starts, cycle, date))
}
fun bucketToday(records: List<KilnDayRecord>, buttons: KilnButtonSet, today: LocalDate): Int {
val starts = KilnCyclePredictor.periodStarts(records, buttons)
val cycle = KilnCyclePredictor.avgCycleLength(starts)
return bucket(lookup(records, buttons, starts, cycle)(today))
}
}