package app.voltplan.cable.data.db

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import androidx.room.Upsert
import app.voltplan.cable.data.model.ElectricalSystem
import app.voltplan.cable.data.model.SavedBattery
import app.voltplan.cable.data.model.SavedCharger
import app.voltplan.cable.data.model.SavedLoad
import kotlinx.coroutines.flow.Flow

@Dao
interface SystemDao {
    @Query("SELECT * FROM systems ORDER BY timestamp DESC")
    fun observeAll(): Flow<List<ElectricalSystem>>

    @Query("SELECT * FROM systems WHERE id = :id")
    fun observe(id: String): Flow<ElectricalSystem?>

    @Query("SELECT * FROM systems WHERE id = :id")
    suspend fun get(id: String): ElectricalSystem?

    @Query("SELECT COUNT(*) FROM systems")
    suspend fun count(): Int

    @Query("SELECT name FROM systems")
    suspend fun allNames(): List<String>

    @Upsert
    suspend fun upsert(system: ElectricalSystem)

    @Delete
    suspend fun delete(system: ElectricalSystem)

    @Query("DELETE FROM systems WHERE id = :id")
    suspend fun deleteById(id: String)
}

@Dao
interface LoadDao {
    @Query("SELECT * FROM loads ORDER BY timestamp DESC")
    fun observeAll(): Flow<List<SavedLoad>>

    @Query("SELECT * FROM loads WHERE systemId = :systemId ORDER BY timestamp DESC")
    fun observeForSystem(systemId: String): Flow<List<SavedLoad>>

    @Query("SELECT * FROM loads WHERE systemId = :systemId")
    suspend fun listForSystem(systemId: String): List<SavedLoad>

    @Query("SELECT * FROM loads WHERE id = :id")
    suspend fun get(id: String): SavedLoad?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(load: SavedLoad)

    @Update
    suspend fun update(load: SavedLoad)

    @Upsert
    suspend fun upsert(load: SavedLoad)

    @Delete
    suspend fun delete(load: SavedLoad)

    @Query("DELETE FROM loads WHERE systemId = :systemId")
    suspend fun deleteForSystem(systemId: String)
}

@Dao
interface BatteryDao {
    @Query("SELECT * FROM batteries ORDER BY timestamp DESC")
    fun observeAll(): Flow<List<SavedBattery>>

    @Query("SELECT * FROM batteries WHERE systemId = :systemId ORDER BY timestamp DESC")
    fun observeForSystem(systemId: String): Flow<List<SavedBattery>>

    @Query("SELECT * FROM batteries WHERE systemId = :systemId")
    suspend fun listForSystem(systemId: String): List<SavedBattery>

    @Query("SELECT * FROM batteries WHERE id = :id")
    suspend fun get(id: String): SavedBattery?

    @Upsert
    suspend fun upsert(battery: SavedBattery)

    @Delete
    suspend fun delete(battery: SavedBattery)

    @Query("DELETE FROM batteries WHERE systemId = :systemId")
    suspend fun deleteForSystem(systemId: String)
}

@Dao
interface ChargerDao {
    @Query("SELECT * FROM chargers ORDER BY timestamp DESC")
    fun observeAll(): Flow<List<SavedCharger>>

    @Query("SELECT * FROM chargers WHERE systemId = :systemId ORDER BY timestamp DESC")
    fun observeForSystem(systemId: String): Flow<List<SavedCharger>>

    @Query("SELECT * FROM chargers WHERE systemId = :systemId")
    suspend fun listForSystem(systemId: String): List<SavedCharger>

    @Query("SELECT * FROM chargers WHERE id = :id")
    suspend fun get(id: String): SavedCharger?

    @Upsert
    suspend fun upsert(charger: SavedCharger)

    @Delete
    suspend fun delete(charger: SavedCharger)

    @Query("DELETE FROM chargers WHERE systemId = :systemId")
    suspend fun deleteForSystem(systemId: String)
}
