local M = {}

local function getFluidTotalUses(item)
    if not item then return nil end

    local total

    -- 1) Intentar DrainableUsesInt
    if item.getDrainableUsesInt then
        total = item:getDrainableUsesInt()
    end

    -- 2) Fallback desde UseDelta
    if (not total or total <= 0) and item.getUseDelta then
        local useDelta = item:getUseDelta()
        if useDelta and useDelta > 0 and useDelta < 1 then
            total = math.floor(1 / useDelta + 0.5)
        end
    end

    if not total or total <= 0 then return nil end
    if total > 1000 then return nil end -- evitar valores absurdos

    return total
end

local function getFluidContainerInfo(item)
    if not item or not InspectUI_isFluidContainer(item) then
        return nil, nil
    end

    -- Prioridad: API de FluidContainer (litros)
    local fc = item.getFluidContainer and item:getFluidContainer()
    if fc then
        local okCap, cap = pcall(function() return fc.getCapacity and fc:getCapacity() end)
        local okAmt, amt = pcall(function() return fc.getAmount and fc:getAmount() end)
        if okCap and cap and cap > 0 then
            local amount = (okAmt and amt) or 0
            return amount, cap
        end
    end

    -- Fallback: drainable uses
    local totalUses = getFluidTotalUses(item)
    if not totalUses then return nil, nil end

    local usedDelta = item.getUsedDelta and item:getUsedDelta() or 0
    if usedDelta < 0 then usedDelta = 0 end
    if usedDelta > 1 then usedDelta = 1 end

    local remaining = math.floor(totalUses * (1 - usedDelta) + 0.001)
    if remaining < 0 then remaining = 0 end
    if remaining > totalUses then remaining = totalUses end

    return remaining, totalUses
end

local function getPoisonPower(item)
    if not item then return nil end
    local v
    if item.getPoisonPower then
        v = item:getPoisonPower()
    end
    if (not v or v == 0) and item.getScriptItem then
        local script = item:getScriptItem()
        if script and script.getPoisonPower then
            v = script:getPoisonPower()
        end
    end
    if not v or v == 0 then return nil end
    return InspectUI_fmtNumber(v, 2)
end

local function isFuelLike(item)
    if not item then return false end
    local function lower(val)
        if not val then return "" end
        return string.lower(tostring(val))
    end
    local dc = item.getDisplayCategory and lower(item:getDisplayCategory()) or ""
    local cat = item.getCategory and lower(item:getCategory()) or ""
    local name = item.getDisplayName and lower(item:getDisplayName()) or ""

    local tokens = { "fuel", "gas", "petrol", "diesel", "propane", "gasoline" }
    for _, t in ipairs(tokens) do
        if dc:find(t, 1, true) or cat:find(t, 1, true) or name:find(t, 1, true) then
            return true
        end
    end
    return false
end

local function getTainted(item)
    if not item then return nil end
    if item.isTaintedWater then
        local ok, res = pcall(function() return item:isTaintedWater() end)
        if ok then return res end
    end
    if item.getTainted then
        local ok, res = pcall(function() return item:getTainted() end)
        if ok then return res end
    end
    -- Revisar el FluidContainer interno, si existe
    if item.getFluidContainer then
        local fc = item:getFluidContainer()
        if fc then
            if fc.isTainted then
                local ok, res = pcall(function() return fc:isTainted() end)
                if ok then return res end
            end
            if fc.getTainted then
                local ok, res = pcall(function() return fc:getTainted() end)
                if ok then return res end
            end
        end
    end
    if item.getScriptItem then
        local script = item:getScriptItem()
        if script and script.isTaintedWater then
            local ok, res = pcall(function() return script:isTaintedWater() end)
            if ok then return res end
        end
        if script and script.getTainted then
            local ok, res = pcall(function() return script:getTainted() end)
            if ok then return res end
        end
    end
    return nil
end

M.defs = {
    --------------------------------------------------
    -- FLUID CONTAINERS
    --------------------------------------------------
    {
        id       = "fluidAmount",
        labelKey = "IGUI_Inspect_Stat_FluidAmount",
        fallback = "Amount",
        getter   = function(item)
            if not item then return end
            if not InspectUI_isFluidContainer(item) then return end

            local amount, capacity = getFluidContainerInfo(item)
            if not amount or not capacity then return end

            -- Mostrar litros con dos decimales si vienen de FluidContainer
            if capacity <= 20 then
                return string.format("%.2f / %.2f L", amount, capacity)
            end

            -- Usos (enteros) para drainables comunes
            return string.format("%d / %d", math.floor(amount + 0.5), math.floor(capacity + 0.5))
        end,
    },
    {
        id       = "fluidCapacity",
        labelKey = "IGUI_Inspect_Stat_FluidCapacity",
        fallback = "Fluid capacity",
        getter   = function(item)
            if not item then return end

            if not InspectUI_isFluidContainer(item) then
                return
            end

            local _, cap = getFluidContainerInfo(item)
            if not cap then return end

            -- Capacidad total en "unidades / litros"
            if cap <= 20 then
                return InspectUI_fmtNumber(cap, 2)
            end
            return tostring(math.floor(cap + 0.5))
        end,
    },
    {
        id       = "taintedWater",
        labelKey = "IGUI_Inspect_Stat_Tainted",
        fallback = "Tainted",
        getter   = function(item)
            if not InspectUI_isFluidContainer(item) then return end
            local v = getTainted(item)
            if v == nil then return end
            return v and InspectUI_tr("IGUI_Inspect_Yes", "Yes") or InspectUI_tr("IGUI_Inspect_No", "No")
        end,
    },
    {
        id       = "fluidPoison",
        labelKey = "IGUI_Inspect_Stat_Poison",
        fallback = "Poison",
        getter   = function(item)
            if not InspectUI_isFluidContainer(item) then return end
            local v = getPoisonPower(item)
            -- Mostrar como booleano (Sí/No)
            if v and tonumber(v) and tonumber(v) > 0 then
                return InspectUI_tr("IGUI_Inspect_Yes", "Yes")
            end
            -- Gasolina/combustibles se tratan como venenosos
            if isFuelLike(item) then
                return InspectUI_tr("IGUI_Inspect_Yes", "Yes")
            end
            return InspectUI_tr("IGUI_Inspect_No", "No")
        end,
    },
    {
        id       = "rainFactor",
        labelKey = "IGUI_Inspect_Stat_RainFactor",
        fallback = "Rain factor",
        getter   = function(item)
            if not item then return end
            if not item.getScriptItem then return end

            local script = item:getScriptItem()
            if not script or not script.getRainFactor then
                return
            end

            local v = script:getRainFactor()
            if not v or v == 0 then
                return
            end

            -- Valor tal cual (normalmente 0-1 o parecido)
            return InspectUI_fmtNumber(v, 2)
        end,
    },
}

M.order = {
    "fluidAmount",
    "fluidCapacity",
    "taintedWater",
    "fluidPoison",
    "rainFactor",
}

return M
