package com.chick_mood.data.database

import androidx.room.*
import androidx.sqlite.db.SupportSQLiteDatabase
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import com.chick_mood.data.model.MoodRecord
import com.chick_mood.data.model.UserConfig
import com.chick_mood.data.model.UserConfigEntry

/**
 * 应用主数据库
 *
 * 使用Room数据库框架管理应用的本地数据存储
 * 包含心情记录和用户配置两个主要数据表
 * 支持数据库迁移和预填充数据
 *
 * @author Claude
 * @date 2025-10-22
 */
@Database(
    entities = [
        MoodRecord::class,
        UserConfig::class,
        UserConfigEntry::class
    ],
    version = 2,
    exportSchema = true
)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {

    /**
     * 心情记录数据访问对象
     */
    abstract fun moodRecordDao(): MoodRecordDao

    /**
     * 用户配置键值对数据访问对象
     */
    abstract fun userConfigEntryDao(): UserConfigEntryDao

    companion object {
        /**
         * 数据库名称
         */
        const val DATABASE_NAME = "chick_mood_database"

        /**
         * 数据库版本
         */
        const val DATABASE_VERSION = 1

        /**
         * 数据库实例（单例）
         */
        @Volatile
        private var INSTANCE: AppDatabase? = null

        /**
         * 获取数据库实例
         *
         * 使用单例模式确保全局只有一个数据库实例
         * 如果实例不存在则创建新的实例
         *
         * @param context 应用上下文
         * @return 数据库实例
         */
        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    DATABASE_NAME
                )
                    .addCallback(DatabaseCallback())
                    .fallbackToDestructiveMigration() // 开发阶段使用，生产环境应提供具体的迁移策略
                    .build()
                INSTANCE = instance
                instance
            }
        }

        /**
         * 关闭数据库实例
         * 主要用于测试场景
         */
        fun closeDatabase() {
            INSTANCE?.close()
            INSTANCE = null
        }
    }

    /**
     * 数据库回调
     *
     * 处理数据库创建和打开时的初始化操作
     */
    private class DatabaseCallback : RoomDatabase.Callback() {

        /**
         * 数据库创建时调用
         * 初始化默认的用户配置数据
         */
        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            // 在IO线程中执行数据库初始化操作
            CoroutineScope(Dispatchers.IO).launch {
                populateDatabase(db)
            }
        }

        /**
         * 数据库打开时调用
         * 可以在这里执行数据验证或迁移后的清理工作
         */
        override fun onOpen(db: SupportSQLiteDatabase) {
            super.onOpen(db)
            // 启用外键约束
            db.execSQL("PRAGMA foreign_keys=ON")
        }

        /**
         * 填充初始数据
         *
         * @param database 数据库实例
         */
        private suspend fun populateDatabase(database: SupportSQLiteDatabase) {
            try {
                // 插入默认用户配置
                insertDefaultUserConfigs(database)

                // 可以在这里添加其他初始化数据
                // 例如：示例心情记录、默认设置等

            } catch (e: Exception) {
                // 记录初始化错误，但不影响应用启动
                e.printStackTrace()
            }
        }

        /**
         * 插入默认用户配置
         *
         * @param db 数据库实例
         */
        private fun insertDefaultUserConfigs(db: SupportSQLiteDatabase) {
            val currentTime = System.currentTimeMillis() / 1000

            // 应用版本
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('app_version', '1.0.0', $currentTime)
                """.trimIndent()
            )

            // 首次使用时间
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('first_use_time', $currentTime, $currentTime)
                """.trimIndent()
            )

            // 使用天数初始化
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('usage_days', 1, $currentTime)
                """.trimIndent()
            )

            // 心情记录总数初始化
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('total_mood_records', 0, $currentTime)
                """.trimIndent()
            )

            // 最后活跃时间
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('last_active_time', $currentTime, $currentTime)
                """.trimIndent()
            )

            // 默认用户昵称
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('user_nickname', '小鸡主人', $currentTime)
                """.trimIndent()
            )

            // 默认提醒设置
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('morning_reminder', '09:00', $currentTime)
                """.trimIndent()
            )

            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('evening_reminder', '21:00', $currentTime)
                """.trimIndent()
            )

            // 默认功能开关
            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('notification_enabled', 1, $currentTime)
                """.trimIndent()
            )

            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('sound_enabled', 1, $currentTime)
                """.trimIndent()
            )

            db.execSQL(
                """
                INSERT OR REPLACE INTO user_config (config_key, config_value, updated_at)
                VALUES ('vibration_enabled', 1, $currentTime)
                """.trimIndent()
            )
        }
    }
}