package fr.luc.gamingcore.util;

import fr.luc.gamingcore.Main;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;

/**
 * Gestionnaire centralisé des messages configurables et rechargeables depuis `messages.yml`.
 */
public class MessageManager {

    private final Main plugin;
    private final File messagesFile;
    private FileConfiguration messagesConfig;
    private final Map<String, String> cachedMessages = new ConcurrentHashMap<>();
    private String prefix = "<gradient:#00C9FF:#92FE9D>[Guilde]</gradient> <dark_gray>»</dark_gray> <gray>";

    /**
     * Constructeur du MessageManager.
     *
     * @param plugin Instance principale du plugin.
     */
    public MessageManager(Main plugin) {
        this.plugin = plugin;
        this.messagesFile = new File(plugin.getDataFolder(), "messages.yml");
    }

    /**
     * Charge ou recharge le fichier `messages.yml` depuis le disque.
     */
    public synchronized void reload() {
        if (!messagesFile.exists()) {
            plugin.saveResource("messages.yml", false);
        }

        this.messagesConfig = YamlConfiguration.loadConfiguration(messagesFile);
        this.cachedMessages.clear();

        // Charger les valeurs par défaut depuis le jar si des clés manquent
        InputStream defStream = plugin.getResource("messages.yml");
        if (defStream != null) {
            YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(defStream, StandardCharsets.UTF_8));
            messagesConfig.setDefaults(defConfig);
        }

        this.prefix = messagesConfig.getString("prefix", prefix);
        TextUtil.setPrefix(this.prefix);

        // Mettre en cache toutes les chaînes trouvées
        for (String key : messagesConfig.getKeys(true)) {
            if (messagesConfig.isString(key)) {
                cachedMessages.put(key, Objects.requireNonNull(messagesConfig.getString(key)));
            }
        }

        plugin.getLogger().info("Fichier messages.yml charge avec succes (" + cachedMessages.size() + " messages en cache).");
    }

    /**
     * Récupère un message par sa clé et applique le remplacement des placeholders.
     *
     * @param key          La clé du message dans messages.yml.
     * @param placeholders Paires clé/valeur pour le remplacement (ex: "{guild}", "Valhalla", "{cost}", "1 000 $").
     * @return Le message formaté avec placeholders appliqués.
     */
    public String get(String key, String... placeholders) {
        String msg = cachedMessages.get(key);
        if (msg == null) {
            msg = "<red>[Message manquant: " + key + "]</red>";
        }

        if (placeholders != null && placeholders.length >= 2) {
            for (int i = 0; i < placeholders.length - 1; i += 2) {
                String phKey = placeholders[i];
                String phVal = placeholders[i + 1];
                if (phKey != null && phVal != null) {
                    msg = msg.replace(phKey, phVal);
                }
            }
        }

        return msg;
    }

    /**
     * Envoie un message formaté avec MiniMessage à un émetteur de commande.
     *
     * @param sender       Le destinataire du message.
     * @param key          La clé du message.
     * @param placeholders Paires de placeholders.
     */
    public void send(CommandSender sender, String key, String... placeholders) {
        if (sender == null) return;
        String formatted = get(key, placeholders);
        TextUtil.sendMessage(sender, formatted);
    }

    /**
     * Envoie une notification dans l'Action Bar d'un joueur.
     *
     * @param player       Le joueur destinataire.
     * @param key          La clé du message.
     * @param placeholders Paires de placeholders.
     */
    public void sendActionBar(Player player, String key, String... placeholders) {
        if (player == null) return;
        String formatted = get(key, placeholders);
        TextUtil.sendActionBar(player, formatted);
    }

    /**
     * Obtient le préfixe global actuel.
     *
     * @return La chaîne MiniMessage du préfixe.
     */
    public String getPrefix() {
        return prefix;
    }
}
