import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import org.server_info.MOTD.MOTD
import java.util.*
import org.bukkit.conversations.*
import org.bukkit.entity.Player

class MOTDGuiHandler(private val plugin: MOTD) : Listener {

    private val editingSessions = HashMap<UUID, EditSession>()

    data class EditSession(
        val index: Int,
        val action: String // "edit" or "add"
    )

    // Main quotes management GUI
    fun openQuotesGui(player: Player) {
        val quotes = plugin.getCurrentQuotes()
        val inventorySize = ((quotes.size / 9) + 2) * 9 // Round up to nearest multiple of 9, plus action buttons row

        val inventory = Bukkit.createInventory(null, inventorySize, "MOTD Quotes Manager")

        // Add quotes
        quotes.forEachIndexed { index, quoteItem ->
            val item = ItemStack(Material.PAPER)
            val meta = item.itemMeta

            if (meta != null) {
                meta.setDisplayName("${quoteItem.color}Quote #${index + 1}")

                val lore = ArrayList<String>()
                lore.add("${ChatColor.WHITE}${quoteItem.text}")
                lore.add("${ChatColor.GRAY}Color: ${quoteItem.color.replace('§', '&')}")
                lore.add("")
                lore.add("${ChatColor.YELLOW}Click to edit")
                lore.add("${ChatColor.RED}Shift-click to delete")

                meta.lore = lore
                item.itemMeta = meta
            }

            inventory.setItem(index, item)
        }

        // Add action buttons at the bottom
        val addButton = ItemStack(Material.EMERALD_BLOCK)
        val addMeta = addButton.itemMeta
        if (addMeta != null) {
            addMeta.setDisplayName("${ChatColor.GREEN}Add New Quote")
            addButton.itemMeta = addMeta
        }

        val refreshButton = ItemStack(Material.GOLD_BLOCK)
        val refreshMeta = refreshButton.itemMeta
        if (refreshMeta != null) {
            refreshMeta.setDisplayName("${ChatColor.YELLOW}Refresh MOTD Now")
            refreshButton.itemMeta = refreshMeta
        }

        val saveButton = ItemStack(Material.DIAMOND_BLOCK) // New save button
        val saveMeta = saveButton.itemMeta
        if (saveMeta != null) {
            saveMeta.setDisplayName("${ChatColor.BLUE}Save Quotes")
            saveButton.itemMeta = saveMeta
        }

        val exitButton = ItemStack(Material.REDSTONE_BLOCK)
        val exitMeta = exitButton.itemMeta
        if (exitMeta != null) {
            exitMeta.setDisplayName("${ChatColor.RED}Close")
            exitButton.itemMeta = exitMeta
        }

        // Set buttons in the last row
        val lastRowStart = inventorySize - 9
        inventory.setItem(lastRowStart + 1, addButton)
        inventory.setItem(lastRowStart + 3, refreshButton)
        inventory.setItem(lastRowStart + 5, saveButton) // Add new save button
        inventory.setItem(lastRowStart + 7, exitButton)

        player.openInventory(inventory)
    }

    // GUI for selecting a color
    fun openColorSelectorGui(player: Player, index: Int, action: String) {
        val inventory = Bukkit.createInventory(null, 27, "Select Quote Color")

        // Store the user's editing session
        editingSessions[player.uniqueId] = EditSession(index, action)

        // Add color options
        addColorOption(inventory, 0, Material.WHITE_WOOL, "White", "§f")
        addColorOption(inventory, 1, Material.ORANGE_WOOL, "Gold", "§6")
        addColorOption(inventory, 2, Material.MAGENTA_WOOL, "Light Purple", "§d")
        addColorOption(inventory, 3, Material.LIGHT_BLUE_WOOL, "Aqua", "§b")
        addColorOption(inventory, 4, Material.YELLOW_WOOL, "Yellow", "§e")
        addColorOption(inventory, 5, Material.LIME_WOOL, "Green", "§a")
        addColorOption(inventory, 6, Material.PINK_WOOL, "Light Red", "§c")
        addColorOption(inventory, 7, Material.GRAY_WOOL, "Dark Gray", "§8")
        addColorOption(inventory, 8, Material.LIGHT_GRAY_WOOL, "Gray", "§7")
        addColorOption(inventory, 9, Material.CYAN_WOOL, "Dark Aqua", "§3")
        addColorOption(inventory, 10, Material.PURPLE_WOOL, "Dark Purple", "§5")
        addColorOption(inventory, 11, Material.BLUE_WOOL, "Blue", "§9")
        addColorOption(inventory, 12, Material.BROWN_WOOL, "Brown", "§6") // Using gold as closest to brown
        addColorOption(inventory, 13, Material.GREEN_WOOL, "Dark Green", "§2")
        addColorOption(inventory, 14, Material.RED_WOOL, "Dark Red", "§4")
        addColorOption(inventory, 15, Material.BLACK_WOOL, "Black", "§0")

        // Add formatting options
        addColorOption(inventory, 18, Material.IRON_INGOT, "Bold", "§l")
        addColorOption(inventory, 19, Material.GOLD_INGOT, "Italic", "§o")
        addColorOption(inventory, 20, Material.DIAMOND, "Underline", "§n")
        addColorOption(inventory, 21, Material.EMERALD, "Strikethrough", "§m")
        addColorOption(inventory, 22, Material.REDSTONE, "Obfuscated", "§k")
        addColorOption(inventory, 23, Material.QUARTZ, "Reset", "§r")

        // Cancel button
        val cancelButton = ItemStack(Material.BARRIER)
        val cancelMeta = cancelButton.itemMeta
        if (cancelMeta != null) {
            cancelMeta.setDisplayName("${ChatColor.RED}Cancel")
            cancelButton.itemMeta = cancelMeta
        }
        inventory.setItem(26, cancelButton)

        player.openInventory(inventory)
    }

    private fun addColorOption(inventory: Inventory, slot: Int, material: Material, name: String, colorCode: String) {
        val item = ItemStack(material)
        val meta = item.itemMeta

        if (meta != null) {
            meta.setDisplayName("${colorCode}$name")

            val lore = ArrayList<String>()
            lore.add("${ChatColor.GRAY}Color code: ${colorCode.replace('§', '&')}")
            lore.add("${ChatColor.YELLOW}Click to select")

            meta.lore = lore
            item.itemMeta = meta
        }

        inventory.setItem(slot, item)
    }

    @EventHandler
    fun onInventoryClick(event: InventoryClickEvent) {
        val player = event.whoClicked as? Player ?: return
        val title = event.view.title

        // Prevent moving items
        if (title == "MOTD Quotes Manager" || title == "Select Quote Color") {
            event.isCancelled = true

            // Check if clicked in the player inventory area
            if (event.clickedInventory == player.inventory) {
                return
            }
        } else {
            return
        }

        val item = event.currentItem ?: return

        when (title) {
            "MOTD Quotes Manager" -> {
                handleMainGuiClick(event, player)
            }
            "Select Quote Color" -> {
                handleColorSelectorClick(event, player)
            }
        }
    }

    private fun handleMainGuiClick(event: InventoryClickEvent, player: Player) {
        val item = event.currentItem ?: return

        when (item.type) {
            Material.PAPER -> {
                // Clicked on a quote
                val slotIndex = event.slot

                if (event.isShiftClick) {
                    // Delete the quote
                    if (plugin.removeQuote(slotIndex)) {
                        player.sendMessage("${ChatColor.GREEN}Quote #${slotIndex + 1} has been deleted.")
                        openQuotesGui(player) // Refresh the GUI
                    } else {
                        player.sendMessage("${ChatColor.RED}Failed to delete quote.")
                    }
                } else {
                    // Edit the quote
                    openColorSelectorGui(player, slotIndex, "edit")
                }
            }
            Material.EMERALD_BLOCK -> {
                // Add new quote
                openColorSelectorGui(player, -1, "add")
            }
            Material.GOLD_BLOCK -> {
                // Refresh MOTD
                plugin.updateServerMOTD()
                player.sendMessage("${ChatColor.GREEN}MOTD has been refreshed!")
            }
            Material.DIAMOND_BLOCK -> {
                // Save quotes to config
                plugin.saveQuotes()
                player.sendMessage("${ChatColor.GREEN}Quotes have been saved to config!")
            }
            Material.REDSTONE_BLOCK -> {
                // Close GUI
                player.closeInventory()
            }
            else -> return
        }
    }

    private fun handleColorSelectorClick(event: InventoryClickEvent, player: Player) {
        val item = event.currentItem ?: return

        if (item.type == Material.BARRIER) {
            // Cancel and go back
            openQuotesGui(player)
            editingSessions.remove(player.uniqueId)
            return
        }

        // Get the color code from the clicked item
        val meta = item.itemMeta ?: return
        val displayName = meta.displayName

        if (displayName.isNotEmpty()) {
            val colorCode = if (displayName.startsWith("§")) {
                "§" + displayName[1].toString()
            } else {
                "§f" // Default to white if something goes wrong
            }

            val session = editingSessions[player.uniqueId] ?: return

            player.closeInventory()

            // Start conversation for text input
            startTextInputConversation(player, session.index, session.action, colorCode)
        }
    }

    private fun startTextInputConversation(player: Player, index: Int, action: String, colorCode: String) {
        val factory = ConversationFactory(plugin)
            .withModality(true)
            .withPrefix { "${ChatColor.GOLD}[MOTD] ${ChatColor.RESET}" }
            .withFirstPrompt(object : StringPrompt() {
                override fun getPromptText(context: ConversationContext): String {
                    return if (action == "add") {
                        "${ChatColor.YELLOW}Enter the text for your new quote:"
                    } else {
                        "${ChatColor.YELLOW}Enter the new text for quote #${index + 1}:"
                    }
                }

                override fun acceptInput(context: ConversationContext, input: String?): Prompt? {
                    if (input == null || input.isBlank()) {
                        player.sendMessage("${ChatColor.RED}Quote text cannot be empty. Operation cancelled.")
                        return Prompt.END_OF_CONVERSATION
                    }

                    if (action == "add") {
                        if (plugin.addQuote(input, colorCode)) {
                            player.sendMessage("${ChatColor.GREEN}New quote added: ${colorCode}$input")
                        } else {
                            player.sendMessage("${ChatColor.RED}Failed to add quote.")
                        }
                    } else {
                        if (plugin.editQuote(index, input, colorCode)) {
                            player.sendMessage("${ChatColor.GREEN}Quote #${index + 1} has been updated: ${colorCode}$input")
                        } else {
                            player.sendMessage("${ChatColor.RED}Failed to update quote.")
                        }
                    }

                    // Schedule opening the GUI on the next tick
                    Bukkit.getScheduler().runTask(plugin, Runnable {
                        openQuotesGui(player)
                    })

                    return Prompt.END_OF_CONVERSATION
                }
            })
            .withEscapeSequence("cancel")
            .withLocalEcho(false)
            .thatExcludesNonPlayersWithMessage("This command can only be run by a player")

        val conversation = factory.buildConversation(player)
        conversation.begin()
    }

    @EventHandler
    fun onInventoryClose(event: InventoryCloseEvent) {
        val player = event.player as? Player ?: return

        // If the inventory being closed is the color selector and not caused by clicking a color option
        if (event.view.title == "Select Quote Color") {
            // Clean up the session if not transitioning to another GUI
            Bukkit.getScheduler().runTaskLater(plugin, Runnable {
                if (player.openInventory.title != "MOTD Quotes Manager") {
                    editingSessions.remove(player.uniqueId)
                }
            }, 1)
        }
    }
}