/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2024 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.tntleague.game

import de.steamwar.message.SubMessage
import de.steamwar.tntleague.colorByTeam
import de.steamwar.tntleague.config.TNTLeagueWorldConfig
import de.steamwar.tntleague.config.TeamConfig
import de.steamwar.tntleague.config.targetedBlocks
import de.steamwar.tntleague.game.TNTLeagueGame.WinReason
import de.steamwar.tntleague.game.TNTLeagueGame.updateFightinfo
import de.steamwar.tntleague.game.TNTLeagueGame.win
import de.steamwar.tntleague.message
import de.steamwar.tntleague.plugin
import net.kyori.adventure.text.Component
import org.bukkit.GameMode
import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack

data class TNTLeagueTeam(val config: TeamConfig) {

    var leader: Player? = null
        set(player) {
            field = player
            if (player != null) {
                with(player.inventory) {
                    clear()
                    setItem(4, readyItem())
                }
            }
        }

    val members = mutableListOf<Player>()
    val invites = mutableListOf<Player>()

    val name: SubMessage
        get() = config.name

    val color: Char
        get() = config.color

    var isReady: Boolean = false
        set(value) {
            field = value
            leader?.inventory?.setItem(4, readyItem())
            leader?.let { it.playSound(it.location, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1f) }

            message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", name)

            if (value && opposite.isReady) {
                TNTLeagueGame.checkStart()
            }
        }

    var damagedBlocks: Int = 0
        set(value) {
            field = value
            if (value >= targetedBlocks) {
                win(this, WinReason.DESTROYED)
            }
        }

    var coins: Int = 0

    val opposite: TNTLeagueTeam
        get() = when (this) {
            TNTLeagueGame.redTeam -> TNTLeagueGame.blueTeam
            TNTLeagueGame.blueTeam -> TNTLeagueGame.redTeam
            else -> error("Invalid Team")
        }

    val ergebnisInt: Int
        get() = when (this) {
            TNTLeagueGame.redTeam -> 2
            TNTLeagueGame.blueTeam -> 3
            else -> error("Invalid Team")
        }

    fun join(player: Player): Boolean {
        members.add(player)

        with(player) {
            teleport(config.worldConfig.spawnLocation)
            gameMode = GameMode.ADVENTURE
            inventory.clear()
            message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name)
        }

        if (leader == null) {
            leader = player
        }

        updateFightinfo()

        return true
    }

    fun readyItem() = if (isReady) {
        ItemStack.of(Material.LIME_DYE).apply {
            itemMeta = itemMeta.apply {
                displayName(Component.text(message.parse("READY", leader!!)))
            }
        }
    } else {
        ItemStack.of(Material.RED_DYE).apply {
            itemMeta = itemMeta.apply {
                displayName(Component.text(message.parse("NOT_READY", leader!!)))
            }
        }
    }

    fun start() = members.forEach {
        with(it) {
            gameMode = GameMode.SURVIVAL
        }
    }

    fun leave(player: Player) {
        members.remove(player)
        if (TNTLeagueGame.state == TNTLeagueGame.GameState.LOBBY) {
            if (members.isEmpty()) {
                plugin.server.onlinePlayers.firstOrNull { it != player && TNTLeagueGame.getTeam(it) == null }?.run {
                    join(this)
                }
            }
            if (leader == player) {
                leader = members.firstOrNull()

                if (leader == null && TNTLeagueGame.state == TNTLeagueGame.GameState.LOBBY) {
                    isReady = false
                }
            }
        } else if (TNTLeagueGame.state == TNTLeagueGame.GameState.RUNNING) {
            if (members.isEmpty()) {
                win(this.opposite, WinReason.LEAVE)
            }
        }
    }

    fun remove(player: Player) {
        leave(player)
        with(player) {
            teleport(TNTLeagueWorldConfig.lobby)
            gameMode = GameMode.SPECTATOR
            inventory.clear()
            message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name)
        }
        updateFightinfo()
    }
}