package dev.privacyllc.period.core.notifications

import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId

/**
 * The arithmetic behind "wake me at ten".
 *
 * Off by a day here means somebody's first reminder arrives tomorrow instead of
 * today — the kind of thing nobody notices until they are the user with the
 * missed period.
 */
class ReminderSchedulerTest {

    private val zone = ZoneId.of("UTC")

    @Test fun `a time later today waits until today`() {
        val now = LocalDateTime.of(2026, 8, 18, 8, 0)
        val d = ReminderScheduler.delayUntil(LocalTime.of(10, 0), zone, now)
        assertEquals(120, d.toMinutes())
        assertEquals(LocalDate.of(2026, 8, 18), ReminderScheduler.nextRunDate(LocalTime.of(10, 0), now))
    }

    @Test fun `a time already past today waits until tomorrow`() {
        val now = LocalDateTime.of(2026, 8, 18, 11, 0)
        val d = ReminderScheduler.delayUntil(LocalTime.of(10, 0), zone, now)
        assertEquals(23 * 60, d.toMinutes())
        assertEquals(LocalDate.of(2026, 8, 19), ReminderScheduler.nextRunDate(LocalTime.of(10, 0), now))
    }

    @Test fun `the exact minute counts as past, not now`() {
        // Scheduling a zero delay for "right now" fires immediately and then
        // again in 24 hours, which is two reminders on the first day.
        val now = LocalDateTime.of(2026, 8, 18, 10, 0)
        assertEquals(24 * 60, ReminderScheduler.delayUntil(LocalTime.of(10, 0), zone, now).toMinutes())
    }

    @Test fun `the delay is never negative and never beyond a day`() {
        listOf(LocalTime.MIDNIGHT, LocalTime.of(6, 30), LocalTime.of(23, 59)).forEach { target ->
            (0..23).forEach { hour ->
                val now = LocalDateTime.of(2026, 8, 18, hour, 17)
                val minutes = ReminderScheduler.delayUntil(target, zone, now).toMinutes()
                assertTrue("$target at $hour gave $minutes", minutes in 0..(24 * 60))
            }
        }
    }
}
