package moe.oko.opennaw.model;

import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.type.CityState;
import moe.oko.opennaw.model.type.CityType;
import net.kyori.adventure.text.Component;

import org.bukkit.*;

public class City {
    private String name;
    private String resource;
    private CityState state;

    private CityType type;
    private Nation owner;

    //Null until its needed.
    private Nation attacker;

    private Location point;
    private short health;

    public City(String name, String resource, Location location) {
        this.name = name;
        this.resource = resource;
        //Default is unclaimed.
        this.owner = Nation.UNCLAIMED;
        this.state = CityState.NORMAL;
        this.type = CityType.NORMAL;
        this.point = location;
        this.health = 300;
    }

    //DB Const
    public City(String name, String resource, String type, Location location, Nation owner) {
        this.name = name;
        this.resource = resource;
        this.type = CityType.valueOf(type);
        this.point = location;
        this.owner = owner;
        this.health = 300;
        this.state = CityState.NORMAL;
    }

    public String getName() {
        return name;
    }

    public String getResource() {
        return resource;
    }

    public Nation getOwner() {
        return owner;
    }

    public void setOwner(Nation nation) {
        this.owner = nation;
    }

    public Location getPoint() {
        return point;
    }

    public short getHealth() {
        return health;
    }

    public void damage(short damage) {
        this.health -= damage;
    }

    public CityType getType() { return type; }

    public void setType(CityType type) {
        this.type = type;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean underSiege() {
        return state.equals(CityState.SIEGE);
    }

    public boolean startSiege(Nation nation) {
        if(state.equals(CityState.RECOVERY)) return false;
        state = CityState.SIEGE;
        Bukkit.broadcastMessage(ChatColor.RED + nation.getName() + ChatColor.GOLD + " has begun a siege against the city of " + ChatColor.AQUA + getName());
        for(var player : Bukkit.getOnlinePlayers()) {
            player.playSound(player.getLocation(), Sound.ITEM_TRIDENT_THUNDER, 1F, 1F);
        }
        attacker = nation;
        return true;
    }

    public void damage() {
        //Ran each time a city is damaged by a capture event
        //Makes an explosion of ash around a block
        point.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, point, 1, .01, .01, .01);
        point.getWorld().playSound(point, Sound.ENTITY_GENERIC_EXPLODE, 1F, 1F);
        health = (short) (health - OpenNAW.getInstance().getConfigHelper().cityDamageOnStrike());
        switch (health) {
            case 250:
            case 200:
            case 150:
            case 100:
            case 50:
                for(var player : Bukkit.getOnlinePlayers()) {
                    if(player.getLocation().distance(point) < 100) {
                        player.sendMessage(ChatColor.BOLD + "" + ChatColor.RED + "THE CITY HAS FALLEN TO " + health + " HEALTH...");
                    }
                }
                return;
            case 10:
                for(var player : Bukkit.getOnlinePlayers()) {
                    if(player.getLocation().distance(point) < 100) {
                        player.sendMessage(ChatColor.BOLD + "" + ChatColor.RED + "THE CITY IS ABOUT TO BE CAPTURED!");
                    }
                }
        }
        if(health == 0 || health < 0) {
            capture();
        }
    }

    public void defend() {
        //successful defense logic.
        Bukkit.broadcastMessage(ChatColor.RED + attacker.getName() + ChatColor.GOLD + "'s siege against the city of "
                + ChatColor.AQUA + getName() + ChatColor.GOLD + " has " + ChatColor.RED + "failed");
        if(health < 250) {
            health = (short) (health + 50);
        }
        OpenNAW.getInstance().getActionLogger().cancelDefenseActions(this);
        attacker = null;
        this.state = CityState.RECOVERY; //Start recovery, prohibit sieges until restart.
        OpenNAW.getInstance().getLogger().info("Starting regen...");
        OpenNAW.getInstance().getTntHandler().endSiege(this);
    }

    public void capture() {
        setOwner(attacker);
        attacker = null; //reset to null so there isn't any bugs
        //This is our "capture" logic. So now we do shenanigans.
        if(OpenNAW.getInstance().isDynmapEnabled()) {
            //Dyn is enabled, we need to do setters.
            OpenNAW.getInstance().getDynmapHandler().updateCityInfoMarker(this);
        }
        Bukkit.broadcastMessage(ChatColor.AQUA + getName() + ChatColor.GOLD + " has been successfully captured by " + ChatColor.RED + this.owner.getName());
        OpenNAW.getInstance().getLogger().info("Starting regen...");
        OpenNAW.getInstance().getTntHandler().endSiege(this);
    }

    public boolean isUnclaimed() {
        return owner == Nation.UNCLAIMED;
    }
}