package com.ponzischeme89.memby.ui

import com.ponzischeme89.memby.data.model.BaseItem
import com.ponzischeme89.memby.ui.detail.airingNoticeFor
import com.ponzischeme89.memby.ui.detail.scheduleSeriesStub
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test

class AiringNoticeTest {
    private fun card(
        availability: String = "upcoming",
        availabilityText: String = "Upcoming",
        dayLabel: String = "Tomorrow",
        airLabel: String = "Tomorrow: 9:00 PM",
        source: String? = "sonarr",
        seriesItemId: String? = "emby-42",
    ) = BaseItem(
        id = "sonarr:7:42",
        name = "Northbound",
        type = "MembySonarrEpisode",
        genres = listOf("Drama"),
        productionYear = 2024,
        membySource = source,
        membyEpisodeTitle = "The Crossing",
        membyEpisodeCode = "S02E04",
        membyAirDayLabel = dayLabel,
        membyAirLabel = airLabel,
        membyAvailability = availability,
        membyAvailabilityText = availabilityText,
        membyPlayable = false,
        membySeriesItemId = seriesItemId,
    )

    @Test
    fun `notice names the episode and repeats the card's own wording`() {
        val notice = requireNotNull(airingNoticeFor(card()))

        assertEquals("AIRING TOMORROW", notice.label)
        assertTrue(notice.headline.startsWith("S02E04"))
        assertTrue(notice.headline.endsWith("The Crossing"))
        assertTrue(notice.detail.contains("Tomorrow: 9:00 PM"))
        assertTrue(notice.detail.contains("Upcoming"))
    }

    @Test
    fun `an episode already on the server is not announced as airing`() {
        val notice = requireNotNull(
            airingNoticeFor(
                card(
                    availability = "available",
                    availabilityText = "Added at 8:12 PM",
                    dayLabel = "Today",
                    airLabel = "Aired today at 8:00 PM",
                ),
            ),
        )

        assertEquals("NEW EPISODE READY", notice.label)
    }

    @Test
    fun `an episode that has aired but not landed says so`() {
        val notice = requireNotNull(
            airingNoticeFor(
                card(
                    availability = "awaiting",
                    availabilityText = "Awaiting download",
                    dayLabel = "Today",
                    airLabel = "Aired today at 8:00 PM",
                ),
            ),
        )

        assertEquals("AIRED TODAY", notice.label)
    }

    @Test
    fun `an air time the gateway could not date is not given one`() {
        val notice = requireNotNull(
            airingNoticeFor(card(dayLabel = "Upcoming", airLabel = "Coming up")),
        )

        assertEquals("UPCOMING EPISODE", notice.label)
    }

    @Test
    fun `only schedule cards carry a notice`() {
        assertNull(airingNoticeFor(card(source = null)))
        assertNull(airingNoticeFor(card(source = "radarr")))
        assertNull(airingNoticeFor(BaseItem(id = "series", name = "Northbound", type = "Series")))
    }

    @Test
    fun `a card with nothing to say produces no notice`() {
        val silent = BaseItem(
            id = "sonarr:7:42",
            name = "Northbound",
            type = "MembySonarrEpisode",
            membySource = "sonarr",
        )

        assertNull(airingNoticeFor(silent))
    }

    @Test
    fun `the stub opens the show, not the episode that was pressed`() {
        val stub = requireNotNull(scheduleSeriesStub(card()))

        assertEquals("emby-42", stub.id)
        assertEquals("Northbound", stub.name)
        assertTrue(stub.isSeries)
        assertEquals(listOf("Drama"), stub.genres)
        // The card's overview is the *episode's*; the page it opens is about the show.
        assertNull(stub.overview)
    }

    @Test
    fun `a show Emby has never imported opens nothing`() {
        assertNull(scheduleSeriesStub(card(seriesItemId = null)))
        assertNull(scheduleSeriesStub(card(seriesItemId = "  ")))
        assertNull(scheduleSeriesStub(BaseItem(id = "movie", name = "Film", type = "Movie")))
    }
}
