package de.krisenvorrat.app.data.db

import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

/**
 * Enthält alle Room-Migrationen der Krisenvorrat-Datenbank.
 *
 * Checkliste für jede neue Schema-Änderung:
 * 1. Migration(X, Y)-Objekt hier ergänzen
 * 2. DB-Version in [KrisenvorratDatabase] hochzählen
 * 3. Migration in [de.krisenvorrat.app.di.DatabaseModule].addMigrations() eintragen
 * 4. Migrationspfad in [de.krisenvorrat.app.data.db.KrisenvorratDatabaseMigrationTest] testen
 * 5. Bei neuen Pflichtfeldern ohne sinnvollen Default: interaktiven MigrationScreen ergänzen
 */
internal object Migrations {

    /**
     * V1 → V2:
     * - `kcal_per_100g` umbenannt in `kcal_per_kg`
     * - `min_stock`-Spalte entfernt
     *
     * SQLite unterstützt erst ab 3.25 (API 29) ALTER TABLE … RENAME COLUMN.
     * Da minSdk = 26, wird die Tabelle neu erstellt und die Daten kopiert.
     */
    val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(db: SupportSQLiteDatabase) {
            db.execSQL(
                """
                CREATE TABLE `items_new` (
                    `id` TEXT NOT NULL,
                    `name` TEXT NOT NULL,
                    `category_id` INTEGER NOT NULL,
                    `quantity` REAL NOT NULL,
                    `unit` TEXT NOT NULL,
                    `unit_price` REAL NOT NULL,
                    `kcal_per_kg` INTEGER,
                    `expiry_date` TEXT,
                    `location_id` INTEGER NOT NULL,
                    `notes` TEXT NOT NULL,
                    `last_updated` INTEGER NOT NULL,
                    PRIMARY KEY(`id`),
                    FOREIGN KEY(`category_id`) REFERENCES `categories`(`id`)
                        ON UPDATE NO ACTION ON DELETE CASCADE,
                    FOREIGN KEY(`location_id`) REFERENCES `locations`(`id`)
                        ON UPDATE NO ACTION ON DELETE CASCADE
                )
                """.trimIndent()
            )
            db.execSQL(
                """
                INSERT INTO `items_new`
                    (id, name, category_id, quantity, unit, unit_price,
                     kcal_per_kg, expiry_date, location_id, notes, last_updated)
                SELECT
                    id, name, category_id, quantity, unit, unit_price,
                    kcal_per_100g, expiry_date, location_id, notes, last_updated
                FROM `items`
                """.trimIndent()
            )
            db.execSQL("DROP TABLE `items`")
            db.execSQL("ALTER TABLE `items_new` RENAME TO `items`")
            db.execSQL(
                "CREATE INDEX IF NOT EXISTS `index_items_category_id` ON `items` (`category_id`)"
            )
            db.execSQL(
                "CREATE INDEX IF NOT EXISTS `index_items_location_id` ON `items` (`location_id`)"
            )
        }
    }

    /**
     * V2 → V3:
     * - Neue Tabelle `pending_sync_ops` für die Offline-Sync-Queue.
     */
    val MIGRATION_2_3 = object : Migration(2, 3) {
        override fun migrate(db: SupportSQLiteDatabase) {
            db.execSQL(
                """
                CREATE TABLE IF NOT EXISTS `pending_sync_ops` (
                    `id` TEXT NOT NULL,
                    `item_id` TEXT NOT NULL,
                    `operation` TEXT NOT NULL,
                    `payload` TEXT NOT NULL,
                    `created_at` INTEGER NOT NULL,
                    PRIMARY KEY(`id`)
                )
                """.trimIndent()
            )
        }
    }

    /**
     * V3 → V4:
     * - Neue Tabelle `messages` für die Chat-/Messaging-Funktion.
     */
    val MIGRATION_3_4 = object : Migration(3, 4) {
        override fun migrate(db: SupportSQLiteDatabase) {
            db.execSQL(
                """
                CREATE TABLE IF NOT EXISTS `messages` (
                    `id` TEXT NOT NULL,
                    `sender_id` TEXT NOT NULL,
                    `sender_username` TEXT NOT NULL,
                    `receiver_id` TEXT NOT NULL,
                    `body` TEXT NOT NULL,
                    `sent_at` INTEGER NOT NULL,
                    `is_pending` INTEGER NOT NULL,
                    PRIMARY KEY(`id`)
                )
                """.trimIndent()
            )
        }
    }
}
