package org.redcastlemedia.multitallented.civs.items;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.redcastlemedia.multitallented.civs.Civs;
import org.redcastlemedia.multitallented.civs.CivsSingleton;
import org.redcastlemedia.multitallented.civs.ConfigManager;
import org.redcastlemedia.multitallented.civs.civclass.ClassType;
import org.redcastlemedia.multitallented.civs.civilians.Civilian;
import org.redcastlemedia.multitallented.civs.civilians.CivilianManager;
import org.redcastlemedia.multitallented.civs.regions.RegionType;
import org.redcastlemedia.multitallented.civs.regions.RegionUpkeep;
import org.redcastlemedia.multitallented.civs.spells.SpellType;
import org.redcastlemedia.multitallented.civs.towns.Town;
import org.redcastlemedia.multitallented.civs.towns.TownManager;
import org.redcastlemedia.multitallented.civs.towns.TownType;
import org.redcastlemedia.multitallented.civs.util.Constants;
import org.redcastlemedia.multitallented.civs.util.FallbackConfigUtil;
import org.redcastlemedia.multitallented.civs.util.Util;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;

import java.io.File;
import java.util.*;
import java.util.logging.Level;
import java.util.regex.Pattern;

@CivsSingleton(priority = CivsSingleton.SingletonLoadPriority.HIGHER)
public class ItemManager {
    private static ItemManager itemManager;
    private HashMap<String, CivItem> itemTypes = new HashMap<>();

    public static ItemManager getInstance() {
        if (itemManager == null) {
            itemManager = new ItemManager();
            itemManager.loadAllItemTypes();
        }
        return itemManager;
    }

    public void reload() {
        itemTypes.clear();
        loadAllItemTypes();
    }

    private void loadAllItemTypes() {
        final String ITEM_TYPES_FOLDER_NAME = Constants.ITEM_TYPES;
        String resourcePath = "resources." + ConfigManager.getInstance().getDefaultConfigSet() + "." + ITEM_TYPES_FOLDER_NAME;
        Reflections reflections = new Reflections(resourcePath, new ResourcesScanner());
        for (String fileName : reflections.getResources(Pattern.compile(".*\\.yml"))) {
            loopThroughResources("/" + fileName);
        }
        File itemTypesFolder = new File(Civs.dataLocation, ITEM_TYPES_FOLDER_NAME);
        if (itemTypesFolder.exists()) {
            for (File file : itemTypesFolder.listFiles()) {
                String itemName = file.getName().replace(".yml", "").toLowerCase();
                if (itemTypes.containsKey(itemName) &&
                        itemTypes.get(itemName).getItemType() != CivItem.ItemType.FOLDER) {
                    continue;
                }
                loopThroughTypeFiles(file, null);
            }
        }
    }

    private void loopThroughResources(String path) {
        String relativePath = path.replace("/resources/" + ConfigManager.getInstance().getDefaultConfigSet(), "");
        String[] pathSplit = relativePath.split("/");
        String currentFileName = pathSplit[pathSplit.length - 1];
        try {
            FolderType folderType = null;
            for (String currentFolder : pathSplit) {
                if (currentFolder.isEmpty() || Constants.ITEM_TYPES.equals(currentFolder) ||
                        currentFolder.equals(currentFileName)) {
                    continue;
                }
                if (!ItemManager.getInstance().itemTypes.containsKey(currentFolder.replace(Constants.INVISIBLE, "").toLowerCase())) {
                    boolean isVisible = relativePath.substring(0, relativePath.lastIndexOf(currentFolder) + currentFolder.length())
                            .contains(Constants.INVISIBLE);
                    FolderType currentFolderType = createFolder(currentFolder.toLowerCase(), !isVisible);
                    if (folderType != null) {
                        folderType.getChildren().add(currentFolderType);
                    }
                    folderType = currentFolderType;
                } else {
                    folderType = (FolderType) ItemManager.getInstance().getItemType(currentFolder.toLowerCase());
                }
            }

            File file = new File(Civs.dataLocation, relativePath);
            FileConfiguration typeConfig = FallbackConfigUtil.getConfigFullPath(file, path);
            if (!typeConfig.getBoolean("enabled", true)) {
                return;
            }
            String type = typeConfig.getString("type",Constants.REGION);
            CivItem civItem = null;
            String itemName = currentFileName.replace(".yml", "").toLowerCase();
            if (Constants.REGION.equals(type)) {
                civItem = loadRegionType(typeConfig, itemName);
            } else if ("spell".equals(type)) {
                civItem = loadSpellType(typeConfig, itemName);
            } else if ("class".equals(type)) {
                civItem = loadClassType(typeConfig, itemName);
            } else if ("town".equals(type)) {
                civItem = loadTownType(typeConfig, itemName);
            }
            if (folderType != null) {
                folderType.getChildren().add(civItem);
            }
        } catch (Exception e) {
            Civs.logger.log(Level.SEVERE, "Unable to read from {0}", currentFileName);
            Civs.logger.log(Level.SEVERE, "Exception during file read", e);
        }
    }

    private FolderType createFolder(String currentFileName, boolean invisible) {
        String folderName = currentFileName.replace(Constants.INVISIBLE, "");
        FolderType folderType = new FolderType(new ArrayList<>(),
                folderName,
                ConfigManager.getInstance().getFolderIcon(folderName.toLowerCase()),
                0,
                null,
                new ArrayList<>(),
                invisible,
                1);
        itemTypes.put(folderName.toLowerCase(), folderType);
        return folderType;
    }

    private void loopThroughTypeFiles(File file, List<CivItem> parentList) {
        try {
            if (file.isDirectory() && !file.getName().contains(".yml")) {
                List<CivItem> currParentList;
                if (ItemManager.getInstance().getItemType(file.getName().toLowerCase()) != null) {
                    FolderType folderType = (FolderType) ItemManager.getInstance().getItemType(file.getName().toLowerCase());
                    currParentList = folderType.getChildren();
                } else {
                    currParentList = new ArrayList<>();
                }

                for (File pFile : file.listFiles()) {
                    loopThroughTypeFiles(pFile, currParentList);
                }
                if (itemTypes.containsKey(file.getName().toLowerCase())) {
                    return;
                }
                String folderName = file.getName().replace(Constants.INVISIBLE, "");
                FolderType folderType = new FolderType(new ArrayList<>(),
                        folderName,
                        ConfigManager.getInstance().getFolderIcon(folderName.toLowerCase()),
                        0,
                        null,
                        currParentList,
                        !file.getName().contains("invisible"),
                        1);
                itemTypes.put(folderName.toLowerCase(), folderType);
                if (parentList != null) {
                    parentList.add(folderType);
                }
            } else {
                String name = file.getName().replace(".yml", "").toLowerCase();
                if (itemTypes.containsKey(name)) {
                    return;
                }
                try {
                    FileConfiguration typeConfig = new YamlConfiguration();
                    typeConfig.load(file);
                    if (!typeConfig.getBoolean("enabled", true)) {
                        return;
                    }
                    String type = typeConfig.getString("type","region");
                    CivItem civItem = null;
                    String itemName = file.getName().replace(".yml", "").toLowerCase();
                    if (type.equals("region")) {
                        civItem = loadRegionType(typeConfig, itemName);
                    } else if (type.equals("spell")) {
                        civItem = loadSpellType(typeConfig, itemName);
                    } else if (type.equals("class")) {
                        civItem = loadClassType(typeConfig, itemName);
                    } else if (type.equals("town")) {
                        civItem = loadTownType(typeConfig, itemName);
                    }
                    if (civItem != null && parentList != null) {
                        parentList.add(civItem);
                    }
                } catch (Exception e) {
                    Civs.logger.severe("Unable to read from " + file.getName());
                    e.printStackTrace();
                }
            }
        } catch (NullPointerException npe) {
            Civs.logger.warning("No region types found in " + file.getName());
            return;
        }
    }
    public CivItem loadClassType(FileConfiguration config, String name) {
        //TODO load classestype properly
        CVItem icon = CVItem.createCVItemFromString(config.getString("icon", Material.CHEST.name()));
        ClassType civItem = new ClassType(
                config.getStringList("reqs"),
                name,
                icon,
                CVItem.createCVItemFromString(config.getString("shop-icon", config.getString("icon", Material.CHEST.name()))),
                config.getDouble("price", 0),
                config.getString("permission"),
                config.getStringList("children"),
                config.getStringList("groups"),
                config.getInt("mana-per-second", 1),
                config.getInt("max-mana", 100),
                config.getBoolean("is-in-shop", true),
                config.getInt("level", 1));

        itemTypes.put(name, civItem);
        return civItem;
    }

    public CivItem loadSpellType(FileConfiguration config, String name) {
        CVItem icon = CVItem.createCVItemFromString(config.getString("icon", Material.CHEST.name()));
        SpellType spellType = new SpellType(
                config.getStringList("reqs"),
                name,
                icon.getMat(),
                CVItem.createCVItemFromString(config.getString("shop-icon", config.getString("icon", Material.CHEST.name()))),
                config.getInt("qty", 0),
                config.getInt("min", 0),
                config.getInt("max", -1),
                config.getDouble("price", 0),
                config.getString("permission"),
                config.getStringList("groups"),
                config,
                config.getBoolean("is-in-shop", true),
                config.getInt("level", 1));
        itemTypes.put(name.toLowerCase(), spellType);
        return spellType;
    }

    private HashMap<String, Integer> convertListToMap(List<String> inputList) {
        HashMap<String, Integer> returnMap = new HashMap<>();
        for (String currentString : inputList) {
            String[] splitString = currentString.split(":");
            if (splitString.length != 2) {
                returnMap.put(splitString[0], 1);
            } else {
                returnMap.put(splitString[0], Integer.parseInt(splitString[1]));
            }
        }
        return returnMap;
    }

    public TownType loadTownType(FileConfiguration config, String name) throws NullPointerException {
        CVItem icon = CVItem.createCVItemFromString(config.getString("icon", Material.STONE.name()));
        HashMap<String, String> effects = new HashMap<>();
        List<String> configEffects = config.getStringList("effects");
        for (String effectString : configEffects) {
            if (effectString.contains(":")) {
                String[] effectSplit = effectString.split(":");
                effects.put(effectSplit[0], effectSplit[1]);
            } else {
                effects.put(effectString, null);
            }
        }
        int buildRadius = config.getInt("build-radius", 20);
        TownType townType = new TownType(
                name,
                icon,
                CVItem.createCVItemFromString(config.getString("shop-icon", config.getString("icon", Material.CHEST.name()))),
                config.getStringList("pre-reqs"),
                config.getInt("qty", 0),
                config.getInt("min",0),
                config.getInt("max", -1),
                config.getDouble("price", 0),
                config.getString("permission"),
                convertListToMap(config.getStringList("build-reqs")),
                convertListToMap(config.getStringList("limits")),
                effects,
                buildRadius,
                config.getInt("build-radius-y", buildRadius),
                config.getStringList("critical-build-reqs"),
                config.getInt("power", 200),
                config.getInt("max-power", 1000),
                config.getStringList("groups"),
                config.getString("child"),
                config.getInt("child-population", 0),
                config.getBoolean("is-in-shop", true),
                config.getInt("level", 1));
        townType.setDefaultGovType(config.getString("gov-type", ConfigManager.getInstance().getDefaultGovernmentType()));
        itemTypes.put(Util.getValidFileName(name).toLowerCase(), townType);
        return townType;
    }

    public RegionType loadRegionType(FileConfiguration config, String name) {
        CVItem icon = CVItem.createCVItemFromString(config.getString("icon", Material.CHEST.name()));
        List<List<CVItem>> reqs = new ArrayList<>();
        for (String req : config.getStringList("build-reqs")) {
            reqs.add(CVItem.createListFromString(req));
        }
        List<RegionUpkeep> upkeeps = new ArrayList<>();
        ConfigurationSection upkeepSection = config.getConfigurationSection("upkeep");
        if (upkeepSection != null) {
            for (String key : upkeepSection.getKeys(false)) {
                List<List<CVItem>> reagents = new ArrayList<>();
                for (String reagent : config.getStringList("upkeep." + key + ".reagents")) {
                    reagents.add(CVItem.createListFromString(reagent));
                }
                List<List<CVItem>> inputs = new ArrayList<>();
                for (String input : config.getStringList("upkeep." + key + ".input")) {
                    inputs.add(CVItem.createListFromString(input));
                }
                List<List<CVItem>> outputs = new ArrayList<>();
                for (String output : config.getStringList("upkeep." + key + ".output")) {
                    outputs.add(CVItem.createListFromString(output));
                }
                double payout = config.getDouble("upkeep." + key + ".payout", 0);
                double exp = config.getDouble("upkeep." + key + ".exp", 0);
                String perm = config.getString("upkeep." + key + ".perm", "");
                RegionUpkeep regionUpkeep = new RegionUpkeep(reagents, inputs, outputs, payout, exp, perm);
                regionUpkeep.setPowerReagent(config.getInt("upkeep." + key + ".power-reagent", 0));
                regionUpkeep.setPowerInput(config.getInt("upkeep." + key + ".power-input", 0));
                regionUpkeep.setPowerOutput(config.getInt("upkeep." + key + ".power-output", 0));
                if (config.isSet("upkeep." + key + ".command")) {
                    regionUpkeep.setCommand(config.getString("upkeep." + key + ".command"));
                }
                upkeeps.add(regionUpkeep);
            }
        }
        HashSet<String> townSet;
        if (config.isSet("towns")) {
            townSet = new HashSet<>(config.getStringList("towns"));
        } else {
            townSet = new HashSet<>();
        }
        HashMap<String, String> effects = new HashMap<>();
        for (String s : config.getStringList("effects")) {
            String[] effectSplit = s.split(":");
            if (effectSplit.length > 1) {
                effects.put(effectSplit[0], effectSplit[1]);
            } else {
                effects.put(s, null);
            }
        }
        int buildRadius = config.getInt("build-radius", 5);
        int buildRadiusX = config.getInt("build-radius-x", buildRadius);
        int buildRadiusY = config.getInt("build-radius-y", buildRadius);
        int buildRadiusZ = config.getInt("build-radius-z", buildRadius);
        int effectRadius = config.getInt("effect-radius", buildRadius);
        List<String> rebuild = config.getStringList("rebuild");
        if (rebuild.isEmpty()) {
            rebuild = new ArrayList<>();
            String onlyRebuild = config.getString("rebuild");
            if (onlyRebuild != null && !onlyRebuild.isEmpty()) {
                rebuild.add(onlyRebuild);
            }
        }
        Set<Biome> biomes = new HashSet<>();
        if (config.isSet("biomes")) {
            for (String s : config.getStringList("biomes")) {
                biomes.add(Biome.valueOf(s));
            }
        }
        HashSet<String> worlds = new HashSet<>();
        if (config.isSet("worlds")) {
            worlds.addAll(config.getStringList("worlds"));
        }
        RegionType regionType = new RegionType(
                name,
                icon,
                CVItem.createCVItemFromString(config.getString("shop-icon", config.getString("icon", Material.CHEST.name()))),
                config.getStringList("pre-reqs"),
                config.getInt("qty", 0),
                config.getInt("min", 0),
                config.getInt("max", -1),
                config.getDouble("price", 0),
                config.getString("permission"),
                reqs,
                upkeeps,
                effects,
                buildRadius,
                buildRadiusX,
                buildRadiusY,
                buildRadiusZ,
                effectRadius,
                rebuild,
                townSet,
                biomes,
                config.getLong("period", 0),
                config.getString("period", "false").equals("daily"),
                config.getStringList("groups"),
                config.getBoolean("is-in-shop", true),
                config.getBoolean("rebuild-required", false),
                config.getInt("level",1),
                worlds);
        if (config.isSet("commands-on-creation")) {
            regionType.getCommandsOnCreation().addAll(config.getStringList("commands-on-creation"));
        }
        if (config.isSet("commands-on-destruction")) {
            regionType.getCommandsOnCreation().addAll(config.getStringList("commands-on-destruction"));
        }
        if (config.isSet("dynmap-marker")) {
            regionType.setDynmapMarkerKey(config.getString("dynmap-marker"));
        }
        itemTypes.put(name.toLowerCase(), regionType);
        return regionType;
    }

    public Map<String, Integer> loadCivItems(FileConfiguration civConfig) {
        HashMap<String, Integer> items = new HashMap<>();
        ConfigurationSection configurationSection = civConfig.getConfigurationSection("items");
        if (configurationSection == null) {
            return items;
        }
        for (String key : configurationSection.getKeys(false)) {
            CivItem currentItem = getItemType(key);
            if (currentItem == null) {
                continue;
            }
            items.put(key, civConfig.getInt("items." + key));
        }
        return items;
    }

    public CivItem getItemType(String name) {
        String processedName = ChatColor.stripColor(name);
        return itemTypes.get(processedName.replace(
                ChatColor.stripColor(ConfigManager.getInstance().getCivsItemPrefix()), "").toLowerCase());
    }

    public List<CivItem> getItemGroup(String groupName) {
        ArrayList<CivItem> returnList = new ArrayList<>();

        for (CivItem item : this.itemTypes.values()) {
            if (item.getGroups().contains(groupName)) {
                returnList.add(item);
            }
        }

        return returnList;
    }

    public Map<String, Integer> getNewItems(Civilian civilian) {
        HashMap<String, Integer> newItems = new HashMap<>();
        for (CivItem civItem : itemTypes.values()) {
            if (civItem.getItemType() == CivItem.ItemType.FOLDER ||
                    civilian.getStashItems().containsKey(civItem.getProcessedName()) ||
                    !hasItemUnlocked(civilian, civItem)) {
                continue;
            }
            int count = civilian.getCountStashItems(civItem.getProcessedName()) +
                    civilian.getCountNonStashItems(civItem.getProcessedName());
            if (civItem.getCivQty() > 0) {
                newItems.put(civItem.getProcessedName(), civItem.getQty());
            } else if (civItem.getCivMin() > 0 && civItem.getCivMin() > count) {
                newItems.put(civItem.getProcessedName(), civItem.getCivMin() - count);
            }
        }
        return newItems;
    }

    public List<CivItem> getShopItems(Civilian civilian, CivItem parent) {
        return getAllItemsWithParent(civilian, parent, true);
    }
    private List<CivItem> getAllItemsWithParent(Civilian civilian, CivItem parent, boolean isShop) {
        List<CivItem> returnList = new ArrayList<>();
        HashSet<CivItem> checkList = new HashSet<>();
        if (parent == null) {
            for (Map.Entry<String, CivItem> entry : itemTypes.entrySet()) {
                CivItem civItem = entry.getValue();
                if (civItem.getItemType() == CivItem.ItemType.FOLDER) {
                    checkList.addAll(((FolderType) civItem).getChildren());
                } else if (civItem.getItemType() == CivItem.ItemType.CLASS) {
                    for (String key : ((ClassType) civItem).getChildren()) {
                        if (getItemType(key) != null) {
                            checkList.add(getItemType(key));
                        }
                    }
                }
            }
            for (CivItem civItem : itemTypes.values()) {
                if (checkList.contains(civItem)) {
                    continue;
                }
                returnList.add(civItem);
            }
        } else {
            if (parent.getItemType().equals(CivItem.ItemType.FOLDER)) {
                returnList.addAll(((FolderType) parent).getChildren());
            } else if (parent.getItemType().equals(CivItem.ItemType.CLASS)) {
                for (String key : ((ClassType) parent).getChildren()) {
                    if (getItemType(key) != null) {
                        checkList.add(getItemType(key));
                    }
                }
            }
        }
        returnList.removeAll(checkList);
        checkList.clear();
        for (CivItem item : returnList) {
            if (!hasItemUnlocked(civilian, item) ||
                    (isShop && !item.getInShop())) {
                checkList.add(item);
            }
        }
        returnList.removeAll(checkList);

        checkList.clear();
        for (CivItem currentItem : returnList) {
            if (currentItem.getItemType() != CivItem.ItemType.FOLDER) {
                continue;
            }
            if (getAllItemsWithParent(civilian, currentItem, true).isEmpty()) {
                checkList.add(currentItem);
            }
        }
        returnList.removeAll(checkList);
        return returnList;
    }

    public boolean hasItemUnlocked(Civilian civilian, CivItem civItem) {
        if (civItem.getCivReqs().isEmpty()) {
            return true;
        }
        Player player = Bukkit.getPlayer(civilian.getUuid());
        if (player == null) {
            return false;
        }
        outer: for (String reqString : civItem.getCivReqs()) {
            for (String req : reqString.split("\\|")) {
                //perm=civs.admin
                if (req.startsWith("perm=")) {
                    String permission = req.replace("perm=", "");
                    if (Civs.perm != null &&
                            Civs.perm.has(player, permission)) {
                        continue outer;
                    } else {
                        continue;
                    }
                //member=settlement:town:...
                } else if (req.startsWith("member=")) {
                    String[] townTypeStrings = req.replace("member=", "").split(":");
                    Set<String> townTypes = new HashSet<>(Arrays.asList(townTypeStrings));
                    for (Town town : TownManager.getInstance().getTowns()) {
                        if (townTypes.contains(town.getType()) &&
                                town.getPeople().containsKey(civilian.getUuid())) {
                            continue outer;
                        }
                    }
                    continue;
                //population=15
                } else if (req.startsWith("population=")) {
                    int pop = Integer.parseInt(req.replace("population=", ""));
                    for (Town town : TownManager.getInstance().getTowns()) {
                        if (!town.getPeople().containsKey(civilian.getUuid()) ||
                                !town.getPeople().get(civilian.getUuid()).contains(Constants.OWNER)) {
                            continue;
                        }
                        if (pop <= town.getPopulation()) {
                            continue outer;
                        }
                    }
                    continue;
                }
                String[] splitReq = req.split(":");
                //house:???
                if (splitReq.length < 2) {
                    if (civilian.getCountStashItems(splitReq[0]) > 0 ||
                            civilian.getCountNonStashItems(splitReq[0]) > 0) {
                        continue outer;
                    } else {
                        continue;
                    }
                }
                String[] reqParams = splitReq[1].split("=");
                //shack:built=1
                if (reqParams[0].equals("built")) {
                    if (civilian.getCountNonStashItems(splitReq[0]) >= Integer.parseInt(reqParams[1])) {
                        continue outer;
                    } else {
                        continue;
                    }
                //bash:level=4
                } else if (reqParams[0].equals("level")) {
                    CivItem reqItem = itemManager.getItemType(splitReq[0]);
                    if (reqItem == null || civilian.getExp().get(reqItem) == null) {
                        continue;
                    }
                    int level = civilian.getLevel(reqItem);
                    if (level >= Integer.parseInt(reqParams[1])) {
                        continue outer;
                    } else {
                        continue;
                    }
                //house:has=2
                } else if (reqParams[0].equals("has")) {
                    if (civilian.getCountStashItems(splitReq[0]) >= Integer.parseInt(reqParams[1]) ||
                            civilian.getCountNonStashItems(splitReq[0]) > Integer.parseInt(reqParams[1])) {
                        continue outer;
                    } else {
                        continue;
                    }
                //hamlet:population=15
                } else if (reqParams[0].equals("population")) {
                    int requirement = Integer.parseInt(reqParams[1]);
                    for (Town town : TownManager.getInstance().getTowns()) {
                        if (!town.getType().equalsIgnoreCase(splitReq[0]) ||
                                !town.getPeople().containsKey(civilian.getUuid()) ||
                                !town.getPeople().get(civilian.getUuid()).contains(Constants.OWNER)) {
                            continue;
                        }
                        if (requirement <= town.getPopulation()) {
                            continue outer;
                        }
                    }
                    continue;
                }
            }
            return false;
        }
        return true;
    }

    public void addMinItems(Civilian civilian) {
        ArrayList<CivItem> addItems = new ArrayList<>();
        for (CivItem civItem : itemTypes.values()) {
            if (civItem.getCivMin() < 1) {
                continue;
            }
            int count = civilian.getCountStashItems(civItem.getProcessedName());
            if (CivItem.ItemType.REGION == civItem.getItemType()) {
                count += civilian.getCountRegions(civItem.getProcessedName());
            }
            if (count >= civItem.getCivMin()) {
                continue;
            }
            if (hasItemUnlocked(civilian, civItem)) {
                int add = 0;
                while(count + add < civItem.getCivMin()) {
                    addItems.add(civItem);
                    add++;
                }
            }
        }
        for (CivItem civItem : addItems) {
            civilian.getStashItems().put(civItem.getProcessedName(), civItem.getQty());
        }
        CivilianManager.getInstance().saveCivilian(civilian);
    }

    public ArrayList<CivItem> getItemsByLevel(int level) {
        ArrayList<CivItem> itemSet = new ArrayList<>();
        for (CivItem civItem : this.itemTypes.values()) {
            if (civItem.getLevel() == level && civItem.getInShop()) {
                itemSet.add(civItem);
            }
        }
        return itemSet;
    }
}