-- laundering/sh_api.lua
-- Initialise le namespace Laundering des deux côtés.
-- Expose Laundering.Compute() : fonction pure utilisable côté serveur ET potentiellement
-- côté client pour les estimations d'affichage (pas d'effets de bord).
-- Les tables internes (_transactions, _cooldowns, _npcs) sont serveur uniquement.

Laundering = Laundering or {}

-- Tables internes serveur (déclarées ici pour que le namespace existe proprement)
if SERVER then
    -- [steamID64] = CurTime() de fin de cooldown
    Laundering._cooldowns     = Laundering._cooldowns     or {}
    -- [steamID64] = { amount, methodId, startedAt, endsAt, requiresProximity, maxDistance, onComplete, onCancel }
    Laundering._transactions  = Laundering._transactions  or {}
    -- [entity] = true  (toutes les entités laundering_npc spawnable via SpawnNPC)
    Laundering._npcs          = Laundering._npcs          or {}
end

-- ============================================================================
-- Laundering.Compute — fonction pure
-- Calcule le montant propre obtenu pour un montant sale donné.
-- Retourne : cleanAmount (int), isPartial (bool), tier (table|nil)
-- ============================================================================

function Laundering.Compute(amount, tiersOverride)
    amount = math.floor(tonumber(amount) or 0)
    if amount <= 0 then return 0, false, nil end

    local tiers = tiersOverride or Laundering.Config.Tiers
    local tier
    for _, t in ipairs(tiers) do
        if amount >= t.min and amount <= t.max then
            tier = t
            break
        end
    end
    if not tier then return 0, false, nil end

    local r = math.random()  -- [0, 1[
    local rate, isPartial
    if r < tier.partialChance then
        -- Résultat dégradé : taux uniforme dans [partialMin, partialMax]
        rate      = tier.partialMin + math.random() * (tier.partialMax - tier.partialMin)
        isPartial = true
    else
        rate      = tier.baseRate
        isPartial = false
    end

    return math.floor(amount * rate), isPartial, tier
end

-- ============================================================================
-- Laundering.GetTierForAmount — helper partagé (UI)
-- Retourne le tier applicable à un montant donné, ou nil.
-- ============================================================================

function Laundering.GetTierForAmount(amount, tiersOverride)
    amount = math.floor(tonumber(amount) or 0)
    if amount <= 0 then return nil end

    local tiers = tiersOverride or Laundering.Config.Tiers
    for _, t in ipairs(tiers) do
        if amount >= t.min and amount <= t.max then
            return t
        end
    end
    return nil
end
