package com.ponzischeme89.memby.ui.detail

import com.ponzischeme89.memby.data.model.BaseItem
import com.ponzischeme89.memby.ui.theme.FactSeparator
import java.util.Locale

/**
 * What a detail page says when it was opened from the "Shows airing in the next 5 days"
 * row: which episode is due, and when.
 *
 * It exists because that row's cards stand for an *episode* while the page they open is
 * the *show*. Without it the viewer picks "Thursday, 9pm" from the launcher and arrives at
 * a page that says nothing about Thursday. It is deliberately a property of the route
 * taken, not of the show — the same page reached from Favourites or a search carries no
 * notice, because nothing there promised one.
 *
 * Every field is wording the gateway already authored ([BaseItem.membyAirLabel] and
 * friends), so the TV never computes an air time from a timestamp and can never contradict
 * the card the viewer just pressed.
 */
data class AiringNotice(
    /** The eyebrow: "AIRING TOMORROW", "AIRED TODAY", "NEW EPISODE READY". */
    val label: String,
    /** "S03E04 • The Crossing", or empty when Sonarr named neither. */
    val headline: String,
    /** "In 8 hours (4:00 PM) • Awaiting download". */
    val detail: String,
)

/**
 * The notice for a schedule card, or null for anything else — including a movie-schedule
 * card, which has no episode to announce and opens no series page.
 */
fun airingNoticeFor(item: BaseItem): AiringNotice? {
    if (!item.isTvSchedule) return null
    val day = item.membyAirDayLabel?.trim().orEmpty()
    val airLabel = item.membyAirLabel?.trim().orEmpty()
    val availability = item.membyAvailabilityText?.trim().orEmpty()
    val headline = listOfNotNull(
        item.membyEpisodeCode?.trim()?.takeIf(String::isNotEmpty),
        item.membyEpisodeTitle?.trim()?.takeIf(String::isNotEmpty),
    ).joinToString(FactSeparator)
    val detail = listOf(airLabel, availability)
        .filter(String::isNotEmpty)
        .joinToString(FactSeparator)
    // A notice with nothing to say is worse than none: it would claim a schedule the page
    // cannot name.
    if (headline.isEmpty() && detail.isEmpty()) return null
    return AiringNotice(label = airingNoticeLabel(day, airLabel, item.membyAvailability), headline, detail)
}

/**
 * The Emby series a schedule card stands for, as much of it as the card itself knows, or
 * null when the library has never imported the show.
 *
 * The page opens on this and fills in from Emby a moment later, the same way the launcher
 * draws its cached rows before the network answers — waiting on one item request before
 * anything appears is the one thing that would make the row feel broken. The episode's own
 * overview and artwork are deliberately left behind: they belong to the episode, and the
 * page this becomes is about the show.
 */
fun scheduleSeriesStub(card: BaseItem): BaseItem? {
    if (!card.isTvSchedule) return null
    val seriesId = card.membySeriesItemId?.trim()?.takeIf(String::isNotEmpty) ?: return null
    return BaseItem(
        id = seriesId,
        name = card.name,
        type = "Series",
        genres = card.genres,
        productionYear = card.productionYear,
    )
}

private fun airingNoticeLabel(day: String, airLabel: String, availability: String?): String = when {
    // The episode is already on the server, so "airing" would send someone to wait for
    // something they could watch now.
    availability == "available" -> "NEW EPISODE READY"
    airLabel.startsWith("Aired", ignoreCase = true) ->
        "AIRED ${day.ifEmpty { "TODAY" }.uppercase(Locale.ROOT)}"
    day.isEmpty() || day.equals("Upcoming", ignoreCase = true) -> "UPCOMING EPISODE"
    else -> "AIRING ${day.uppercase(Locale.ROOT)}"
}
