package melody.offline.music.database

import android.content.Context
import androidx.room.Room
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import melody.offline.music.bean.OfflineBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import melody.offline.music.util.LogTag

class AppOfflineDBManager private constructor(context: Context) {

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

        fun getInstance(context: Context): AppOfflineDBManager {
            return instance ?: synchronized(this) {
                instance ?: AppOfflineDBManager(context).also { instance = it }
            }
        }
    }

    val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            // 在数据库中添加新的列
            database.execSQL("ALTER TABLE OfflineBean ADD COLUMN isFavorite INTEGER NOT NULL DEFAULT 0")
        }
    }

    private val database = Room.databaseBuilder(
        context.applicationContext, AppOfflineDatabase::class.java, "offline_data_base"
    ).addMigrations(MIGRATION_1_2).build()

    private val dao = database.localOfflineDao()

    suspend fun insertOfflineBean(bean: OfflineBean) {
        withContext(Dispatchers.IO) {
            LogTag.LogD(LogTag.VO_TEST_ONLY, "insertOfflineBean bean.videoId->${bean.videoId}")
            val offlineBean = getOfflineBeanByID(bean.videoId)
            if (offlineBean == null) {
                LogTag.LogD(LogTag.VO_TEST_ONLY, "insertOfflineBean 1")
                dao.insertOfflineBean(bean)
            } else {
                LogTag.LogD(LogTag.VO_TEST_ONLY, "insertOfflineBean 2")
                dao.updateOfflineBean(bean)
            }
        }
    }

    suspend fun insertOfflineListBean(list: List<OfflineBean>) {
        withContext(Dispatchers.IO) {
            for (bean in list) {
                val offlineBean = getOfflineBeanByID(bean.videoId)
                if (offlineBean == null) {
                    dao.insertOfflineBean(bean)
                } else {
                    dao.updateOfflineBean(bean)
                }
            }
        }
    }

    suspend fun getAllOfflineBeans(): List<OfflineBean> {
        return withContext(Dispatchers.IO) {
            dao.getAllOfflineBeans()
        }
    }

    suspend fun deleteOfflineBean(bean: OfflineBean) {
        withContext(Dispatchers.IO) {
            dao.deleteOfflineBean(bean)
        }
    }

    suspend fun deleteAllOfflineBean() {
        withContext(Dispatchers.IO) {
            dao.deleteAllOfflineBean()
        }
    }

    suspend fun updateOfflineBean(bean: OfflineBean) {
        withContext(Dispatchers.IO) {
            dao.updateOfflineBean(bean)
        }
    }

    suspend fun getOfflineBeanByID(id: String): OfflineBean? {
        return dao.getOfflineBeanByID(id)
    }
}
