package com.jihe.punchnet.data

import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Database
import androidx.room.Delete
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch

@Entity(tableName = "routes")
data class RouteItem (
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,

    @ColumnInfo(name = "net_ip")
    val net_ip: Int,
    // mask int, Intof(255,255,255,0
    @ColumnInfo(name = "mask_ip")
    val mask_ip: Int,
    @ColumnInfo(name = "gateway")
    val gateway: Int,
)

@Dao
interface RouteDAO {
    @Insert
    suspend fun insert(item: RouteItem): Long

    @Update
    suspend fun update(item: RouteItem)

    @Query("DELETE FROM routes WHERE id = :id")
    suspend fun deleteById(id: Long)

    @Query("SELECT * FROM routes")
    fun getAll(): Flow<List<RouteItem>>
}

@Database(entities = [RouteItem::class], version = 1)
abstract class AppDatabase: RoomDatabase() {
    abstract fun routeDao(): RouteDAO

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

class RouteRepository(private val routeDao: RouteDAO) {
    val all_routes: Flow<List<RouteItem>> = routeDao.getAll()

    suspend fun insert(item: RouteItem) {
        routeDao.insert(item)
    }

    suspend fun update(item: RouteItem) {
        routeDao.update(item)
    }

    suspend fun deleteById(id: Long) {
        routeDao.deleteById(id)
    }
}

class RouteViewModel(application: Application): AndroidViewModel(application) {
    private val repository: RouteRepository

    init {
        val routeDao = AppDatabase.getDatabase(application).routeDao()
        repository = RouteRepository(routeDao)
    }

    val allRoutes: Flow<List<RouteItem>> = repository.all_routes

    fun insert(item: RouteItem) = viewModelScope.launch {
        repository.insert(item)
    }

    fun update(item: RouteItem) = viewModelScope.launch {
        repository.update(item)
    }

    fun deleteById(id: Long) = viewModelScope.launch {
        repository.deleteById(id)
    }
}