package de.walamana.models

import de.walamana.plugins.DateAsLong
import de.walamana.plugins.dbQuery
import kotlinx.serialization.Serializable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import java.util.Date

@Serializable
data class Gottesdienst(
    val id: Int,
    val name: String,
    val date: DateAsLong,
    val attendance: DateAsLong,
    val planId: Int
)

object Gottesdienste : Table() {
    val id = integer("id").autoIncrement()
    val name = varchar("name", 128).default("")
    val date = long("date")
    val attendance = long("attendance")
    val planId = integer("planId")
        .references(GottesdienstGroups.id, onDelete = ReferenceOption.CASCADE)

    override val primaryKey = PrimaryKey(id)
}

object GottesdiensteDao {

    private fun resultRowToGottesdienst(row: ResultRow) = Gottesdienst(
        row[Gottesdienste.id],
        row[Gottesdienste.name],
        Date(row[Gottesdienste.date]),
        Date(row[Gottesdienste.attendance]),
        row[Gottesdienste.planId]
    )

    suspend fun allGottesdienste(): List<Gottesdienst> = dbQuery {
        Gottesdienste.selectAll().map(::resultRowToGottesdienst)
    }

    suspend fun getGottesdiensteForPlan(planId: Int): List<Gottesdienst> = dbQuery {
        Gottesdienste.select { Gottesdienste.planId eq planId }.map(::resultRowToGottesdienst)
    }

    suspend fun createGottesdienst(name: String, date: Date, attendance: Date, planId: Int): Gottesdienst? = dbQuery {
        val statement = Gottesdienste.insert {
            it[Gottesdienste.name] = name
            it[Gottesdienste.date] = date.time
            it[Gottesdienste.attendance] = attendance.time
            it[Gottesdienste.planId] = planId
        }
        statement.resultedValues?.singleOrNull()?.let(::resultRowToGottesdienst)
    }

    suspend fun deleteGottesdienst(id: Int): Boolean = dbQuery {
        Gottesdienste.deleteWhere { Gottesdienste.id eq id } > 0
    }

    suspend fun updateGottesdienst(
        id: Int,
        name: String? = null,
        date: Date? = null,
        attendance: Date? = null,
        planId: Int? = null
    ): Boolean = dbQuery {
        Gottesdienste.update({ Gottesdienste.id eq id }) {
            if (name != null) it[Gottesdienste.name] = name
            if (date != null) it[Gottesdienste.date] = date.time
            if (attendance != null) it[Gottesdienste.attendance] = attendance.time
            if (planId != null) it[Gottesdienste.planId] = planId
        } > 0
    }
}
