package nl.sbdeveloper.themeparkplus.gui;

import com.cryptomorin.xseries.XMaterial;
import fr.minuskube.inv.ClickableItem;
import fr.minuskube.inv.content.InventoryContents;
import fr.minuskube.inv.content.SlotPos;
import nl.iobyte.menuapi.item.ItemBuilder;
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.api.objects.MalfunctionReport;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import nl.sbdeveloper.themeparkplus.util.Inventory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import static nl.sbdeveloper.themeparkplus.util.ConfigUtil.__;

public class MalfunctionGUI extends Inventory {
    private final Attraction att;

    public MalfunctionGUI(Attraction att, Player p) {
        super(1, __(ThemeParkPlus.getSConfig().getFile().getString("Malfunction.GUI.Title").replace("%ridename%", att.getName())));
        this.att = att;
        open(p);
    }

    @Override
    public void init(Player player, InventoryContents contents) {
        contents.set(getSlot("Report"), ClickableItem.of(getItem("Report", __(att.getName())), e -> {
            if (!PlusAPI.isReported(att.getID())) {
                MalfunctionReport malfunctionReport = new MalfunctionReport(att.getID(), player.getUniqueId());
                PlusAPI.addReport(malfunctionReport);
                att.setStatus(Status.MALFUNCTION);

                player.sendMessage(ConfigUtil.getMessage("Malfunction.Reported", Collections.singletonMap("%ride%", att.getName())));
            } else {
                player.sendMessage(ConfigUtil.getMessage("Malfunction.AlreadyReported", Collections.singletonMap("%ride%", att.getName())));
            }
            close(player);
        }));

        contents.set(getSlot("Fix"), ClickableItem.of(getItem("Fix", PlusAPI.getReport(att.getID())), e -> {
            if (PlusAPI.isReported(att.getID())) {

                PlusAPI.removeReport(att.getID());
                att.setStatus(Status.CLOSED);

                player.sendMessage(ConfigUtil.getMessage("Malfunction.Fixed", Collections.singletonMap("%ride%", att.getName())));
            } else {
                player.sendMessage(ConfigUtil.getMessage("Malfunction.AlreadyFixed", Collections.singletonMap("%ride%", att.getName())));
            }
            close(player);
        }));

        contents.set(getSlot("Cancel"), ClickableItem.of(getItem("Cancel"), e -> close(player)));
    }

    private static SlotPos getSlot(String type) {
        return new SlotPos(0, ThemeParkPlus.getSConfig().getFile().getInt("Malfunction.GUI.Buttons." + type + ".Slot")-1);
    }

    private static ItemStack getItem(String type, Object... data) { //data is a string or a report
        String material = ThemeParkPlus.getSConfig().getFile().getString("Malfunction.GUI.Buttons." + type + ".Material");
        String name = ThemeParkPlus.getSConfig().getFile().getString("Malfunction.GUI.Buttons." + type + ".Name");
        List<String> lores = ThemeParkPlus.getSConfig().getFile().getStringList("Malfunction.GUI.Buttons." + type + ".Lores");

        if (material == null || name == null || lores.isEmpty()) return null; //Something is wrong in the config

        List<String> loresFormatted = new ArrayList<>();
        switch (type) {
            case "Report":
                lores.forEach(lore -> loresFormatted.add(lore.replace("%ridename%", (String) data[0])));
                break;
            case "Fix":
                String ridename = ConfigUtil.getMessage("Malfunction.ThisRide");
                String reporter = "-";
                String date = "-";
                String reason = "-";
                if (data[0] != null) {
                    ridename = ThemePark.getInstance().getAPI().getAttractionService().getAttraction(((MalfunctionReport) data[0]).getRideID()).getName();
                    reporter = Bukkit.getOfflinePlayer(((MalfunctionReport) data[0]).getReporterUUID()).getName();
                    date = ((MalfunctionReport) data[0]).getReportDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss"));
                    reason = ((MalfunctionReport) data[0]).getReason();
                }

                for (String lore : lores) {
                    loresFormatted.add(lore.replace("%ridename%", ridename).replace("%reporter%", reporter).replace("%date%", date).replace("%reason%", reason));
                }
                break;
            default:
                break;
        }

        Optional<XMaterial> stack = XMaterial.matchXMaterial(material);
        return stack.map(xMaterial -> new ItemBuilder(xMaterial.parseItem()).setName(name).setLore(loresFormatted).getItem()).orElse(null);
    }
}
