// Brass and Sigil -- tier system (foundation)
//
// 13-tier civic ladder per docs/economy-system.md §4a. This file owns:
//   - The TIER_CONFIG table (single source of truth for tier perks)
//   - Helper functions: getTier(player), setTier, getTierConfig
//   - Admin commands: /bns admin set-tier, get-tier
//
// Storage: player.persistentData.bnsTier (int, 1-13). Default 1 (Peasant).
//
// Eventually FTB Ranks will mirror this — when the bnstoolkit mod ships,
// rank promotion will set both the NBT tier here AND the FTB Ranks rank
// (which carries the FTB-Chunks permission nodes for wilderness caps).
// For now this NBT is the authoritative source.
//
// All other economy scripts read tier perks through this module's
// exposed globals.

// ─── The ladder ─────────────────────────────────────────────────────
// Names + costs + perks per tier. Edit here to rebalance.
// Sub-fields:
//   wildernessChunks  — FTB Chunks claim cap (also enforced via FTB Ranks
//                       permission node once configured; this is the
//                       fallback / source-of-truth value)
//   plotSlots         — how many spawn plots the player can own at once
//   dailyBountySlots  — how many bounties they can have active at once
//   shopFeeDiscount   — % discount on the 25% base Bazaar fee (negative %)
//   chatColour        — name colour in chat
//   joinBroadcast     — broadcast level on login
const TIER_CONFIG = Object.freeze([
    null, // tiers are 1-indexed, slot 0 reserved
    { id: 1,  name: 'Peasant',     cost: 0,         wildernessChunks: 9,    plotSlots: 0,  dailyBountySlots: 3,  shopFeeDiscount: 0,    chatColour: 'gray',         joinBroadcast: 'none' },
    { id: 2,  name: 'Farmer',      cost: 200,       wildernessChunks: 18,   plotSlots: 0,  dailyBountySlots: 3,  shopFeeDiscount: 0,    chatColour: 'gray',         joinBroadcast: 'none' },
    { id: 3,  name: 'Citizen',     cost: 750,       wildernessChunks: 35,   plotSlots: 1,  dailyBountySlots: 3,  shopFeeDiscount: 0,    chatColour: 'white',        joinBroadcast: 'none' },
    { id: 4,  name: 'Merchant',    cost: 2500,      wildernessChunks: 60,   plotSlots: 1,  dailyBountySlots: 4,  shopFeeDiscount: -2,   chatColour: 'yellow',       joinBroadcast: 'none' },
    { id: 5,  name: 'Knight',      cost: 6500,      wildernessChunks: 100,  plotSlots: 2,  dailyBountySlots: 4,  shopFeeDiscount: -5,   chatColour: 'green',        joinBroadcast: 'simple' },
    { id: 6,  name: 'Baron',       cost: 15000,     wildernessChunks: 150,  plotSlots: 2,  dailyBountySlots: 5,  shopFeeDiscount: -7,   chatColour: 'aqua',         joinBroadcast: 'simple' },
    { id: 7,  name: 'Viscount',    cost: 35000,     wildernessChunks: 220,  plotSlots: 3,  dailyBountySlots: 5,  shopFeeDiscount: -9,   chatColour: 'blue',         joinBroadcast: 'fancy' },
    { id: 8,  name: 'Earl',        cost: 75000,     wildernessChunks: 300,  plotSlots: 3,  dailyBountySlots: 6,  shopFeeDiscount: -11,  chatColour: 'dark_purple',  joinBroadcast: 'fancy' },
    { id: 9,  name: 'Marquess',    cost: 150000,    wildernessChunks: 400,  plotSlots: 4,  dailyBountySlots: 6,  shopFeeDiscount: -13,  chatColour: 'gold',         joinBroadcast: 'fancy' },
    { id: 10, name: 'Duke',        cost: 300000,    wildernessChunks: 525,  plotSlots: 5,  dailyBountySlots: 7,  shopFeeDiscount: -15,  chatColour: 'gold',         joinBroadcast: 'epic' },
    { id: 11, name: 'Archduke',    cost: 700000,    wildernessChunks: 700,  plotSlots: 6,  dailyBountySlots: 7,  shopFeeDiscount: -17,  chatColour: 'red',          joinBroadcast: 'epic' },
    { id: 12, name: 'Grand Duke',  cost: 1500000,   wildernessChunks: 900,  plotSlots: 7,  dailyBountySlots: 8,  shopFeeDiscount: -19,  chatColour: 'red',          joinBroadcast: 'epic_particles' },
    { id: 13, name: 'Sovereign',   cost: 10000000,  wildernessChunks: 1500, plotSlots: 10, dailyBountySlots: 10, shopFeeDiscount: -25,  chatColour: 'light_purple', joinBroadcast: 'epic_spectacular' },
]);
const MAX_TIER = 13;

// Bazaar's base sell fee, before tier discount. A Peasant pays 25%; a
// Sovereign with -25% discount pays 0%. Read by the sell-shop module.
const BAZAAR_BASE_FEE_PCT = 25;

// ─── Tier accessors ─────────────────────────────────────────────────
// Module-local helpers. Each consumer file declares its own TIER_CONFIG
// copy because KubeJS Rhino strict-mode doesn't allow cross-script globals.
// See feedback-kubejs-rhino-gotchas memory note.
const bnsTier = {
    // get the player's current tier (1-13). Defaults to 1 if unset.
    get: function(player) {
        const data = player.persistentData;
        if (!data.contains('bnsTier')) return 1;
        const t = data.getInt('bnsTier');
        return (t >= 1 && t <= MAX_TIER) ? t : 1;
    },

    // set the player's tier (1-13). Clamps to range.
    set: function(player, tier) {
        const clamped = Math.max(1, Math.min(MAX_TIER, tier|0));
        player.persistentData.putInt('bnsTier', clamped);
        return clamped;
    },

    // get the full config row for a tier (1-13).
    config: function(tier) {
        if (tier < 1 || tier > MAX_TIER) return null;
        return TIER_CONFIG[tier];
    },

    // get config for the player's current tier
    playerConfig: function(player) {
        return TIER_CONFIG[this.get(player)];
    },

    // expose the table read-only
    table: function() { return TIER_CONFIG; },

    // bazaar base fee accessor for the sell-shop module
    bazaarBaseFee: function() { return BAZAAR_BASE_FEE_PCT; },

    // effective shop-fee percentage for the player (base + discount).
    // Returns 0..25, never negative.
    effectiveShopFeePct: function(player) {
        const cfg = this.playerConfig(player);
        return Math.max(0, BAZAAR_BASE_FEE_PCT + cfg.shopFeeDiscount);
    },

    MAX: MAX_TIER,
};

// ─── Admin commands ──────────────────────────────────────────────────
// /bns admin tier get <player>
// /bns admin tier set <player> <tier>
// /bns admin tier list  (show the full table)
ServerEvents.commandRegistry(event => {
    const { commands: Commands, arguments: Arguments } = event;

    const tierCmd = Commands.literal('bns')
        .then(Commands.literal('admin')
            .requires(src => src.hasPermission(2))
            .then(Commands.literal('tier')

                .then(Commands.literal('get')
                    .then(Commands.argument('target', Arguments.PLAYER.create(event))
                        .executes(ctx => {
                            const t = Arguments.PLAYER.getResult(ctx, 'target');
                            const tier = bnsTier.get(t);
                            const cfg = bnsTier.config(tier);
                            ctx.source.sendSystemMessage(Text.aqua(
                                `${t.username}: tier ${tier} (${cfg.name})`
                            ));
                            return 1;
                        })))

                .then(Commands.literal('set')
                    .then(Commands.argument('target', Arguments.PLAYER.create(event))
                        .then(Commands.argument('tier', Arguments.INTEGER.create(event))
                            .executes(ctx => {
                                const t = Arguments.PLAYER.getResult(ctx, 'target');
                                const requested = Arguments.INTEGER.getResult(ctx, 'tier');
                                if (requested < 1 || requested > MAX_TIER) {
                                    ctx.source.sendSystemMessage(Text.red(
                                        `Tier must be 1..${MAX_TIER} (got ${requested})`
                                    ));
                                    return 0;
                                }
                                const actual = bnsTier.set(t, requested);
                                const cfg = bnsTier.config(actual);
                                ctx.source.sendSystemMessage(Text.gold(
                                    `Set ${t.username} -> tier ${actual} (${cfg.name})`
                                ));
                                t.tell(Text.gold(`You have been promoted to ${cfg.name}.`));
                                console.info(`[bns/tier] admin set ${t.username} tier=${actual} (${cfg.name})`);
                                return 1;
                            }))))

                .then(Commands.literal('list').executes(ctx => {
                    ctx.source.sendSystemMessage(Text.aqua('--- Tier ladder ---'));
                    for (let i = 1; i <= MAX_TIER; i++) {
                        const c = TIER_CONFIG[i];
                        ctx.source.sendSystemMessage(Text.gray(
                            `  ${i}. ${c.name}  cost ${c.cost}  chunks ${c.wildernessChunks}  plots ${c.plotSlots}  bounties ${c.dailyBountySlots}  fee ${c.shopFeeDiscount}%  ${c.chatColour}`
                        ));
                    }
                    return 1;
                }))
            )
        );

    event.register(tierCmd);
});

// ─── First-join: ensure tier defaults to 1 ──────────────────────────
// Doesn't conflict with welcome.js (different flag).
PlayerEvents.loggedIn(event => {
    const p = event.player;
    if (!p.persistentData.contains('bnsTier')) {
        bnsTier.set(p, 1);
        console.info(`[bns/tier] initialised ${p.username} to tier 1 (Peasant)`);
    }
});

console.info('[bns/tier_system] loaded — 13 tiers configured');
