-- Patched KeyringFix.lua
-- Safest approach: prevent double execution by blocking transfers
-- when the item is already inside the destination container.

local KeyringFix = {}
local Logger = require("Utils/Logger")

local lastLoggedTransfer = {
    itemID = nil,
    destType = nil,
    callCount = 0
}

local function getContainerInfo(container, character)
    if not container then
        return "NULL", "null"
    end

    local containerType = container:getType() or "Unknown"
    local containerName = "Unknown"
    local containerItem = container:getContainingItem()

    if character and container == character:getInventory() then
        containerName = "Player Inventory (" .. character:getUsername() .. ")"
    elseif character then
        if container == character:getInventory() and character:getPrimaryHandItem() then
            containerName = "Primary Hand (Equipped)"
        elseif container == character:getInventory() and character:getSecondaryHandItem() then
            containerName = "Secondary Hand (Equipped)"
        end
    end

    if containerItem then
        containerName = containerItem:getDisplayName() or containerItem:getName() or "Container"
    end

    if containerName == "Unknown" and containerType == "floor" then
        containerName = "Floor/World"
    end

    return containerName, containerType
end

function KeyringFix.apply()
    Logger.debug("Starting KeyringFix application...")

    local ok, TetrisContainerData = pcall(require, "InventoryTetris/Data/TetrisContainerData")
    if not ok or not TetrisContainerData then
        Logger.error("Failed to load TetrisContainerData module: " .. tostring(TetrisContainerData))
        return false
    end
    Logger.debug("TetrisContainerData loaded successfully")

    if not ISInventoryTransferAction then
        Logger.error("ISInventoryTransferAction class not found")
        return false
    end
    Logger.debug("ISInventoryTransferAction class found")

    local og_isValid = ISInventoryTransferAction.isValid
    if not og_isValid then
        Logger.error("Original isValid function not found")
        return false
    end
    Logger.debug("Original isValid function captured")

    function ISInventoryTransferAction:isValid()
        if not self or not self.destContainer or not self.item or not self.character then
            Logger.debug("isValid: Missing required fields")
            return false
        end

        local itemID = self.item:getID() or 0
        local destType = self.destContainer:getType() or "unknown"
        local isSameTransfer = (lastLoggedTransfer.itemID == itemID and 
                                lastLoggedTransfer.destType == destType)

        local shouldLog = false
        if isSameTransfer then
            lastLoggedTransfer.callCount = lastLoggedTransfer.callCount + 1
        else
            lastLoggedTransfer.itemID = itemID
            lastLoggedTransfer.destType = destType
            lastLoggedTransfer.callCount = 1
            shouldLog = true
        end

        if shouldLog then
            local itemName = self.item:getDisplayName() or self.item:getName() or "Unknown Item"
            local itemType = self.item:getFullType() or self.item:getType() or "Unknown Type"
            local itemCategory = self.item:getCategory() or "No Category"
            Logger.debug("========== TRANSFER VALIDATION ==========")
            Logger.debug("Item: " .. itemName)
            Logger.debug("  Type: " .. itemType)
            Logger.debug("  Category: " .. itemCategory)
            Logger.debug("  ID: " .. tostring(itemID))
            local charName = self.character:getUsername() or "Unknown Player"
            Logger.debug("Character: " .. charName)
            local srcName, srcType = getContainerInfo(self.srcContainer, self.character)
            Logger.debug("Source: " .. srcName .. " (" .. srcType .. ")")
            local destName, destType = getContainerInfo(self.destContainer, self.character)
            Logger.debug("Destination: " .. destName .. " (" .. destType .. ")")
            local destDef = TetrisContainerData.getContainerDefinition(self.destContainer)
            local destTetrisType = destDef and destDef.trueType or "none"
            Logger.debug("Tetris Type: " .. tostring(destTetrisType))
        end

        -- SAFETY PATCH: Prevent duplicate transfer execution
        -- If the item is *already inside* the destination container,
        -- the action must not run again.
        if self.item:getContainer() == self.destContainer then
            if shouldLog then
                Logger.debug("Duplicate transfer prevented: Item already in destination container")
                Logger.debug("FINAL RESULT: INVALID (duplicate block)")
            end
            return false
        end

        local destContainerItem = self.destContainer:getContainingItem()
        local isKeyRing = destContainerItem and 
                         type(destContainerItem.hasTag) == "function" and 
                         destContainerItem:hasTag(ItemTag.KEY_RING)

        if isKeyRing and shouldLog then
            Logger.debug("** KEYRING DETECTED ** - Safe-transfer path active")
        end

        if isKeyRing then
            if shouldLog then
                Logger.debug("Validation Path: KEYRING (safe bypass)")
                Logger.debug("FINAL RESULT: VALID")
                Logger.debug("==========================================")
            end
            return true
        end

        local isMoveable = instanceof(self.item, "Moveable")
        local destDef = TetrisContainerData.getContainerDefinition(self.destContainer)

        local valid
        if destDef and destDef.trueType ~= "floor" and isMoveable then
            if shouldLog then
                Logger.debug("Validation Path: MOVEABLE to NON-FLOOR")
            end
            _G.ModScope.withInstanceofExclusion(function()
                valid = og_isValid(self)
            end, "Moveable")
        else
            if shouldLog then
                Logger.debug("Validation Path: STANDARD")
            end
            valid = og_isValid(self)
        end

        if not valid then
            if shouldLog then
                Logger.debug("FINAL RESULT: INVALID (basic validation failed)")
                Logger.debug("==========================================")
            end
            return false
        end

        if not self.enforceTetrisRules then
            if shouldLog then
                Logger.debug("Tetris rules not enforced - skipping validation")
                Logger.debug("FINAL RESULT: VALID")
                Logger.debug("==========================================")
            end
            return true
        end

        if shouldLog then
            Logger.debug("Checking Tetris placement rules...")
        end
        local tetrisValid = self:validateTetrisRules()

        if shouldLog then
            Logger.debug("  Tetris Result: " .. tostring(tetrisValid))
            Logger.debug("FINAL RESULT: " .. (tetrisValid and "VALID" or "INVALID"))
            Logger.debug("==========================================")
        end

        return tetrisValid
    end

    Logger.success("Keyring fix applied successfully (duplicate-safe)")
    return true
end

return KeyringFix