package com.atridad.openclimb.data.database

import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import android.content.Context
import com.atridad.openclimb.data.database.dao.*
import com.atridad.openclimb.data.model.*

@Database(
    entities = [
        Gym::class,
        Problem::class,
        ClimbSession::class,
        Attempt::class
    ],
    version = 5,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class OpenClimbDatabase : RoomDatabase() {
    
    abstract fun gymDao(): GymDao
    abstract fun problemDao(): ProblemDao
    abstract fun climbSessionDao(): ClimbSessionDao
    abstract fun attemptDao(): AttemptDao
    
    companion object {
        @Volatile
        private var INSTANCE: OpenClimbDatabase? = null
        
        val MIGRATION_4_5 = object : Migration(4, 5) {
            override fun migrate(database: SupportSQLiteDatabase) {
                val cursor = database.query("PRAGMA table_info(climb_sessions)")
                val existingColumns = mutableSetOf<String>()
                
                while (cursor.moveToNext()) {
                    val columnName = cursor.getString(cursor.getColumnIndexOrThrow("name"))
                    existingColumns.add(columnName)
                }
                cursor.close()
                
                if (!existingColumns.contains("startTime")) {
                    database.execSQL("ALTER TABLE climb_sessions ADD COLUMN startTime TEXT")
                }
                if (!existingColumns.contains("endTime")) {
                    database.execSQL("ALTER TABLE climb_sessions ADD COLUMN endTime TEXT")
                }
                if (!existingColumns.contains("status")) {
                    database.execSQL("ALTER TABLE climb_sessions ADD COLUMN status TEXT NOT NULL DEFAULT 'COMPLETED'")
                }
                
                database.execSQL("UPDATE climb_sessions SET startTime = createdAt WHERE startTime IS NULL")
                database.execSQL("UPDATE climb_sessions SET status = 'COMPLETED' WHERE status IS NULL OR status = ''")
            }
        }
        
        val MIGRATION_5_6 = object : Migration(5, 6) {
            override fun migrate(database: SupportSQLiteDatabase) {
            }
        }
        
        fun getDatabase(context: Context): OpenClimbDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    OpenClimbDatabase::class.java,
                    "openclimb_database"
                )
                    .addMigrations(MIGRATION_4_5, MIGRATION_5_6)
                    .enableMultiInstanceInvalidation()
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }
}
