package moe.oko.opennaw.util;

import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import moe.oko.opennaw.model.action.Action;
import moe.oko.opennaw.model.action.CityAttackAction;
import moe.oko.opennaw.model.action.CityDefenseAction;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;

import java.util.HashMap;
import java.util.UUID;

public class ActionLogger {
    HashMap<UUID, Action> actionByUuid = new HashMap<>();

    public ActionLogger() {
    }

    public boolean tryAction(Action action) {
        if (action instanceof CityAttackAction) {
            //City attack logic
            CityAttackAction CAA = (CityAttackAction) action;
            if (actionByUuid.containsKey(CAA.getPlayer().getUniqueId())) {
                Action storedAction = actionByUuid.get(CAA.getPlayer().getUniqueId());
                if (actionByUuid.get(CAA.getPlayer().getUniqueId()) instanceof CityAttackAction) {
                    //Action is already running.
                    return true;
                } else {
                    actionByUuid.get(CAA.getPlayer().getUniqueId()).setCancelled(true); //Cancel prior action.
                    actionByUuid.remove(CAA.getPlayer().getUniqueId());
                    CAA.getPlayer().getPlayer().sendMessage(ChatColor.YELLOW + "Action switched.");
                }
            }
            actionByUuid.put(CAA.getPlayer().getUniqueId(), action);
            CAA.initiation(); //Code to run when action started.
            Bukkit.getScheduler().runTaskLater(OpenNAW.getInstance(), () -> {
                OpenNAW.getInstance().getLogger().info("Starting Callback...");
                var actionCallback = actionByUuid.get(CAA.getPlayer().getUniqueId());
                if (!actionCallback.isCancelled()) {
                    OpenNAW.getInstance().getLogger().info("Callback not cancelled!");
                    CAA.completion();
                }
                actionByUuid.remove(CAA.getPlayer().getUniqueId());
            }, CityAttackAction.DELAY);
            CAA.getPlayer().getPlayer().sendMessage(ChatColor.GREEN + "" + ChatColor.ITALIC + "You raise your sword...");
            return true;
        } else if (action instanceof CityDefenseAction) {
            CityDefenseAction CDA = (CityDefenseAction) action;
            if (actionByUuid.containsKey(CDA.getPlayer().getUniqueId())) {
                Action storedAction = actionByUuid.get(CDA.getPlayer().getUniqueId());
                if (actionByUuid.get(CDA.getPlayer().getUniqueId()) instanceof CityDefenseAction) {
                    //Action is already running.
                    return true;
                } else {
                    actionByUuid.get(CDA.getPlayer().getUniqueId()).setCancelled(true); //Cancel prior action.
                    actionByUuid.remove(CDA.getPlayer().getUniqueId());
                    CDA.getPlayer().getPlayer().sendMessage(ChatColor.YELLOW + "Action switched.");
                }
            }
            actionByUuid.put(CDA.getPlayer().getUniqueId(), action);
            CDA.initiation(); //Code to run when action started.
            Bukkit.getScheduler().runTaskLater(OpenNAW.getInstance(), () -> {
                var actionCallback = actionByUuid.get(CDA.getPlayer().getUniqueId());
                if (!actionCallback.isCancelled()) {
                    CDA.completion();
                }
                actionByUuid.remove(CDA.getPlayer().getUniqueId());
            }, CityDefenseAction.DELAY);
            CDA.getPlayer().getPlayer().sendMessage(ChatColor.GREEN + "" + ChatColor.ITALIC + "You stand your ground...");
            return true;
        }
        return false; //Null action?
    }

    public void cancelDefenseActions(City city) {
        for(var action : actionByUuid.values()) {
            if(action instanceof CityDefenseAction) {
                var cda = (CityDefenseAction) action;
                if(cda.city == city) {
                    if(cda.getPlayer().isOnline()) {
                        cda.getPlayer().getPlayer().sendMessage(ChatColor.RED + "Action failed.");
                    }
                    cda.setCancelled(true);
                }
            }
        }
    }

    private boolean enoughTimeElapsed(long timestamp, long delay) {
        return (System.currentTimeMillis() - timestamp) > delay;
    }
}
