/*
 *   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.*
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
import org.jetbrains.exposed.v1.dao.IntEntity
import org.jetbrains.exposed.v1.dao.IntEntityClass
import org.jetbrains.exposed.v1.jdbc.select

object TeamTable : IntIdTable("Team", "TeamID") {
    val kuerzel = varchar("TeamKuerzel", 10).index()
    val color = char("TeamColor", 1).default("8")
    val name = varchar("TeamName", 16).index()
    val deleted = bool("TeamDeleted").default(false)
}

class Team(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<Team>(TeamTable) {
        private val teamCache = mutableMapOf<Int, Team>()

        @JvmStatic
        fun clear() =
            synchronized(teamCache) { teamCache.clear() }

        @JvmStatic
        fun byId(id: Int) =
            synchronized(teamCache) { teamCache.computeIfAbsent(id) { useDb { Team[id] } } }

        @JvmStatic
        fun get(name: String) =
            useDb { find { (TeamTable.name.lowerCase() eq name.lowercase() or (TeamTable.kuerzel.lowerCase() eq name.lowercase())) and not(TeamTable.deleted) }.firstOrNull() }

        @JvmStatic
        fun getAll() =
            useDb { find { not(TeamTable.deleted) }.toList() }

        @JvmStatic
        fun create(kuerzel: String, name: String) =
            useDb {
                new {
                    this.kuerzel = kuerzel
                    this.name = name
                }
            }
    }

    val teamId by TeamTable.id.transform({ EntityID(it, TeamTable) }, { it.value })
    private var kuerzel by TeamTable.kuerzel
    private var color by TeamTable.color
    private var name by TeamTable.name
    var deleted by TeamTable.deleted
        private set
    val members by lazy { useDb { SteamwarUserTable.select(SteamwarUserTable.id).where { SteamwarUserTable.team eq teamId }.map { it[SteamwarUserTable.id].value } } }

    fun size() =
        useDb { SteamwarUser.find { SteamwarUserTable.team eq teamId }.count().toInt() }

    fun disband(user: SteamwarUser) =
        useDb {
            user.team = 0
            deleted = true
            teamCache.remove(teamId)
            TeamTeilnahme.deleteFuture(teamId)
        }

    var teamKuerzel: String
        get() = kuerzel
        set(value) = useDb {
            kuerzel = value
        }

    var teamColor: String
        get() = color
        set(value) = useDb {
            color = value
        }

    var teamName: String
        get() = name
        set(value) = useDb {
            name = value
        }
}