package com.fabledsword.minstrel.cache.db

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.fabledsword.minstrel.cache.db.dao.AudioCacheIndexDao
import com.fabledsword.minstrel.cache.db.dao.AuthSessionDao
import com.fabledsword.minstrel.cache.db.dao.CachedAlbumDao
import com.fabledsword.minstrel.cache.db.dao.CachedArtistDao
import com.fabledsword.minstrel.cache.db.dao.CachedHistorySnapshotDao
import com.fabledsword.minstrel.cache.db.dao.CachedHomeIndexDao
import com.fabledsword.minstrel.cache.db.dao.CachedLikeDao
import com.fabledsword.minstrel.cache.db.dao.CachedMutationDao
import com.fabledsword.minstrel.cache.db.dao.CachedPlaylistDao
import com.fabledsword.minstrel.cache.db.dao.CachedResumeStateDao
import com.fabledsword.minstrel.cache.db.dao.CachedPlaylistTrackDao
import com.fabledsword.minstrel.cache.db.dao.CachedQuarantineDao
import com.fabledsword.minstrel.cache.db.dao.CachedTrackDao
import com.fabledsword.minstrel.cache.db.dao.DiagnosticEventDao
import com.fabledsword.minstrel.cache.db.dao.SyncMetadataDao
import com.fabledsword.minstrel.cache.db.entities.AudioCacheIndexEntity
import com.fabledsword.minstrel.cache.db.entities.AuthSessionEntity
import com.fabledsword.minstrel.cache.db.entities.CachedAlbumEntity
import com.fabledsword.minstrel.cache.db.entities.CachedArtistEntity
import com.fabledsword.minstrel.cache.db.entities.CachedHistorySnapshotEntity
import com.fabledsword.minstrel.cache.db.entities.CachedHomeIndexEntity
import com.fabledsword.minstrel.cache.db.entities.CachedLikeEntity
import com.fabledsword.minstrel.cache.db.entities.CachedMutationEntity
import com.fabledsword.minstrel.cache.db.entities.CachedPlaylistEntity
import com.fabledsword.minstrel.cache.db.entities.CachedResumeStateEntity
import com.fabledsword.minstrel.cache.db.entities.CachedPlaylistTrackEntity
import com.fabledsword.minstrel.cache.db.entities.CachedQuarantineEntity
import com.fabledsword.minstrel.cache.db.entities.CachedTrackEntity
import com.fabledsword.minstrel.cache.db.entities.DiagnosticEventEntity
import com.fabledsword.minstrel.cache.db.entities.SyncMetadataEntity

/**
 * Single Room database for the whole app. Mirrors the Flutter client's
 * Drift `AppDb` — same logical schema, one entity-family per @Entity.
 *
 * Native v1 starts at schema version 1 (the Flutter Drift schemaVersion 11
 * is an internal client detail; the server is the source of truth and the
 * sync controller refills on first launch). Future schema bumps land per
 * change with explicit `Migration` entries; `fallbackToDestructiveMigration`
 * in `DatabaseModule` is the safety net while we're pre-v1.
 *
 * Entity families land in Task 4.2 slices. The set will grow until the
 * whole Drift schema is mirrored.
 */
@Database(
    entities = [
        SyncMetadataEntity::class,
        CachedArtistEntity::class,
        CachedAlbumEntity::class,
        CachedTrackEntity::class,
        CachedLikeEntity::class,
        CachedPlaylistEntity::class,
        CachedPlaylistTrackEntity::class,
        CachedQuarantineEntity::class,
        AudioCacheIndexEntity::class,
        CachedMutationEntity::class,
        CachedResumeStateEntity::class,
        CachedHomeIndexEntity::class,
        CachedHistorySnapshotEntity::class,
        AuthSessionEntity::class,
        DiagnosticEventEntity::class,
    ],
    // v7: + diagnostic_events table (M9) and the diagnosticsOptOut column
    // on auth_session. Pre-v1 destructive fallback rebuilds on mismatch.
    version = 7,
    exportSchema = true,
)
@TypeConverters(MinstrelTypeConverters::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun syncMetadataDao(): SyncMetadataDao
    abstract fun cachedArtistDao(): CachedArtistDao
    abstract fun cachedAlbumDao(): CachedAlbumDao
    abstract fun cachedTrackDao(): CachedTrackDao
    abstract fun cachedLikeDao(): CachedLikeDao
    abstract fun cachedPlaylistDao(): CachedPlaylistDao
    abstract fun cachedPlaylistTrackDao(): CachedPlaylistTrackDao
    abstract fun cachedQuarantineDao(): CachedQuarantineDao
    abstract fun audioCacheIndexDao(): AudioCacheIndexDao
    abstract fun cachedMutationDao(): CachedMutationDao
    abstract fun cachedResumeStateDao(): CachedResumeStateDao
    abstract fun cachedHomeIndexDao(): CachedHomeIndexDao
    abstract fun cachedHistorySnapshotDao(): CachedHistorySnapshotDao
    abstract fun authSessionDao(): AuthSessionDao
    abstract fun diagnosticEventDao(): DiagnosticEventDao
}
