/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.bausystem.region;

import de.steamwar.core.FlatteningWrapper;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

@Getter
public class GameModeConfig {

    private final boolean loaded;

    /**
     * See gamemode config Times key
     */
    private Times Times = new Times();
    private Schematic Schematic = new Schematic();
    private Arena Arena = new Arena();
    private Server Server = new Server();
    private Techhider Techhider = new Techhider();

    public GameModeConfig(File file) {
        if (file == null || !file.exists()) {
            loaded = false;
            return;
        }
        loaded = true;

        FileConfiguration config = YamlConfiguration.loadConfiguration(file);

        Times.load(config.getConfigurationSection("Times"));
        Schematic.load(config.getConfigurationSection("Schematic"));
        Arena.load(config.getConfigurationSection("Arena"));
        Server.load(config.getConfigurationSection("Server"));
        Techhider.load(config.getConfigurationSection("Techhider"));
    }

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    @Getter
    public static class Times {
        private int PreFightDuration = 30;

        private void load(ConfigurationSection section) {
            PreFightDuration = section.getInt("PreFightDuration", 30);
        }
    }

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    @Getter
    public static class Schematic {
        private Map<Set<Material>, Integer> Limited = new HashMap<>();

        private void load(ConfigurationSection section) {
            for(Map<?, ?> entry : section.getMapList("Limited")) {
                int amount = (Integer) entry.get("Amount");
                Set<String> materials = new HashSet<>((List<String>) entry.get("Materials"));
                if (amount == 0) {
                    materials.forEach(material -> Limited.put(Collections.singleton(Material.getMaterial(material)), 0));
                } else {
                    Limited.put(materials.stream().map(Material::getMaterial).collect(Collectors.toSet()), amount);
                }
            }
        }
    }

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    @Getter
    public static class Arena {
        private boolean NoFloor = false;

        private void load(ConfigurationSection section) {
            NoFloor = section.getBoolean("NoFloor", false);
        }
    }

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    @Getter
    public static class Server {
        private List<String> ChatNames;

        private void load(ConfigurationSection section) {
            ChatNames = section.getStringList("ChatNames");
        }
    }

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    @Getter
    public static class Techhider {
        private boolean Active = false;
        private Material ObfuscateWith = Material.END_STONE;
        private Set<Material> HiddenBlocks = new HashSet<>();
        private Set<String> HiddenBlockEntities = new HashSet<>();

        private void load(ConfigurationSection section) {
            Active = section.getBoolean("Active", false);
            ObfuscateWith = Material.getMaterial(section.getString("ObfuscateWith", "END_STONE"));
            HiddenBlocks = section.getStringList("HiddenBlocks").stream().map(String::toUpperCase).map(FlatteningWrapper.impl::getMaterial).filter(Objects::nonNull).collect(Collectors.toUnmodifiableSet());
            HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(section.getStringList("HiddenBlockEntities")));
        }
    }
}
