package com.ponzischeme89.memby.ui.genre

import com.ponzischeme89.memby.data.model.BaseItem
import com.ponzischeme89.memby.data.model.UserItemData

/**
 * A stable, human-sized genre catalogue.
 *
 * Emby libraries tend to describe the same shelf with several neighbouring labels
 * (Action and Adventure, Science Fiction and Sci-Fi, Family and Animation). Presenting
 * every raw label makes the picker long and unpredictable, so the television exposes a
 * fixed set of useful categories and sends their pipe-delimited Emby genres as one OR
 * filter. The order is product design, not server data, and therefore never jumps around
 * while home rows are arriving.
 */
data class GenreCategory(
    val id: String,
    val label: String,
    val genres: List<String>,
    val icon: GenreCategoryIcon,
) {
    val filter: String get() = genres.joinToString("|")
}

enum class GenreCategoryIcon {
    ALL,
    ACTION,
    COMEDY,
    CRIME,
    DRAMA,
    HORROR,
    MYSTERY,
    SCI_FI,
    THRILLER,
    WAR,
    FAMILY,
    DOCUMENTARY,
    ROMANCE,
    WESTERN,
    MUSIC,
    SPORT,
    REALITY,
}

const val ALL_MEDIA_CATEGORY_ID = "all"

private val allMediaCategory = GenreCategory(
    id = ALL_MEDIA_CATEGORY_ID,
    label = "All",
    genres = emptyList(),
    icon = GenreCategoryIcon.ALL,
)

private val coreGenreCategories = listOf(
    GenreCategory("action-adventure", "Action & Adventure", listOf("Action", "Adventure"), GenreCategoryIcon.ACTION),
    GenreCategory("comedy", "Comedy", listOf("Comedy"), GenreCategoryIcon.COMEDY),
    GenreCategory("crime", "Crime", listOf("Crime", "Film-Noir"), GenreCategoryIcon.CRIME),
    GenreCategory("drama", "Drama", listOf("Drama"), GenreCategoryIcon.DRAMA),
    GenreCategory("horror", "Horror", listOf("Horror"), GenreCategoryIcon.HORROR),
    GenreCategory("mystery", "Mystery", listOf("Mystery"), GenreCategoryIcon.MYSTERY),
    GenreCategory(
        "sci-fi-fantasy",
        "Sci-Fi & Fantasy",
        listOf("Science Fiction", "Sci-Fi", "Sci Fi", "Fantasy"),
        GenreCategoryIcon.SCI_FI,
    ),
    GenreCategory("thriller", "Thriller", listOf("Thriller", "Suspense"), GenreCategoryIcon.THRILLER),
    GenreCategory("war-history", "War & History", listOf("War", "History"), GenreCategoryIcon.WAR),
    GenreCategory(
        "family-animation",
        "Family & Animation",
        listOf("Family", "Animation", "Children", "Kids"),
        GenreCategoryIcon.FAMILY,
    ),
    GenreCategory("documentary", "Documentary", listOf("Documentary"), GenreCategoryIcon.DOCUMENTARY),
    GenreCategory("romance", "Romance", listOf("Romance"), GenreCategoryIcon.ROMANCE),
    GenreCategory("western", "Western", listOf("Western"), GenreCategoryIcon.WESTERN),
    GenreCategory("music-musicals", "Music & Musicals", listOf("Music", "Musical"), GenreCategoryIcon.MUSIC),
    GenreCategory("sport", "Sport", listOf("Sport", "Sports"), GenreCategoryIcon.SPORT),
)

private val realityCategory = GenreCategory(
    "reality",
    "Reality TV",
    listOf("Reality", "Reality TV"),
    GenreCategoryIcon.REALITY,
)

fun genreCategories(itemType: String): List<GenreCategory> =
    if (itemType.equals("Series", ignoreCase = true)) coreGenreCategories + realityCategory
    else coreGenreCategories

fun genreCategoryTabs(itemType: String): List<GenreCategory> =
    listOf(allMediaCategory.copy(label = allMediaLabel(itemType))) + genreCategories(itemType)

fun genreCategory(itemType: String, id: String?): GenreCategory =
    genreCategoryTabs(itemType).firstOrNull { it.id == id } ?: genreCategoryTabs(itemType).first()

fun allMediaLabel(itemType: String): String =
    if (itemType.equals("Series", ignoreCase = true)) "All TV shows" else "All Movies"

fun BaseItem.withFavourite(favourite: Boolean): BaseItem = copy(
    userData = (userData ?: UserItemData()).copy(isFavorite = favourite),
)

fun BaseItem.withPlayed(played: Boolean): BaseItem = copy(
    userData = (userData ?: UserItemData()).copy(
        played = played,
        playbackPositionTicks = if (played) 0L else userData?.playbackPositionTicks ?: 0L,
    ),
)
