package com.ponzischeme89.memby.ui

import com.ponzischeme89.memby.data.model.BaseItem
import com.ponzischeme89.memby.data.model.UserItemData
import com.ponzischeme89.memby.ui.detail.availableSeasons
import com.ponzischeme89.memby.ui.detail.defaultSeason
import com.ponzischeme89.memby.ui.detail.episodesForSeason
import com.ponzischeme89.memby.ui.detail.nextEpisodeToWatch
import com.ponzischeme89.memby.ui.detail.primaryActionLabel
import com.ponzischeme89.memby.ui.detail.seasonLabel
import org.junit.Assert.assertEquals
import org.junit.Test

class SeriesDetailsTest {
    private fun episode(
        id: String,
        season: Int,
        number: Int,
        played: Boolean = false,
        resumeTicks: Long = 0,
    ) = BaseItem(
        id = id,
        name = "Episode $number",
        type = "Episode",
        parentIndexNumber = season,
        indexNumber = number,
        userData = UserItemData(played = played, playbackPositionTicks = resumeTicks),
    )

    @Test
    fun `seasons are distinct and ordered with specials first`() {
        val episodes = listOf(
            episode("s2e1", 2, 1),
            episode("s0e1", 0, 1),
            episode("s1e1", 1, 1),
            episode("s2e2", 2, 2),
        )

        assertEquals(listOf(0, 1, 2), availableSeasons(episodes))
    }

    @Test
    fun `season list is ordered by episode number`() {
        val episodes = listOf(
            episode("e3", 1, 3),
            episode("e1", 1, 1),
            episode("e2", 1, 2),
        )

        assertEquals(listOf("e1", "e2", "e3"), episodesForSeason(episodes, 1).map(BaseItem::id))
    }

    @Test
    fun `default season contains the first unwatched episode`() {
        val episodes = listOf(
            episode("s1e1", 1, 1, played = true),
            episode("s1e2", 1, 2, played = true),
            episode("s2e1", 2, 1),
        )

        assertEquals(2, defaultSeason(episodes))
    }

    @Test
    fun `an old resume marker does not pull schedule playback behind later progress`() {
        val episodes = (1..7).map { number ->
            episode(
                id = "s3e$number",
                season = 3,
                number = number,
                played = number in 2..6,
                resumeTicks = when (number) {
                    1 -> 60_000_000L
                    7 -> 120_000_000L
                    else -> 0L
                },
            )
        }

        val next = requireNotNull(nextEpisodeToWatch(episodes))

        assertEquals("s3e7", next.id)
        assertEquals("Resume S03E07", primaryActionLabel(
            BaseItem(id = "series", name = "Series", type = "Series"),
            next,
        ))
    }

    @Test
    fun `season zero is labelled specials`() {
        assertEquals("Specials", seasonLabel(0))
        assertEquals("Season 3", seasonLabel(3))
    }
}
