package dev.privacyllc.period.domain.cycle

import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import java.time.LocalDate

class CycleTest {

    private fun starts(vararg dates: String) = dates.mapIndexed { i, d ->
        PeriodRecord(id = i.toLong(), startDate = LocalDate.parse(d))
    }

    @Test
    fun `intervals are the gaps between consecutive starts`() {
        val cycles = starts("2026-01-01", "2026-01-30", "2026-02-27").toCycles()
        assertEquals(listOf(29, 28), cycles.map { it.cycleLengthDays })
    }

    @Test
    fun `records out of order still produce ascending cycles`() {
        val cycles = starts("2026-02-27", "2026-01-01", "2026-01-30").toCycles()
        assertEquals(listOf(29, 28), cycles.map { it.cycleLengthDays })
    }

    @Test
    fun `a duplicate start date does not produce a zero-length cycle`() {
        val cycles = starts("2026-01-01", "2026-01-01", "2026-01-30").toCycles()
        assertEquals(listOf(29), cycles.map { it.cycleLengthDays })
        assertTrue(cycles.none { it.cycleLengthDays == 0 })
    }

    @Test
    fun `unconfirmed records are not cycle boundaries`() {
        val records = starts("2026-01-01", "2026-01-15", "2026-01-30")
            .mapIndexed { i, r -> if (i == 1) r.copy(isConfirmed = false) else r }
        assertEquals(listOf(29), records.toCycles().map { it.cycleLengthDays })
    }

    @Test
    fun `fewer than two starts is no cycles rather than an error`() {
        assertTrue(starts("2026-01-01").toCycles().isEmpty())
        assertTrue(emptyList<PeriodRecord>().toCycles().isEmpty())
    }
}
