package fr.luc.gamingcore.economy;

import fr.luc.gamingcore.Main;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;

import java.text.NumberFormat;
import java.util.Locale;

/**
 * Gestionnaire d'interaction avec le système économique Vault.
 */
public class EconomyManager {

    private final Main plugin;
    private final NumberFormat numberFormat;

    /**
     * Constructeur de l'EconomyManager.
     *
     * @param plugin Instance principale du plugin.
     */
    public EconomyManager(Main plugin) {
        this.plugin = plugin;
        this.numberFormat = NumberFormat.getNumberInstance(Locale.FRANCE);
        this.numberFormat.setMaximumFractionDigits(2);
        this.numberFormat.setMinimumFractionDigits(0);
    }

    /**
     * Vérifie si le service économique Vault est disponible et connecté.
     *
     * @return true si Vault est chargé avec un provider économique actif.
     */
    public boolean isAvailable() {
        return plugin.getEconomy() != null;
    }

    /**
     * Obtient l'instance sous-jacente de l'économie Vault.
     *
     * @return L'Economy de Vault ou null si non disponible.
     */
    public Economy getVaultEconomy() {
        return plugin.getEconomy();
    }

    /**
     * Obtient le solde financier actuel d'un joueur.
     *
     * @param player Le joueur concerné.
     * @return Le solde du joueur (0.0 si l'économie est indisponible).
     */
    public double getBalance(OfflinePlayer player) {
        if (!isAvailable() || player == null) {
            return 0.0;
        }
        return plugin.getEconomy().getBalance(player);
    }

    /**
     * Vérifie si un joueur possède au moins le montant spécifié.
     *
     * @param player Le joueur à vérifier.
     * @param amount Le montant requis.
     * @return true si le solde du joueur est supérieur ou égal au montant requis.
     */
    public boolean has(OfflinePlayer player, double amount) {
        if (!isAvailable() || player == null || amount <= 0) {
            return false;
        }
        return plugin.getEconomy().has(player, amount);
    }

    /**
     * Débite un montant du compte d'un joueur.
     *
     * @param player Le joueur à débiter.
     * @param amount Le montant à retirer.
     * @return true si la transaction bancaire a réussi, false sinon.
     */
    public boolean withdraw(OfflinePlayer player, double amount) {
        if (!isAvailable() || player == null || amount <= 0) {
            return false;
        }
        EconomyResponse response = plugin.getEconomy().withdrawPlayer(player, amount);
        return response.transactionSuccess();
    }

    /**
     * Crédite un montant sur le compte d'un joueur.
     *
     * @param player Le joueur à créditer.
     * @param amount Le montant à ajouter.
     * @return true si la transaction bancaire a réussi, false sinon.
     */
    public boolean deposit(OfflinePlayer player, double amount) {
        if (!isAvailable() || player == null || amount <= 0) {
            return false;
        }
        EconomyResponse response = plugin.getEconomy().depositPlayer(player, amount);
        return response.transactionSuccess();
    }

    /**
     * Formate un montant numérique en chaîne lisible avec séparateurs de milliers et symbole monétaire (ex: "1 250 $").
     *
     * @param amount Le montant à formater.
     * @return La chaîne formatée.
     */
    public String format(double amount) {
        if (isAvailable()) {
            try {
                return plugin.getEconomy().format(amount);
            } catch (Throwable ignored) {
                // Fallback si le provider d'économie (ex: EssentialsX) n'est pas encore initialisé
            }
        }
        return numberFormat.format(amount) + " $";
    }
}
