----------------------------------------------------------
-- Category_Ammo.lua
-- Ammunition rules (v3.9 modular)
----------------------------------------------------------

local C = {}
C.parent = "Ammunition"

local TOKENS = {
    AmmoCarton = { "carton" },
    AmmoBox    = { "box", "box of", "ammo box", "caja", "caja de" },
}

local function lower(val)
    if not val then return "" end
    return string.lower(tostring(val))
end

local function matchTokens(text, tokens)
    for _, token in ipairs(tokens) do
        if text:find(token, 1, true) then
            return true
        end
    end
    return false
end

local function getDisplayCategory(item)
    return lower(item.getDisplayCategory and item:getDisplayCategory())
end

local function getCategory(item)
    return lower(item.getCategory and item:getCategory())
end

local function getText(item)
    local name = lower(item.getDisplayName and item:getDisplayName())
    local dc   = getDisplayCategory(item)
    local cat  = getCategory(item)
    return (name or "") .. " " .. (dc or "") .. " " .. (cat or "")
end

local function getName(item)
    return lower(item.getDisplayName and item:getDisplayName())
end

local function isAmmo(item, statMap)
    if not item then return false end
    local dc = getDisplayCategory(item)
    local cat = getCategory(item)
    return dc == "ammo" or cat == "ammo" or (statMap and statMap["caliber"] ~= nil)
end

C.rules = {
    -- Ammunition base
    {
        id = "Ammunition.Base",
        priority = 50,
        match = function(item, statMap)
            return isAmmo(item, statMap)
        end,
        category = "Ammunition",
    },

    {
        id = "Ammunition.Carton",
        priority = 92,
        match = function(item, statMap)
            if not isAmmo(item, statMap) then return false end
            return matchTokens(getText(item), TOKENS.AmmoCarton)
        end,
        category = "Ammunition/Carton",
    },

    {
        id = "Ammunition.Magazine",
        priority = 92,
        match = function(item, statMap)
            if not isAmmo(item, statMap) then return false end
            if item.getCurrentAmmoCount then
                local maxAmmo  = item.getMaxAmmo and item:getMaxAmmo() or 0
                local ammoType = item.getAmmoType and item:getAmmoType() or ""
                return maxAmmo > 0 and ammoType ~= "" and item.getCurrentAmmoCount
            end
            return false
        end,
        category = "Ammunition/Magazine",
    },

    {
        id = "Ammunition.AmmoBox",
        priority = 92,
        match = function(item, statMap)
            if not isAmmo(item, statMap) then return false end
            local name = getName(item)
            if matchTokens(name, TOKENS.AmmoBox) then
                return true
            end

            -- Fallback: large stacks are likely boxes (avoid hitting single loose rounds)
            local count = item.getCount and item:getCount() or 0
            return count > 10
        end,
        category = "Ammunition/AmmoBox",
    },

    {
        id = "Ammunition.LooseRound",
        priority = 92,
        match = function(item, statMap)
            if not isAmmo(item, statMap) then return false end
            local name = getName(item)
            if matchTokens(name, TOKENS.AmmoBox) then return false end
            if matchTokens(name, TOKENS.AmmoCarton) then return false end
            return true
        end,
        category = "Ammunition/LooseRound",
    },
}

return C
