package com.example.scanwich

import android.content.Context
import androidx.room.*
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import kotlinx.coroutines.flow.Flow

@Entity(tableName = "meals")
data class Meal(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val date: Long,
    val name: String = "Repas",
    val analysisText: String,
    val totalCalories: Int,
    val carbs: Int = 0,
    val protein: Int = 0,
    val fat: Int = 0,
    val type: String = "Collation"
)

@Entity(tableName = "glycemia")
data class Glycemia(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val date: Long,
    val value: Double,
    val moment: String
)

@Entity(tableName = "sports")
data class SportActivity(
    @PrimaryKey val id: Long,
    val name: String,
    val type: String,
    val distance: Float,
    val movingTime: Int,
    val calories: Float?,
    val date: Long // timestamp
)

@Entity(tableName = "favorite_meals")
data class FavoriteMeal(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val name: String,
    val analysisText: String,
    val calories: Int,
    val carbs: Int,
    val protein: Int,
    val fat: Int
)

@Dao
interface AppDao {
    @Insert suspend fun insertMeal(meal: Meal): Long
    @Delete suspend fun deleteMeal(meal: Meal)
    @Query("SELECT * FROM meals ORDER BY date DESC") fun getAllMeals(): Flow<List<Meal>>
    @Query("SELECT * FROM meals WHERE date >= :startOfDay AND date < :endOfDay ORDER BY date DESC")
    fun getMealsForDay(startOfDay: Long, endOfDay: Long): Flow<List<Meal>>
    @Query("SELECT * FROM meals WHERE date >= :start AND date <= :end ORDER BY date ASC")
    suspend fun getMealsInRangeSync(start: Long, end: Long): List<Meal>
    
    @Insert suspend fun insertGlycemia(glycemia: Glycemia): Long
    @Delete suspend fun deleteGlycemia(glycemia: Glycemia)
    @Query("SELECT * FROM glycemia ORDER BY date DESC") fun getAllGlycemia(): Flow<List<Glycemia>>
    @Query("SELECT * FROM glycemia WHERE date >= :startOfDay AND date < :endOfDay ORDER BY date DESC")
    fun getGlycemiaForDay(startOfDay: Long, endOfDay: Long): Flow<List<Glycemia>>
    @Query("SELECT * FROM glycemia WHERE date >= :start AND date <= :end ORDER BY date ASC")
    suspend fun getGlycemiaInRangeSync(start: Long, end: Long): List<Glycemia>

    @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertSports(sports: List<SportActivity>)
    @Query("SELECT * FROM sports ORDER BY date DESC") fun getAllSports(): Flow<List<SportActivity>>
    @Query("SELECT * FROM sports WHERE date >= :startOfDay AND date < :endOfDay ORDER BY date DESC") 
    fun getSportsForDay(startOfDay: Long, endOfDay: Long): Flow<List<SportActivity>>
    @Query("SELECT * FROM sports WHERE date >= :start AND date <= :end ORDER BY date ASC")
    suspend fun getSportsInRangeSync(start: Long, end: Long): List<SportActivity>

    @Insert suspend fun insertFavorite(meal: FavoriteMeal)
    @Delete suspend fun deleteFavorite(meal: FavoriteMeal)
    @Query("SELECT * FROM favorite_meals ORDER BY name ASC") fun getAllFavorites(): Flow<List<FavoriteMeal>>
}

@Database(entities = [Meal::class, Glycemia::class, SportActivity::class, FavoriteMeal::class], version = 7)
abstract class AppDatabase : RoomDatabase() {
    abstract fun appDao(): AppDao
    companion object {
        @Volatile private var INSTANCE: AppDatabase? = null

        private val MIGRATION_6_7 = object : Migration(6, 7) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL("CREATE TABLE IF NOT EXISTS `favorite_meals` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `analysisText` TEXT NOT NULL, `calories` INTEGER NOT NULL, `carbs` INTEGER NOT NULL, `protein` INTEGER NOT NULL, `fat` INTEGER NOT NULL)")
            }
        }

        fun getDatabase(context: Context): AppDatabase =
            INSTANCE ?: synchronized(this) {
                Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "app_db")
                    .addMigrations(MIGRATION_6_7)
                    .fallbackToDestructiveMigration()
                    .build().also { INSTANCE = it }
            }
    }
}
