package com.seven.ikar.kotlin.core.local

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(
    entities = [CachedChatMessageEntity::class, CachedChatEntity::class, TransferQueueEntity::class],
    version = 4,
    exportSchema = false
)
abstract class IkarLocalDatabase : RoomDatabase() {
    abstract fun cachedChatMessageDao(): CachedChatMessageDao
    abstract fun cachedChatDao(): CachedChatDao
    abstract fun transferQueueDao(): TransferQueueDao

    companion object {
        @Volatile
        private var instance: IkarLocalDatabase? = null

        private val Migration1To2 = object : Migration(1, 2) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL(
                    """
                    CREATE TABLE IF NOT EXISTS transfer_queue (
                        id TEXT NOT NULL PRIMARY KEY,
                        groupId TEXT NOT NULL,
                        type TEXT NOT NULL,
                        status TEXT NOT NULL,
                        chatId TEXT,
                        text TEXT,
                        replyToMessageId TEXT,
                        attachmentId TEXT,
                        fileName TEXT NOT NULL,
                        contentType TEXT NOT NULL,
                        fileSizeBytes INTEGER NOT NULL,
                        localPath TEXT NOT NULL,
                        sortOrder INTEGER NOT NULL,
                        progressPercent INTEGER NOT NULL,
                        errorMessage TEXT,
                        createdAtMillis INTEGER NOT NULL,
                        updatedAtMillis INTEGER NOT NULL
                    )
                    """.trimIndent()
                )
            }
        }

        private val Migration2To3 = object : Migration(2, 3) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL(
                    """
                    CREATE TABLE IF NOT EXISTS cached_chats (
                        owner_user_id TEXT NOT NULL,
                        chat_id TEXT NOT NULL,
                        last_activity_at TEXT,
                        is_pinned INTEGER NOT NULL,
                        is_archived INTEGER NOT NULL,
                        unread_count INTEGER NOT NULL,
                        payload_json TEXT NOT NULL,
                        updated_at_millis INTEGER NOT NULL,
                        PRIMARY KEY(owner_user_id, chat_id)
                    )
                    """.trimIndent()
                )
                db.execSQL("CREATE INDEX IF NOT EXISTS index_cached_chats_owner_user_id_is_archived_is_pinned ON cached_chats(owner_user_id, is_archived, is_pinned)")
                db.execSQL("CREATE INDEX IF NOT EXISTS index_cached_chats_owner_user_id_last_activity_at ON cached_chats(owner_user_id, last_activity_at)")
            }
        }

        private val Migration3To4 = object : Migration(3, 4) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL("ALTER TABLE transfer_queue ADD COLUMN storyVisibility TEXT")
                db.execSQL("ALTER TABLE transfer_queue ADD COLUMN hasProtectedContent INTEGER NOT NULL DEFAULT 0")
                db.execSQL("ALTER TABLE transfer_queue ADD COLUMN ttlSeconds INTEGER")
            }
        }

        fun getInstance(context: Context): IkarLocalDatabase =
            instance ?: synchronized(this) {
                instance ?: Room.databaseBuilder(
                    context.applicationContext,
                    IkarLocalDatabase::class.java,
                    "ikar-local.db"
                )
                    .addMigrations(Migration1To2, Migration2To3, Migration3To4)
                    .build()
                    .also { instance = it }
            }
    }
}
