package com.n3plugins.guardiansrift;

import net.runelite.api.gameval.ItemID;

import java.util.Collection;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

final class GuardiansRiftPouchRules
{
    private static final Set<Integer> DEGRADED_POUCH_IDS = new HashSet<>(Arrays.asList(
            ItemID.RCU_POUCH_MEDIUM_DEGRADE,
            ItemID.RCU_POUCH_LARGE_DEGRADE,
            ItemID.RCU_POUCH_GIANT_DEGRADE,
            ItemID.RCU_POUCH_COLOSSAL_DEGRADE));

    private static final Set<Integer> PREVENTION_IDS = new HashSet<>(Arrays.asList(
            ItemID.SKILLCAPE_RUNECRAFTING,
            ItemID.SKILLCAPE_RUNECRAFTING_TRIMMED,
            ItemID.SKILLCAPE_MAX,
            ItemID.ABYSSAL_LANTERN_REDWOOD));

    private GuardiansRiftPouchRules()
    {
    }

    static int availableSpace(Collection<Integer> itemIds, int runecraftLevel)
    {
        int total = 0;
        if (itemIds.contains(ItemID.RCU_POUCH_COLOSSAL))
        {
            return colossalCapacity(runecraftLevel);
        }
        if (itemIds.contains(ItemID.RCU_POUCH_SMALL))
        {
            total += 3;
        }
        if (itemIds.contains(ItemID.RCU_POUCH_MEDIUM) && runecraftLevel >= 25)
        {
            total += 6;
        }
        if (itemIds.contains(ItemID.RCU_POUCH_LARGE) && runecraftLevel >= 50)
        {
            total += 9;
        }
        if (itemIds.contains(ItemID.RCU_POUCH_GIANT) && runecraftLevel >= 75)
        {
            total += 12;
        }
        return total;
    }

    static int colossalCapacity(int runecraftLevel)
    {
        if (runecraftLevel >= 85)
        {
            return 40;
        }
        if (runecraftLevel >= 75)
        {
            return 27;
        }
        if (runecraftLevel >= 50)
        {
            return 16;
        }
        if (runecraftLevel >= 25)
        {
            return 8;
        }
        return 0;
    }

    static boolean isDegradedPouch(int itemId)
    {
        return DEGRADED_POUCH_IDS.contains(itemId);
    }

    static boolean hasDegradationPrevention(Collection<Integer> equipmentIds)
    {
        for (int itemId : equipmentIds)
        {
            if (PREVENTION_IDS.contains(itemId))
            {
                return true;
            }
        }
        return false;
    }

    static GuardiansRiftRepairRoute chooseRepairRoute(GuardiansRiftPouchRepairPolicy policy,
                                                      GuardiansRiftRepairContext context)
    {
        switch (policy)
        {
            case CORDELIA_ONLY:
                return context.isCordeliaAvailable() ? GuardiansRiftRepairRoute.CORDELIA : GuardiansRiftRepairRoute.NONE;
            case NPC_CONTACT_ONLY:
                return context.isNpcContactReady() ? GuardiansRiftRepairRoute.NPC_CONTACT_DARK_MAGE : GuardiansRiftRepairRoute.NONE;
            case DARK_MAGE_ONLY:
                return context.isDarkMageVisible() ? GuardiansRiftRepairRoute.DARK_MAGE : GuardiansRiftRepairRoute.NONE;
            case CORDELIA_THEN_NPC_CONTACT_THEN_DARK_MAGE:
            default:
                if (context.isCordeliaAvailable())
                {
                    return GuardiansRiftRepairRoute.CORDELIA;
                }
                if (context.isNpcContactReady())
                {
                    return GuardiansRiftRepairRoute.NPC_CONTACT_DARK_MAGE;
                }
                return context.isDarkMageVisible() ? GuardiansRiftRepairRoute.DARK_MAGE : GuardiansRiftRepairRoute.NONE;
        }
    }

    static EnumSet<GuardiansRiftPouchAction> fillActions(int guardianEssence,
                                                         List<GuardiansRiftPouchState> pouches)
    {
        EnumSet<GuardiansRiftPouchAction> actions = EnumSet.noneOf(GuardiansRiftPouchAction.class);
        int remaining = guardianEssence;
        for (GuardiansRiftPouchState pouch : pouches)
        {
            if (remaining <= 0)
            {
                break;
            }
            if (pouch.getFreeSpace() > 0)
            {
                actions.add(fillAction(pouch.getItemId()));
                remaining -= pouch.getFreeSpace();
            }
        }
        return actions;
    }

    static EnumSet<GuardiansRiftPouchAction> emptyActions(int inventoryFreeSlots,
                                                          List<GuardiansRiftPouchState> pouches)
    {
        EnumSet<GuardiansRiftPouchAction> actions = EnumSet.noneOf(GuardiansRiftPouchAction.class);
        int remaining = inventoryFreeSlots;
        for (GuardiansRiftPouchState pouch : pouches)
        {
            if (remaining <= 0)
            {
                break;
            }
            if (pouch.getStoredEssence() > 0)
            {
                actions.add(emptyAction(pouch.getItemId()));
                remaining -= pouch.getStoredEssence();
            }
        }
        return actions;
    }

    private static GuardiansRiftPouchAction fillAction(int itemId)
    {
        if (itemId == ItemID.RCU_POUCH_SMALL) return GuardiansRiftPouchAction.FILL_SMALL;
        if (itemId == ItemID.RCU_POUCH_MEDIUM) return GuardiansRiftPouchAction.FILL_MEDIUM;
        if (itemId == ItemID.RCU_POUCH_LARGE) return GuardiansRiftPouchAction.FILL_LARGE;
        if (itemId == ItemID.RCU_POUCH_GIANT) return GuardiansRiftPouchAction.FILL_GIANT;
        return GuardiansRiftPouchAction.FILL_COLOSSAL;
    }

    private static GuardiansRiftPouchAction emptyAction(int itemId)
    {
        if (itemId == ItemID.RCU_POUCH_SMALL) return GuardiansRiftPouchAction.EMPTY_SMALL;
        if (itemId == ItemID.RCU_POUCH_MEDIUM) return GuardiansRiftPouchAction.EMPTY_MEDIUM;
        if (itemId == ItemID.RCU_POUCH_LARGE) return GuardiansRiftPouchAction.EMPTY_LARGE;
        if (itemId == ItemID.RCU_POUCH_GIANT) return GuardiansRiftPouchAction.EMPTY_GIANT;
        return GuardiansRiftPouchAction.EMPTY_COLOSSAL;
    }
}
