package xyz.cottongin.radio247.data.db

import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase

/**
 * Seeds the database with all SomaFM stations on first creation.
 * Station data sourced from https://somafm.com/channels.json.
 * Sorted alphabetically by name; listener counts from a March 2026 snapshot.
 */
object SomaFmSeedData : RoomDatabase.Callback() {

    private data class SeedStation(
        val name: String,
        val streamId: String,
        val maxBitrate: Int,
        val artworkUrl: String,
        val listeners: Int
    ) {
        val has256: Boolean get() = maxBitrate >= 256
    }

    private val STATIONS = listOf(
        SeedStation("Beat Blender", "beatblender", 128, "https://api.somafm.com/logos/256/beatblender256.png", 162),
        SeedStation("Black Rock FM", "brfm", 128, "https://api.somafm.com/logos/256/brfm256.jpg", 14),
        SeedStation("Boot Liquor", "bootliquor", 320, "https://api.somafm.com/logos/256/bootliquor256.png", 73),
        SeedStation("Bossa Beyond", "bossa", 256, "https://api.somafm.com/logos/256/bossa-256.jpg", 84),
        SeedStation("Chillits Radio", "chillits", 256, "https://api.somafm.com/logos/256/chillits256.png", 6),
        SeedStation("Covers", "covers", 128, "https://api.somafm.com/logos/256/covers256.png", 37),
        SeedStation("DEF CON Radio", "defcon", 256, "https://api.somafm.com/logos/256/defcon256.png", 204),
        SeedStation("Deep Space One", "deepspaceone", 128, "https://api.somafm.com/logos/256/deepspaceone256.png", 457),
        SeedStation("Digitalis", "digitalis", 256, "https://api.somafm.com/logos/256/digitalis256.png", 39),
        SeedStation("Doomed", "doomed", 256, "https://api.somafm.com/logos/256/doomed256.png", 20),
        SeedStation("Drone Zone", "dronezone", 256, "https://api.somafm.com/logos/256/dronezone256.png", 1298),
        SeedStation("Dub Step Beyond", "dubstep", 256, "https://api.somafm.com/logos/256/dubstep256.png", 46),
        SeedStation("Fluid", "fluid", 128, "https://api.somafm.com/logos/256/fluid256.jpg", 68),
        SeedStation("Folk Forward", "folkfwd", 128, "https://api.somafm.com/logos/256/folkfwd256.png", 151),
        SeedStation("Groove Salad", "groovesalad", 256, "https://api.somafm.com/logos/256/groovesalad256.png", 1893),
        SeedStation("Groove Salad Classic", "gsclassic", 128, "https://api.somafm.com/logos/256/gsclassic256.jpg", 303),
        SeedStation("Heavyweight Reggae", "reggae", 256, "https://api.somafm.com/logos/256/reggae256.png", 69),
        SeedStation("Illinois Street Lounge", "illstreet", 128, "https://api.somafm.com/logos/256/illstreet256.jpg", 71),
        SeedStation("Indie Pop Rocks!", "indiepop", 128, "https://api.somafm.com/logos/256/indiepop256.png", 424),
        SeedStation("Left Coast 70s", "seventies", 320, "https://api.somafm.com/logos/256/seventies256.jpg", 226),
        SeedStation("Lush", "lush", 128, "https://api.somafm.com/logos/256/lush256.png", 299),
        SeedStation("Metal Detector", "metal", 128, "https://api.somafm.com/logos/256/metal256.png", 38),
        SeedStation("Mission Control", "missioncontrol", 128, "https://api.somafm.com/logos/256/missioncontrol256.png", 49),
        SeedStation("PopTron", "poptron", 128, "https://api.somafm.com/logos/256/poptron256.png", 103),
        SeedStation("SF 10-33", "sf1033", 128, "https://api.somafm.com/logos/256/sf1033256.png", 47),
        SeedStation("SF Police Scanner", "scanner", 128, "https://api.somafm.com/logos/256/scanner256.png", 14),
        SeedStation("SF in SF", "sfinsf", 128, "https://api.somafm.com/logos/256/sfinsf256.jpg", 3),
        SeedStation("Secret Agent", "secretagent", 128, "https://api.somafm.com/logos/256/secretagent256.png", 223),
        SeedStation("Seven Inch Soul", "7soul", 128, "https://api.somafm.com/logos/256/7soul256.png", 74),
        SeedStation("SomaFM Live", "live", 128, "https://api.somafm.com/logos/256/live256.png", 14),
        SeedStation("SomaFM Specials", "specials", 128, "https://api.somafm.com/logos/256/specials256.png", 18),
        SeedStation("Sonic Universe", "sonicuniverse", 256, "https://api.somafm.com/logos/256/sonicuniverse256.png", 92),
        SeedStation("Space Station Soma", "spacestation", 320, "https://api.somafm.com/logos/256/spacestation256.png", 386),
        SeedStation("Suburbs of Goa", "suburbsofgoa", 128, "https://api.somafm.com/logos/256/suburbsofgoa256.png", 84),
        SeedStation("Synphaera Radio", "synphaera", 256, "https://api.somafm.com/logos/256/synphaera256.jpg", 257),
        SeedStation("The Dark Zone", "darkzone", 256, "https://api.somafm.com/logos/256/darkzone256.jpg", 140),
        SeedStation("The In-Sound", "insound", 256, "https://api.somafm.com/logos/256/insound-256.jpg", 17),
        SeedStation("The Trip", "thetrip", 128, "https://api.somafm.com/logos/256/thetrip256.jpg", 98),
        SeedStation("ThistleRadio", "thistle", 128, "https://api.somafm.com/logos/256/thistle256.jpg", 52),
        SeedStation("Tiki Time", "tikitime", 256, "https://api.somafm.com/logos/256/tikitime256.jpg", 24),
        SeedStation("Underground 80s", "u80s", 256, "https://api.somafm.com/logos/256/u80s256.png", 243),
        SeedStation("Vaporwaves", "vaporwaves", 128, "https://api.somafm.com/logos/256/vaporwaves256.png", 55),
        SeedStation("cliqhop idm", "cliqhop", 256, "https://api.somafm.com/logos/256/cliqhop256.png", 55),
        SeedStation("n5MD Radio", "n5md", 128, "https://api.somafm.com/logos/256/n5md256.png", 25),
    )

    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        seedStations(db, includePinned = true)
    }

    /**
     * Inserts the SomaFM playlist and all stations.
     * @param includeIsHidden true for v3+ schema, false for MIGRATION_1_2.
     * @param includeStreams true for v4+ schema (fresh install), false otherwise.
     * @param includePinned true for v6+ schema (fresh install), false for migrations before MIGRATION_5_6.
     */
    fun seedStations(
        db: SupportSQLiteDatabase,
        includeIsHidden: Boolean = true,
        includeStreams: Boolean = true,
        includePinned: Boolean = false
    ) {
        val (pinnedCol, pinnedVal) = if (includePinned) ", pinned" to ", 1" else "" to ""
        db.execSQL(
            "INSERT INTO playlists (name, sortOrder, starred, isBuiltIn$pinnedCol) VALUES ('SomaFM', 0, 0, 1$pinnedVal)"
        )
        val cursor = db.query("SELECT last_insert_rowid()")
        cursor.moveToFirst()
        val playlistId = cursor.getLong(0)
        cursor.close()

        val qualityCol = if (includeStreams) ", qualityOverride" else ""
        val qualityVal = if (includeStreams) ", NULL" else ""

        STATIONS.forEachIndexed { index, station ->
            val url = "https://ice1.somafm.com/${station.streamId}-${station.maxBitrate}-mp3"
            val escapedName = station.name.replace("'", "''")
            if (includeIsHidden) {
                db.execSQL(
                    """INSERT INTO stations (name, url, playlistId, sortOrder, starred, defaultArtworkUrl, listenerCount, isHidden$qualityCol)
                       VALUES ('$escapedName', '$url', $playlistId, $index, 0, '${station.artworkUrl}', ${station.listeners}, 0$qualityVal)"""
                )
            } else {
                db.execSQL(
                    """INSERT INTO stations (name, url, playlistId, sortOrder, starred, defaultArtworkUrl, listenerCount)
                       VALUES ('$escapedName', '$url', $playlistId, $index, 0, '${station.artworkUrl}', ${station.listeners})"""
                )
            }

            if (includeStreams) {
                val stationCursor = db.query("SELECT last_insert_rowid()")
                stationCursor.moveToFirst()
                val stationId = stationCursor.getLong(0)
                stationCursor.close()
                insertStreamsForStation(db, stationId, station.streamId, station.has256)
            }
        }
    }

    /**
     * Seeds station_streams for SomaFM stations that already exist in the DB.
     * Used by MIGRATION_3_4 when upgrading from v3 to v4.
     */
    fun seedStreamsForExistingStations(db: SupportSQLiteDatabase) {
        STATIONS.forEach { seed ->
            val cursor = db.query(
                "SELECT id FROM stations WHERE url LIKE '%${seed.streamId}%' LIMIT 1"
            )
            if (cursor.moveToFirst()) {
                val stationId = cursor.getLong(0)
                insertStreamsForStation(db, stationId, seed.streamId, seed.has256)
            }
            cursor.close()
        }
    }

    private fun insertStreamsForStation(
        db: SupportSQLiteDatabase,
        stationId: Long,
        streamId: String,
        has256: Boolean
    ) {
        if (has256) {
            db.execSQL(
                "INSERT INTO station_streams (stationId, bitrate, ssl, url) VALUES ($stationId, 256, 1, 'https://ice1.somafm.com/$streamId-256-mp3')"
            )
            db.execSQL(
                "INSERT INTO station_streams (stationId, bitrate, ssl, url) VALUES ($stationId, 256, 0, 'http://ice1.somafm.com/$streamId-256-mp3')"
            )
        }
        db.execSQL(
            "INSERT INTO station_streams (stationId, bitrate, ssl, url) VALUES ($stationId, 128, 1, 'https://ice1.somafm.com/$streamId-128-mp3')"
        )
        db.execSQL(
            "INSERT INTO station_streams (stationId, bitrate, ssl, url) VALUES ($stationId, 128, 0, 'http://ice1.somafm.com/$streamId-128-mp3')"
        )
    }
}
