package nl.sbdeveloper.themeparkplus.api;

import com.cryptomorin.xseries.XMaterial;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import de.tr7zw.changeme.nbtapi.NBTItem;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import nl.sbdeveloper.themeparkplus.api.objects.Gate;
import nl.sbdeveloper.themeparkplus.api.objects.MalfunctionReport;
import nl.sbdeveloper.themeparkplus.api.objects.WaitingRow;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import nl.sbdeveloper.themeparkplus.util.WGUtil;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.*;

public class PlusAPI {
    private static final HashMap<Location, Gate> gates = new HashMap<>();
    private static final HashMap<String, WaitingRow> rows = new HashMap<>();
    private static final HashMap<String, MalfunctionReport> reports = new HashMap<>();

    private PlusAPI() {}

    public static void addReport(MalfunctionReport report) {
        reports.put(report.getRideID(), report);
    }

    public static void removeReport(String rideID) {
        reports.remove(rideID);
    }

    public static MalfunctionReport getReport(String rideID) {
        return reports.get(rideID);
    }

    public static boolean isReported(String rideID) {
        return reports.containsKey(rideID);
    }

    public static Map<String, MalfunctionReport> getReports() {
        return reports;
    }

    /**
     * Add a gate
     *
     * @param gate The gate
     */
    public static void addGate(Gate gate) {
        gates.put(gate.getLoc(), gate);
    }

    /**
     * Remove a gate
     *
     * @param gate The gate
     */
    public static void removeGate(Gate gate) {
        gates.remove(gate.getLoc());
    }

    /**
     * Check if a location is a gate
     *
     * @param loc The location
     * @return true/false
     */
    public static boolean isGate(Location loc) {
        return gates.containsKey(loc);
    }

    /**
     * Get a gate by the location
     *
     * @param loc The location
     * @return The gate
     */
    public static Gate getGate(Location loc) {
        return gates.get(loc);
    }

    /**
     * Get all the gates
     *
     * @return Map with location and gate
     */
    public static Map<Location, Gate> getGates() {
        return gates;
    }

    /**
     * Add a row
     *
     * @param row The row
     */
    public static void addRow(WaitingRow row) {
        rows.put(row.getRideID(), row);
    }

    /**
     * Remove a row
     *
     * @param row The row
     */
    public static void removeRow(WaitingRow row) {
        rows.remove(row.getRideID());
    }

    /**
     * Check if a location is a row
     *
     * @param rideID The rideID
     * @return true/false
     */
    public static boolean isRow(String rideID) {
        return rows.containsKey(rideID);
    }

    /**
     * Get a row by the rideid
     *
     * @param rideID The rideID
     * @return The row
     */
    public static WaitingRow getRow(String rideID) {
        return rows.get(rideID);
    }

    /**
     * Get a row by the location
     *
     * @param loc The location
     * @return The row
     */
    public static WaitingRow getRow(Location loc) {
        if (loc == null) return null;

        List<ProtectedRegion> regions = WGUtil.getRegionsInLocation(loc);
        for (WaitingRow row : rows.values()) {
            if (regions.stream().anyMatch(region -> region.getId().equalsIgnoreCase(row.getRegionID()))) {
                return row;
            }
        }
        return null;
    }

    /**
     * Get a row by the sign location
     *
     * @param signLoc The sign location
     * @return The row
     */
    public static Optional<WaitingRow> getRowBySign(Location signLoc) {
        return rows.values().stream().filter(row -> row.getSignLocations().contains(signLoc)).findFirst();
    }

    /**
     * Get all the rows
     *
     * @return Map with location and rows
     */
    public static Map<String, WaitingRow> getRows() {
        return rows;
    }

    /**
     * Get the ticket itemstack
     *
     * @param att The attraction
     *
     * @return The ticket as ItemStack
     */
    public static ItemStack getFastpassTicket(nl.iobyte.themepark.api.attraction.objects.Attraction att) {
        String ticketName = ConfigUtil.__(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.Item.DisplayName"));

        ItemStack ticket = XMaterial.PAPER.parseItem();
        if (ticket == null) return null;
        ItemMeta meta = ticket.getItemMeta();
        if (meta == null) return null;
        meta.setDisplayName(ticketName);
        List<String> ticketLores = ConfigUtil.getLore("Fastpass.Item.Lore", Collections.singletonMap("%ridename%", att.getName()));
        meta.setLore(ticketLores);
        ticket.setItemMeta(meta);

        NBTItem item = new NBTItem(ticket);
        item.setString("RideID", att.getID());
        ticket = item.getItem();
        return ticket;
    }
}
