----------------------------------------------------------
-- Category_Clothing.lua
-- Token-based rules (v3.8)
----------------------------------------------------------

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

-- token tables
local TOKENS = {
    Headwear = { "hat", "cap", "helmet", "beanie", "beret", "hood"},
    Facewear = { "mask", "gas mask", "respirator", "balaclava"},
    Gloves = {  "glove", "mittens", "gauntlet"  },
    Footwear = { "shoes", "boots", "sneakers", "sandals", "sock", "socks", "stocking", "stockings", "calcetin", "calcetines", "bota", "botas", "zapato", "zapatos", "zapatilla", "zapatillas" },
    Bottoms = { "pants", "jeans", "slacks", "shorts", "skirt", "pantalon", "pantalones", "falda", "bermuda" },
    Tops = { "shirt", "tshirt", "t-shirt", "sweater", "hoodie", "coat", "jacket", "blouse", "tanktop", "camisa", "camiseta", "chaqueta", "abrigo", "sudadera" },
    FullBody = { "fullsuit", "boilersuit", "jumpsuit", "onesie", "dress", "robe" },
    Eyewear   = { "glasses", "goggles", "sunglasses" },
    Neck      = { "scarf", "necklace", "choker" },
    Arms      = { "armguard", "sleeves" },
    UnderwearTop    = { "bra", "undershirt", "bralette", "sports bra", "sportsbra", "sujetador", "brassiere", "top deportivo" },
    UnderwearBottom = { "underpants", "boxers", "boxer", "panties", "briefs", "thong", "calzon", "calzones", "calzoncillo", "calzoncillos", "ropa interior", "slip" },
    Accessory = { "belt", "tail", "wristband", "bracelet", "ring", "earring" },
}

-- Universal token matcher for all categories
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 isClothing(item)
    return instanceof and instanceof(item, "Clothing")
end

local function getLocation(item)
    local loc = item.getBodyLocation and item:getBodyLocation()
    return loc and string.lower(tostring(loc)) or ""
end

C.rules = {
    {
        id = "Clothing.BaseCheck",
        priority = 10,
        match = function(item, statMap)
            return isClothing(item)
        end,
        category = "Clothing",
    },

    {
        id = "Clothing.Headwear",
        priority = 100,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.Headwear)
        end,
        category = "Clothing/Headwear",
    },

    {
        id = "Clothing.Facewear",
        priority = 75,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.Facewear)
        end,
        category = "Clothing/Facewear",
    },

    {
        id = "Clothing.Gloves",
        priority = 85,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.Gloves)
        end,
        category = "Clothing/Gloves",
    },

    {
        id = "Clothing.Footwear",
        priority = 90,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.Footwear)
        end,
        category = "Clothing/Footwear",
    },

    {
        id = "Clothing.Bottoms",
        priority = 85,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.Bottoms)
        end,
        category = "Clothing/Bottoms",
    },

    {
        id = "Clothing.Tops",
        priority = 90,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.Tops)
        end,
        category = "Clothing/Tops",
    },

    {
        id = "Clothing.FullBody",
        priority = 100,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            return matchTokens(getLocation(item), TOKENS.FullBody)
        end,
        category = "Clothing/FullBody",
    },

    {
        id = "Clothing.Eyewear",
        priority = 80,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local text = getLocation(item) .. " " .. (item.getDisplayName and string.lower(tostring(item:getDisplayName())) or "")
            return matchTokens(text, TOKENS.Eyewear)
        end,
        category = "Clothing/Eyewear",
    },

    {
        id = "Clothing.Neck",
        priority = 60,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local text = getLocation(item) .. " " .. (item.getDisplayName and string.lower(tostring(item:getDisplayName())) or "")
            return matchTokens(text, TOKENS.Neck)
        end,
        category = "Clothing/Neck",
    },

    {
        id = "Clothing.Arms",
        priority = 60,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local text = getLocation(item) .. " " .. (item.getDisplayName and string.lower(tostring(item:getDisplayName())) or "")
            return matchTokens(text, TOKENS.Arms)
        end,
        category = "Clothing/Arms",
    },

    {
        id = "Clothing.UnderwearTop",
        priority = 70,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local text = getLocation(item) .. " " .. (item.getDisplayName and string.lower(tostring(item:getDisplayName())) or "")
            return matchTokens(text, TOKENS.UnderwearTop)
        end,
        category = "Clothing/UnderwearTop",
    },

    {
        id = "Clothing.UnderwearBottom",
        priority = 70,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local text = getLocation(item) .. " " .. (item.getDisplayName and string.lower(tostring(item:getDisplayName())) or "")
            return matchTokens(text, TOKENS.UnderwearBottom)
        end,
        category = "Clothing/UnderwearBottom",
    },

    {
        id = "Clothing.Accessory",
        priority = 50,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local text = getLocation(item) .. " "
                .. (item.getDisplayName and string.lower(tostring(item:getDisplayName())) or "")
                .. " " .. (item.getDisplayCategory and string.lower(tostring(item:getDisplayCategory())) or "")
            return matchTokens(text, TOKENS.Accessory)
        end,
        category = "Clothing/Accessory",
    },

    {
        id = "Clothing.Armor",
        priority = 110,
        match = function(item, statMap)
            if not isClothing(item) then return false end
            local bite = statMap and statMap["bite"] and tonumber(statMap["bite"].value) or 0
            return bite >= 15
        end,
        category = "Clothing/Armor",
    },

    {
        id = "Clothing.Base",
        priority = 50,
        match = function(item, statMap)
            local dc = item.getDisplayCategory and item:getDisplayCategory() or ""
            dc = string.lower(dc)
            return dc:find("clothing", 1, true) ~= nil
        end,
        category = "Clothing",
    },
}

return C
