package dev.castarr.tv.data

import androidx.compose.ui.graphics.Color

/**
 * Per-club shortcut to "where does my club play tonight": a rail entry that
 * lists every channel whose EPG mentions the club within the next few hours.
 * Crests are fetched from Wikipedia at runtime and cached on the device;
 * the club colours are the fallback while that is pending or unavailable.
 */
data class TeamFilter(
    val key: String,
    /** Short caption next to the crest in the rail. */
    val label: String,
    /** Full club name, shown in the settings and in messages. */
    val fullName: String,
    /** Lowercase needles matched against programme titles. */
    val needles: List<String>,
    val primary: Color,
    val secondary: Color,
    /** German Wikipedia article the crest is resolved from. */
    val article: String,
) {
    fun matches(title: String): Boolean {
        val haystack = title.lowercase()
        return needles.any { haystack.contains(it) }
    }
}

object TeamFilters {

    /** Minimum window scanned ahead of now. */
    const val MIN_WINDOW_MS = 3 * 60 * 60 * 1000L

    /**
     * Scans until midnight, but never less than [MIN_WINDOW_MS] — asking in
     * the morning should already answer "does my club play tonight", and
     * asking late at night must not cut the evening short.
     */
    fun windowEnd(now: Long): Long {
        val midnight = java.util.Calendar.getInstance().apply {
            timeInMillis = now
            add(java.util.Calendar.DAY_OF_YEAR, 1)
            set(java.util.Calendar.HOUR_OF_DAY, 0)
            set(java.util.Calendar.MINUTE, 0)
            set(java.util.Calendar.SECOND, 0)
            set(java.util.Calendar.MILLISECOND, 0)
        }.timeInMillis
        return maxOf(midnight, now + MIN_WINDOW_MS)
    }

    /** At most this many club groups sit in the rail at once. */
    const val MAX_ACTIVE = 3

    private const val WHITE = 0xFFF2F3F5
    private const val BLACK = 0xFF15171B

    private fun club(
        key: String,
        label: String,
        fullName: String,
        needles: List<String>,
        primary: Long,
        secondary: Long,
        article: String = fullName,
    ) = TeamFilter(key, label, fullName, needles, Color(primary), Color(secondary), article)

    /** Clubs of the top three German divisions. */
    val all: List<TeamFilter> = listOf(
        // --- Bundesliga ---
        club("bayern", "FCB", "FC Bayern München", listOf("bayern münchen", "fc bayern"), 0xFFDC052D, WHITE),
        club("bvb", "BVB", "Borussia Dortmund", listOf("borussia dortmund", "bvb"), 0xFFFDE100, BLACK),
        club("leipzig", "RBL", "RB Leipzig", listOf("rb leipzig"), 0xFFDD0741, WHITE),
        club("leverkusen", "B04", "Bayer 04 Leverkusen", listOf("leverkusen"), 0xFFE32219, BLACK),
        club("frankfurt", "SGE", "Eintracht Frankfurt", listOf("eintracht frankfurt"), 0xFF1A1A1A, 0xFFE1000F),
        club("stuttgart", "1893", "VfB Stuttgart", listOf("vfb stuttgart"), 0xFFE32219, WHITE),
        club("gladbach", "BMG", "Borussia Mönchengladbach", listOf("mönchengladbach", "gladbach"), 0xFF1A1A1A, 0xFF00A94F),
        club("wolfsburg", "WOB", "VfL Wolfsburg", listOf("wolfsburg"), 0xFF65B32E, WHITE),
        club("bremen", "SVW", "SV Werder Bremen", listOf("werder bremen", "werder"), 0xFF1D9053, WHITE),
        club("freiburg", "SCF", "SC Freiburg", listOf("sc freiburg", "freiburg"), 0xFFE2001A, WHITE),
        club("hoffenheim", "TSG", "TSG Hoffenheim", listOf("hoffenheim"), 0xFF1C63B7, WHITE),
        club("mainz", "M05", "1. FSV Mainz 05", listOf("mainz 05", "mainz"), 0xFFE1000F, WHITE),
        club("augsburg", "FCA", "FC Augsburg", listOf("augsburg"), 0xFF00693F, 0xFFE1000F),
        club("union", "FCU", "1. FC Union Berlin", listOf("union berlin"), 0xFFE1000F, 0xFFFDE100),
        club("koeln", "EFC", "1. FC Köln", listOf("1. fc köln", "fc köln"), 0xFFE1000F, WHITE),
        club("hsv", "HSV", "Hamburger SV", listOf("hamburger sv", "hsv"), 0xFF0E5EA6, BLACK),
        club("heidenheim", "FCH1", "1. FC Heidenheim", listOf("heidenheim"), 0xFFE1000F, 0xFF1656A4),
        club("st-pauli", "FCSP", "FC St. Pauli", listOf("st. pauli", "st pauli"), 0xFF6B4423, WHITE),
        // --- 2. Bundesliga ---
        club("schalke", "S04", "FC Schalke 04", listOf("schalke"), 0xFF004D9D, WHITE),
        club("hertha", "BSC", "Hertha BSC", listOf("hertha"), 0xFF004D9D, WHITE),
        club("duesseldorf", "F95", "Fortuna Düsseldorf", listOf("fortuna düsseldorf"), 0xFFE1000F, WHITE),
        club("nuernberg", "FCN", "1. FC Nürnberg", listOf("nürnberg"), 0xFF8B1A1A, WHITE),
        club("kaiserslautern", "FCK", "1. FC Kaiserslautern", listOf("kaiserslautern"), 0xFFE1000F, WHITE),
        club("karlsruhe", "KSC", "Karlsruher SC", listOf("karlsruher sc", "ksc"), 0xFF0055A5, WHITE),
        club("hannover", "H96", "Hannover 96", listOf("hannover 96"), 0xFF00A94F, WHITE),
        club("paderborn", "SCP", "SC Paderborn 07", listOf("paderborn"), 0xFF004D9D, WHITE),
        club("magdeburg", "FCM", "1. FC Magdeburg", listOf("magdeburg"), 0xFF0B7A3E, WHITE),
        club("elversberg", "SVE", "SV Elversberg", listOf("elversberg"), 0xFF1A1A1A, 0xFFE1000F),
        club("darmstadt", "SV98", "SV Darmstadt 98", listOf("darmstadt"), 0xFF004E9E, WHITE),
        club("braunschweig", "BTSV", "Eintracht Braunschweig", listOf("braunschweig"), 0xFFFDE100, 0xFF004E9E),
        club("bochum", "BOC", "VfL Bochum", listOf("bochum"), 0xFF005CA9, WHITE),
        club("muenster", "SCPM", "Preußen Münster", listOf("preußen münster", "münster"), 0xFF00703C, WHITE),
        club("fuerth", "SGF", "SpVgg Greuther Fürth", listOf("greuther fürth", "fürth"), 0xFF00A94F, WHITE),
        club("holstein", "KSV", "Holstein Kiel", listOf("holstein kiel"), 0xFF004E9E, 0xFFE1000F),
        club("dresden", "SGD", "Dynamo Dresden", listOf("dynamo dresden"), 0xFFFDE100, BLACK),
        club("bielefeld", "DSC", "Arminia Bielefeld", listOf("arminia bielefeld", "bielefeld"), 0xFF00539F, WHITE),
        // --- 3. Liga ---
        club("hansa", "FCH", "FC Hansa Rostock", listOf("hansa"), 0xFF0B4EA2, WHITE),
        club("saarbruecken", "FCS", "1. FC Saarbrücken", listOf("saarbrücken"), 0xFF0B4EA2, BLACK),
        club("aue", "FCE", "Erzgebirge Aue", listOf("erzgebirge aue"), 0xFF7C0A02, WHITE),
        club("cottbus", "FCEC", "Energie Cottbus", listOf("energie cottbus", "cottbus"), 0xFFE1000F, WHITE),
        club("essen", "RWE", "Rot-Weiss Essen", listOf("rot-weiss essen", "rot weiss essen"), 0xFFE1000F, WHITE),
        club("duisburg", "MSV", "MSV Duisburg", listOf("msv duisburg", "duisburg"), 0xFF004E9E, WHITE),
        club("mannheim", "SVWM", "SV Waldhof Mannheim", listOf("waldhof mannheim", "waldhof"), 0xFF0B4EA2, WHITE),
        club("wehen", "SVWW", "SV Wehen Wiesbaden", listOf("wehen wiesbaden", "wehen"), 0xFFE1000F, BLACK),
        club("ulm", "SSV", "SSV Ulm 1846", listOf("ssv ulm"), 0xFFE1000F, WHITE, article = "SSV Ulm 1846 Fußball"),
        club("regensburg", "SSVJ", "SSV Jahn Regensburg", listOf("jahn regensburg", "regensburg"), 0xFFE1000F, WHITE),
        club("verl", "SCV", "SC Verl", listOf("sc verl"), 0xFF00703C, WHITE),
        club("viktoria", "VKÖ", "Viktoria Köln", listOf("viktoria köln"), 0xFFE1000F, WHITE),
        club("havelse", "TSVH", "TSV Havelse", listOf("havelse"), 0xFF004E9E, WHITE),
        club("schweinfurt", "FC05", "1. FC Schweinfurt 05", listOf("schweinfurt"), 0xFF00A94F, WHITE),
        club("osnabrueck", "VfLO", "VfL Osnabrück", listOf("osnabrück"), 0xFF6A2C8F, WHITE),
        club("aachen", "ALE", "Alemannia Aachen", listOf("alemannia aachen", "aachen"), 0xFFFDE100, BLACK),
        club("ingolstadt", "FCI", "FC Ingolstadt 04", listOf("ingolstadt"), 0xFFE1000F, BLACK),
        club("wuppertal", "WSV", "Wuppertaler SV", listOf("wuppertaler sv"), 0xFFE1000F, 0xFF0B4EA2),
        club("stuttgart-ii", "VfB2", "VfB Stuttgart II", listOf("vfb stuttgart ii"), 0xFFE32219, BLACK),
        club("hoffenheim-ii", "TSG2", "TSG Hoffenheim II", listOf("hoffenheim ii"), 0xFF1C63B7, BLACK, article = "TSG 1899 Hoffenheim"),
    )

    /** Clubs switched on for a viewer before they touch the settings. */
    private val defaultForUser = mapOf(
        "benjamin" to listOf("hansa"),
        "tobiasb" to listOf("stuttgart"),
    )

    /**
     * Only sport and free-to-air groups are scanned. Searching all 500
     * channels would mostly turn up shopping and radio, and the club is
     * never on those anyway.
     */
    private val groupIncludes = listOf(
        "sport", "dazn", "sky", "magenta", "prime", "free tv", "hd+",
        "dyn", "del", "bundesliga", "fussball", "fußball", "at / ch", "at/ch",
    )

    /** Explicitly out of scope even though they match an include. */
    private val groupExcludes = listOf("nfl")

    fun scansGroup(group: String): Boolean {
        val g = group.lowercase()
        if (groupExcludes.any { g.contains(it) }) return false
        return groupIncludes.any { g.contains(it) }
    }

    fun byKey(key: String): TeamFilter? = all.firstOrNull { it.key == key }

    fun defaultKeysFor(username: String): List<String> =
        defaultForUser[username.trim().lowercase()].orEmpty()
}
