-- sh_config.lua — Config shared (chargé serveur ET client via sh_sdf_system_init.lua)
-- Modifie ce fichier pour régler durées, XP, loot, models, skill-check, immersion, etc.

SDFSystem = SDFSystem or {}

SDFSystem.Config = {
    -- ─── Commandes d'ouverture du menu admin ─────────────────────────────────
    ConCommand  = "sdf_menu",  -- concommand console
    ChatCommand = "!sdf",      -- commande chat

    -- ─── Durées (secondes) ───────────────────────────────────────────────────
    SearchDuration    = 10,    -- durée d'une fouille (s)
    CooldownDuration  = 300,   -- cooldown par poubelle après fouille (5 min)
    MaxSearchDistance = 100,   -- distance max joueur<->entité avant annulation

    -- ─── Gain XP (appel DBALevel.AddXP) ─────────────────────────────────────
    XP = {
        Min = 5,
        Max = 25,
    },

    -- ─── Whitelist des models de poubelles ───────────────────────────────────
    -- L'index 1-based sert à l'encodage réseau (net.WriteUInt).
    Models = {
        -- ── Modèles custom (pipeline Meshy → models/dba) ─────────────────────
        "models/dba/trash_bags_pile.mdl",   -- tas de sacs poubelle
        "models/dba/dumpster.mdl",          -- benne à ordures
        "models/dba/street_bin.mdl",        -- corbeille de rue grillagée
        "models/dba/junk_heap.mdl",         -- tas de déchets divers
        "models/dba/wheelie_bin.mdl",       -- poubelle plastique à roulettes
        -- ── Modèles HL2/CS:S d'origine ───────────────────────────────────────
        "models/highrise/trash_can_03.mdl",
        "models/highrise/trashcanashtray_01.mdl",
        "models/props_interiors/trashcan01.mdl",
        "models/props_interiors/trashcankitchen01.mdl",
        "models/props_junk/trashbin01a.mdl",
        "models/props_junk/trashcluster01a.mdl",
        "models/props/cs_office/trash_can.mdl",
        "models/props_trainstation/trashcan_indoor001a.mdl",
    },

    -- ─── Distance de spawn des lots entity ───────────────────────────────────
    EntitySpawnDistance = 60,

    -- ─── 3D2D render ─────────────────────────────────────────────────────────
    DrawDistance = 400,  -- distance max d'affichage du 3D2D

    -- =========================================================================
    -- A. Argent à distribution pondérée
    -- =========================================================================
    -- Formule : amount = floor( min + (max - min) * (rand() ^ bias) )
    --   bias = 1.0  → distribution uniforme sur [min, max]
    --   bias > 1.0  → probabilité plus élevée pour les petits montants
    --   bias = 2.0  → probabilité ∝ (1 - t) où t ∈ [0,1]
    -- Les lots type="money" et type="entity"/class="spawned_money" utilisent
    -- MoneyRange par défaut. Chaque lot peut surcharger min/max/bias.
    MoneyRange = {
        min  = 100,
        max  = 500,
        bias = 2.0,   -- >1 = favorise les petits montants
    },

    -- =========================================================================
    -- B. Immersion pendant la fouille
    -- =========================================================================
    Immersion = {
        -- Ancien geste GMod (peu visible selon le modèle) : désactivé car remplacé
        -- par ArmAnim (manipulation d'os, voir plus bas). Mets un ACT_GMOD_GESTURE_*
        -- ici si tu veux le réactiver en plus.
        GestureAct        = nil,
        GestureInterval   = 1.2,

        -- Accroupissement pendant la fouille. Désactivé : on préfère rester DEBOUT
        -- avec le buste penché en avant (LeanForward ci-dessous), plus naturel pour
        -- fouiller. Repasse à true si tu veux l'accroupissement à la place.
        CrouchWhileSearching = false,

        -- Effet caméra première personne (léger balancement de tête "fouille").
        FirstPersonEffect    = true,
        FirstPersonBobAmp    = 0.8,   -- amplitude verticale (units)
        FirstPersonPitch     = 5,     -- inclinaison du regard vers le bas (degrés)

        -- Posture de fouille (manipulation d'os ValveBiped) : buste penché +
        -- bras tendus vers l'avant qui farfouillent. Visible sur tous les modèles
        -- au squelette HL2 standard. Tous les angles sont en degrés.
        ArmAnim     = true,
        ArmSpeed    = 8,    -- vitesse du mouvement de fouille
        LeanForward = 22,   -- inclinaison du buste vers l'avant (réparti sur la colonne)
        ArmForward  = 50,   -- à quel point les bras pointent vers l'avant
        ArmSpread   = 18,   -- écartement des bras (évite qu'ils se croisent) — monte pour plus écarté
        ArmDig      = 22,   -- amplitude des allers-retours AVANT/ARRIÈRE (mouvement principal de fouille)
        ArmUpDown   = 5,    -- léger bob vertical (secondaire, garde faible)
        ArmRotate   = 6,    -- légère rotation du poignet (garde faible pour éviter l'effet "tourne")

        -- Son de fouille en boucle sur l'entité (son HL2 natif, zéro asset custom).
        SearchSound       = "physics/cardboard/cardboard_box_strain2.wav",
        SearchSoundVolume = 0.8,
        SearchSoundPitch  = 100,

        -- Particules côté client (mouches / poussière au-dessus de la poubelle).
        -- Mettre à false pour désactiver.
        ParticlesEnabled  = true,
        ParticleColor     = Color(60, 50, 40, 180),   -- brun foncé semi-transparent
        ParticleCount     = 5,       -- sprites simultanés
        ParticleRadius    = 18,      -- rayon de l'orbite (units)
        ParticleSpeed     = 0.8,     -- vitesse angulaire (tours/s)
        ParticleZOffset   = 52,      -- hauteur au-dessus du bas de l'entité (units)
        ParticleSize      = 4,       -- taille du sprite (units, rendu 3D2D)
    },

    -- =========================================================================
    -- D. Scaling par niveau légal (DBALevel)
    -- =========================================================================
    LevelScaling = {
        -- Facteur d'élargissement de la fourchette haute de l'argent par niveau.
        -- effMax = baseMax * (1 + lvl * MoneyLevelFactor)
        -- effMin = baseMin * (1 + lvl * MoneyLevelMinFactor)
        MoneyLevelFactor    = 0.02,   -- +2% du max par niveau
        MoneyLevelMinFactor = 0.005,  -- +0.5% du min par niveau

        -- Niveau au-delà duquel le bonus de rareté ne grandit plus : empêche le
        -- légendaire de devenir fréquent à très haut niveau.
        MaxBonusLevel = 50,

        -- Bonus de poids de rareté par niveau légal (TRÈS doux, ajouté sur baseWeight).
        -- On garde "commun" à 0 et les hauts tiers faibles pour que le légendaire
        -- reste rare même à haut niveau. Mets tout à 0 pour ignorer le niveau.
        RarityBonusPerLevel = {
            commun     = 0,
            rare       = 0.2,
            epique     = 0.05,
            legendaire = 0.01,
        },
    },

    -- =========================================================================
    -- E. Système de rareté (4 tiers)
    -- =========================================================================
    -- baseWeight : poids de base pour le tirage de tier.
    -- notifyType : type DBALib.UI.Notify ("info"|"success"|"warning"|"danger")
    -- sound      : clé DBALib.Sound (ou "" pour aucun son)
    -- colorFn    : fonction () → Color — lazy car DBALib peut ne pas être chargé.
    -- ⚠ RARETÉ : la probabilité d'un tier = son baseWeight / somme des baseWeight
    --   (+ petit bonus de niveau, voir D). Pour rendre le LÉGENDAIRE plus rare,
    --   baisse son baseWeight (1 = très rare) ou monte celui de "commun".
    --   Défauts : commun≈79%, rare≈16%, épique≈4%, légendaire≈0.7%.
    Rarities = {
        {
            id         = "commun",
            label      = "Commun",
            baseWeight = 120,
            notifyType = "info",
            sound      = "ui_notify",
            -- couleur = text.secondary (gris pâle)
            colorFn    = function()
                if DBALib and DBALib.Theme then
                    return DBALib.Theme.palette.text.secondary
                end
                return Color(106, 117, 133)
            end,
        },
        {
            id         = "rare",
            label      = "Rare",
            baseWeight = 25,
            notifyType = "info",
            -- ↑ baisse ce nombre pour rendre "rare" plus rare
            sound      = "ui_notify",
            -- couleur = semantic.info (bleu)
            colorFn    = function()
                if DBALib and DBALib.Theme then
                    return DBALib.Theme.palette.semantic.info
                end
                return Color(56, 139, 253)
            end,
        },
        {
            id         = "epique",
            label      = "Epique",
            baseWeight = 6,
            notifyType = "warning",
            sound      = "ui_levelup",
            -- couleur = violet custom (DBALib.Theme n'a pas de violet)
            colorFn    = function()
                return Color(168, 85, 247)
            end,
        },
        {
            id         = "legendaire",
            label      = "Légendaire",
            baseWeight = 1,   -- TRÈS rare (~0.7%). Mets 0.5 pour encore plus rare, 0 pour le désactiver.
            notifyType = "success",
            sound      = "ui_levelup",
            -- couleur = gold.base
            colorFn    = function()
                if DBALib and DBALib.Theme then
                    return DBALib.Theme.palette.gold.base
                end
                return Color(212, 175, 55)
            end,
        },
    },

    -- =========================================================================
    -- F. Jackpot (déclenché sur rareté "legendaire")
    -- =========================================================================
    Jackpot = {
        Enabled  = true,
        Sound    = "items/suitchargeok1.wav",  -- son HL2 natif
        Duration = 2.5,   -- durée de l'overlay écran (s)
    },

    -- =========================================================================
    -- G. Risque / récompense (issue tirée AVANT le loot)
    -- =========================================================================
    -- À chaque fouille réussie, une issue est tirée au sort.
    -- Le cooldown s'applique dans tous les cas.
    Outcomes = {
        -- Poids relatifs (probabilité = weight / total)
        Weights = {
            success    = 65,
            nothing    = 20,
            rat        = 10,
            contraband = 5,
        },

        -- Dégâts de la morsure (type="rat")
        RatDamage = 15,
        RatSound  = "npc/zombie/claw_strike1.wav",  -- son HL2 natif

        -- XP pour chaque issue (légal sauf contraband = illégal)
        XpSuccess    = { Min = 5, Max = 25 },  -- XP légal (base, avant bonus hits)
        XpNothing    = 2,                       -- XP légal fixe (effort quand même)
        XpRat        = 0,                       -- XP légal (0 = punition)
        XpContraband = 30,                      -- XP ILLÉGAL fixe

        -- Argent bonus en cas de contrebande (en plus de l'XP illégal)
        ContrabandMoney = { Min = 50, Max = 200 },
    },

    -- =========================================================================
    -- H. Loot par modèle
    -- =========================================================================
    -- Chaque entrée de lot porte :
    --   type    : "money" | "weapon" | "entity"
    --   weight  : poids au sein du tier
    --   rarity  : "commun" | "rare" | "epique" | "legendaire"
    --   (+ champs spécifiques au type : min/max ou class)
    --
    -- Pour ajouter une table par modèle :
    --   SDFSystem.Config.LootByModel["models/your/model.mdl"] = { ... lots ... }
    -- Si le modèle n'a pas de table, on utilise "default".
    LootByModel = {
        -- ── Bureau CS:GO (trash_can.mdl) : papiers, petite monnaie ────────────
        ["models/props/cs_office/trash_can.mdl"] = {
            { type = "money",  weight = 40, rarity = "commun",     min = 50,  max = 200  },
            { type = "money",  weight = 20, rarity = "commun",     min = 20,  max = 80   },
            { type = "entity", weight = 20, rarity = "commun",     class = "spawned_money", min = 80, max = 200 },
            { type = "weapon", weight = 10, rarity = "rare",       class = "weapon_pistol" },
            { type = "weapon", weight = 5,  rarity = "epique",     class = "weapon_smg1"   },
            { type = "money",  weight = 3,  rarity = "legendaire", min = 500, max = 1500  },
        },

        -- ── Ferraille rouillée (trashcluster01a.mdl) : débris, armes ─────────
        ["models/props_junk/trashcluster01a.mdl"] = {
            { type = "money",  weight = 30, rarity = "commun",     min = 30,  max = 120  },
            { type = "weapon", weight = 25, rarity = "commun",     class = "weapon_crowbar" },
            { type = "entity", weight = 20, rarity = "commun",     class = "item_box_buckshot" },
            { type = "weapon", weight = 15, rarity = "rare",       class = "weapon_shotgun"    },
            { type = "weapon", weight = 7,  rarity = "epique",     class = "weapon_ar2"        },
            { type = "entity", weight = 2,  rarity = "legendaire", class = "spawned_money", min = 800, max = 2000 },
        },

        -- ── Poubelle cuisine (trashcankitchen01.mdl) : nourriture/argent ─────
        ["models/props_interiors/trashcankitchen01.mdl"] = {
            { type = "money",  weight = 50, rarity = "commun",     min = 60,  max = 250  },
            { type = "money",  weight = 25, rarity = "rare",       min = 200, max = 600  },
            { type = "entity", weight = 15, rarity = "rare",       class = "spawned_money", min = 300, max = 800 },
            { type = "weapon", weight = 7,  rarity = "epique",     class = "weapon_pistol" },
            { type = "money",  weight = 3,  rarity = "legendaire", min = 1000, max = 3000 },
        },

        -- ── Table par défaut (fallback pour tous les autres modèles) ──────────
        default = {
            { type = "money",  weight = 45, rarity = "commun",     min = 50,  max = 400  },
            { type = "weapon", weight = 20, rarity = "commun",     class = "weapon_pistol"  },
            { type = "weapon", weight = 5,  rarity = "commun",     class = "weapon_crowbar" },
            { type = "entity", weight = 15, rarity = "rare",       class = "spawned_money", min = 100, max = 800 },
            { type = "entity", weight = 10, rarity = "rare",       class = "item_box_buckshot" },
            { type = "weapon", weight = 3,  rarity = "epique",     class = "weapon_ar2"        },
            { type = "money",  weight = 2,  rarity = "legendaire", min = 500, max = 2000       },
        },
    },
}

-- ─── Lookup rapide model → index ─────────────────────────────────────────────
SDFSystem.ModelIndex = SDFSystem.ModelIndex or {}
for i, mdl in ipairs(SDFSystem.Config.Models) do
    SDFSystem.ModelIndex[mdl] = i
end

-- ─── Lookup rapide rarity id → table rarity ──────────────────────────────────
SDFSystem.RarityById = SDFSystem.RarityById or {}
for _, r in ipairs(SDFSystem.Config.Rarities) do
    SDFSystem.RarityById[r.id] = r
end

-- ─── Bits réseau ─────────────────────────────────────────────────────────────
-- ceil(log2(8)) = 3 bits pour 8 models ; on garde 4 bits de marge.
SDFSystem.MODEL_INDEX_BITS = 4
-- IDs DB : jusqu'à 65535 entités (16 bits).
SDFSystem.DB_ID_BITS = 16
-- Rareté : 4 tiers → 2 bits suffisent (0-3).
SDFSystem.RARITY_BITS = 2
