/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.sql

import de.steamwar.sql.internal.useDb
import org.jetbrains.exposed.v1.core.and
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.dao.CompositeEntity
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
import org.jetbrains.exposed.v1.jdbc.upsert
import java.util.*

object UserConfigTable : CompositeIdTable("UserConfig") {
    val userId = reference("User", SteamwarUserTable)
    val config = varchar("Config", 32).entityId()
    val value = text("Value", eagerLoading = true)

    override val primaryKey = PrimaryKey(userId, config)

    init {
        addIdColumn(userId)
    }
}

class UserConfig(id: EntityID<CompositeID>) : CompositeEntity(id) {
    val userId by UserConfigTable.userId
    val config by UserConfigTable.config
    var value by UserConfigTable.value

    companion object : CompositeEntityClass<UserConfig>(UserConfigTable) {
        @JvmStatic
        fun getConfig(userId: Int, config: String) =
            useDb {
                find { (UserConfigTable.userId eq userId) and (UserConfigTable.config eq config) }.firstOrNull()?.value
            }

        @JvmStatic
        fun getConfig(user: UUID, config: String) =
            getConfig(SteamwarUser.get(user)!!.id.value, config)

        @JvmStatic
        fun updatePlayerConfig(id: Int, config: String, value: String?) =
            useDb {
                if (value == null) {
                    removePlayerConfig(id, config)
                } else {
                    UserConfigTable.upsert {
                        it[UserConfigTable.userId] = id
                        it[UserConfigTable.config] = config
                        it[UserConfigTable.value] = value
                    }
                }
            }

        @JvmStatic
        fun updatePlayerConfig(user: UUID, config: String, value: String?) =
            updatePlayerConfig(SteamwarUser.get(user)!!.id.value, config, value)

        @JvmStatic
        fun removePlayerConfig(id: Int, config: String) =
            useDb {
                find { (UserConfigTable.userId eq id) and (UserConfigTable.config eq config) }.firstOrNull()?.delete()
            }

        @JvmStatic
        fun removePlayerConfig(user: UUID, config: String) =
            removePlayerConfig(SteamwarUser.get(user)!!.id.value, config)
    }
}