package nl.sbdeveloper.themeparkplus.listeners;

import com.cryptomorin.xseries.XMaterial;
import de.tr7zw.changeme.nbtapi.NBTItem;
import nl.iobyte.themepark.ThemePark;
import nl.iobyte.themepark.api.attraction.enums.Status;
import nl.iobyte.themepark.api.attraction.objects.Attraction;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import nl.sbdeveloper.themeparkplus.api.PlusAPI;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import nl.sbdeveloper.themeparkplus.util.LGUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;

import java.util.Collections;
import java.util.HashMap;

/**
 * Fastpass machine & scanner signs
 */
public class FastpassListeners implements Listener {
    @EventHandler
    public void onSignClick(PlayerInteractEvent e) {
        if (e.getClickedBlock() == null || e.getAction() != Action.RIGHT_CLICK_BLOCK || !(e.getClickedBlock().getState() instanceof Sign) || e.getHand() != EquipmentSlot.HAND) return;

        String mLineOne = ChatColor.stripColor(ConfigUtil.__(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row1")));
        String mLineTwo = ChatColor.stripColor(ConfigUtil.__(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row2")));
        String sLineOne = ChatColor.stripColor(ConfigUtil.__(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row1")));
        String sLineTwo = ChatColor.stripColor(ConfigUtil.__(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row2")));

        Sign sign = (Sign) e.getClickedBlock().getState();
        if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(mLineOne) && !ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(sLineOne)) return;

        if (ChatColor.stripColor(sign.getLine(1)).equalsIgnoreCase(mLineTwo)) {
            //Buy a ticket
            String attID = sign.getLine(2);
            if (!ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(attID)) return;
            Attraction att = ThemePark.getInstance().getAPI().getAttractionService().getAttraction(attID);

            double price;
            try {
                price = Double.parseDouble(sign.getLine(3));
            } catch (NumberFormatException ex) {
                return;
            }

            ItemStack ticket = PlusAPI.getFastpassTicket(att);

            if (ticket == null) return;

            if (ThemeParkPlus.getEconomy().getBalance(e.getPlayer()) < price) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.NotEnoughMoney"));
                return;
            }

            for (ItemStack content : e.getPlayer().getInventory().getContents()) {
                if (content == null || content.getType() == Material.AIR) continue;
                NBTItem nbtContent = new NBTItem(content);
                if (content.getType() == XMaterial.PAPER.parseMaterial() && content.hasItemMeta() && nbtContent.hasKey("RideID") && nbtContent.getString("RideID").equalsIgnoreCase(attID)) {
                    e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.AlreadyHaveTicket"));
                    return;
                }
            }

            ThemeParkPlus.getEconomy().withdrawPlayer(e.getPlayer(), price);

            e.getPlayer().getInventory().addItem(ticket);
            e.getPlayer().updateInventory();
            HashMap<String, String> vars = new HashMap<>();
            vars.put("%ridename%", att.getName());
            vars.put("%price%", String.format("%.2f", price));
            e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.Bought", vars));
        } else if (ChatColor.stripColor(sign.getLine(1)).equalsIgnoreCase(sLineTwo)) {
            //Scan a ticket
            if (!ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(sign.getLine(2))) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.UnknownRide", Collections.singletonMap("%ridename%", sign.getLine(2))));
                return;
            }
            Attraction att = ThemePark.getInstance().getAPI().getAttractionService().getAttraction(sign.getLine(2));

            ItemStack content = e.getPlayer().getInventory().getItemInMainHand();
            if (content.getType() == Material.AIR
                || !content.hasItemMeta()) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.NoTicket"));
                return;
            }

            NBTItem nbtContent = new NBTItem(content);
            if (!nbtContent.hasKey("RideID")) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.NoTicket"));
                return;
            }

            if (!nbtContent.getString("RideID").equals(att.getID())) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.IncorrectTicket"));
                return;
            }

            if (att.getStatus() != Status.OPEN) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.RideClosed"));
                return;
            }

            try {
                String[] locationString = sign.getLine(3).split(":");
                int x = Integer.parseInt(locationString[0]);
                int y = Integer.parseInt(locationString[1]);
                int z = Integer.parseInt(locationString[2]);

                Block b = e.getPlayer().getWorld().getBlockAt(x, y, z);

                if (LGUtil.isOpenable(b)) {
                    LGUtil.openGate(b);
                    Bukkit.getScheduler().scheduleSyncDelayedTask(ThemeParkPlus.getInstance(), () -> LGUtil.closeGate(b), 60L);
                } else {
                    Location tpLoc = new Location(e.getPlayer().getWorld(), x, y, z, e.getPlayer().getLocation().getYaw(), e.getPlayer().getLocation().getPitch());
                    e.getPlayer().teleport(tpLoc);
                }
                e.getPlayer().getInventory().remove(e.getPlayer().getInventory().getItemInMainHand());
                e.getPlayer().updateInventory();
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.Redeemed"));
            } catch (NumberFormatException | ArrayIndexOutOfBoundsException ex) {
                e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.IncorrectSign"));
            }
        }
    }
}
