package com.yourname.premiumah;

import com.yourname.premiumah.command.AhAdminCommand;
import com.yourname.premiumah.command.AhCommand;
import com.yourname.premiumah.config.ConfigManager;
import com.yourname.premiumah.config.MessageManager;
import com.yourname.premiumah.economy.EconomyService;
import com.yourname.premiumah.economy.NoopEconomyService;
import com.yourname.premiumah.economy.VaultEconomyService;
import com.yourname.premiumah.gui.GuiManager;
import com.yourname.premiumah.listener.ChatInputListener;
import com.yourname.premiumah.listener.InventoryGuiListener;
import com.yourname.premiumah.listener.PlayerSessionListener;
import com.yourname.premiumah.manager.AuctionHouseManager;
import com.yourname.premiumah.manager.ClaimManager;
import com.yourname.premiumah.manager.ListingManager;
import com.yourname.premiumah.storage.StorageManager;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.java.JavaPlugin;

public final class PremiumAHPlugin extends JavaPlugin {
    private ConfigManager configManager;
    private MessageManager messageManager;
    private StorageManager storageManager;
    private ListingManager listingManager;
    private ClaimManager claimManager;
    private EconomyService economyService;
    private AuctionHouseManager auctionHouseManager;
    private GuiManager guiManager;

    @Override
    public void onEnable() {
        this.configManager = new ConfigManager(this);
        configManager.reload();
        this.messageManager = new MessageManager(this, configManager);
        messageManager.reload();

        this.storageManager = new StorageManager(this);
        storageManager.load();
        this.listingManager = new ListingManager(storageManager);
        this.claimManager = new ClaimManager(storageManager);
        listingManager.loadFromStorage();
        claimManager.loadFromStorage();

        this.economyService = createEconomyService();
        economyService.reload();

        this.auctionHouseManager = new AuctionHouseManager(this, configManager, messageManager, storageManager, listingManager, claimManager, economyService);
        this.guiManager = new GuiManager(this, configManager, messageManager, listingManager, claimManager, auctionHouseManager);

        registerCommands();
        registerListeners();
        auctionHouseManager.startTasks();

        if (!auctionHouseManager.marketplaceReady() && configManager.requireEconomy()) {
            getLogger().warning("No usable economy provider was found. Players can open GUIs and claims, but listing and buying are disabled.");
        }
        getLogger().info("Dirt Auctions enabled.");
    }

    @Override
    public void onDisable() {
        if (auctionHouseManager != null) {
            auctionHouseManager.stopTasks();
        }
        Bukkit.getScheduler().cancelTasks(this);
        if (guiManager != null) {
            guiManager.shutdown();
        }
        if (auctionHouseManager != null) {
            auctionHouseManager.saveAll();
        }
        if (storageManager != null) {
            storageManager.close();
        }
        if (listingManager != null) {
            listingManager.clear();
        }
        if (claimManager != null) {
            claimManager.clear();
        }
        HandlerList.unregisterAll(this);
        getLogger().info("Dirt Auctions disabled cleanly.");
    }

    public void reloadPluginState() {
        if (auctionHouseManager != null) {
            auctionHouseManager.stopTasks();
            auctionHouseManager.saveAll();
        }
        if (guiManager != null) {
            guiManager.shutdown();
        }

        configManager.reload();
        messageManager.reload();
        storageManager.load();
        listingManager.loadFromStorage();
        claimManager.loadFromStorage();
        economyService.reload();
        auctionHouseManager.startTasks();
    }

    public ConfigManager configManager() {
        return configManager;
    }

    public MessageManager messageManager() {
        return messageManager;
    }

    public ListingManager listingManager() {
        return listingManager;
    }

    public ClaimManager claimManager() {
        return claimManager;
    }

    public AuctionHouseManager auctionHouseManager() {
        return auctionHouseManager;
    }

    public GuiManager guiManager() {
        return guiManager;
    }

    private EconomyService createEconomyService() {
        if (!configManager.economyEnabled()) {
            getLogger().warning("Economy is disabled in config.yml. Marketplace listing and buying are disabled.");
            return new NoopEconomyService();
        }
        try {
            return new VaultEconomyService(this);
        } catch (NoClassDefFoundError error) {
            getLogger().warning("Vault API is not available. Install Vault or a compatible injector for CMI economy support.");
            return new NoopEconomyService();
        }
    }

    private void registerCommands() {
        AhCommand ahCommand = new AhCommand(guiManager, auctionHouseManager, messageManager);
        PluginCommand ah = getCommand("ah");
        if (ah != null) {
            ah.setExecutor(ahCommand);
            ah.setTabCompleter(ahCommand);
        }

        AhAdminCommand ahAdminCommand = new AhAdminCommand(this, guiManager, auctionHouseManager, listingManager, messageManager);
        PluginCommand ahAdmin = getCommand("ahadmin");
        if (ahAdmin != null) {
            ahAdmin.setExecutor(ahAdminCommand);
            ahAdmin.setTabCompleter(ahAdminCommand);
        }
    }

    private void registerListeners() {
        Bukkit.getPluginManager().registerEvents(new InventoryGuiListener(guiManager), this);
        Bukkit.getPluginManager().registerEvents(new ChatInputListener(guiManager), this);
        Bukkit.getPluginManager().registerEvents(new PlayerSessionListener(guiManager), this);
    }
}
