/**
 * InventoryManager — инвентарь игрока (9 слотов hot-bar).
 *
 * Каждый слот хранит {id, kind, modelTypeId, name, params} или null.
 * kind:
 *   'weapon' — оружие (бластер/меч/...). params: { damage, fireRate, range, ammo, ... }
 *   'tool'   — инструмент.
 *   'item'   — обычный предмет (зелье и т.п.).
 *
 * События:
 *   change → onChange callback (для GUI hot-bar в React).
 */

const SLOTS = 5;

let _seq = 1;

export class InventoryManager {
    constructor() {
        /** @type {Array<object|null>} */
        this.slots = new Array(SLOTS).fill(null);
        this.activeIndex = 0;
        this._onChange = null;
    }

    setOnChange(cb) { this._onChange = cb; }
    _notify() { if (this._onChange) try { this._onChange(); } catch (e) { /* ignore */ } }

    /** Положить предмет в первый свободный слот. Возвращает индекс или -1. */
    add(item) {
        const idx = this.slots.findIndex(s => s == null);
        if (idx < 0) return -1;
        this.slots[idx] = this._normalize(item);
        this._notify();
        return idx;
    }

    /** Положить в конкретный слот (заменяет содержимое). */
    setSlot(index, item) {
        if (index < 0 || index >= SLOTS) return;
        this.slots[index] = item ? this._normalize(item) : null;
        this._notify();
    }

    removeSlot(index) {
        if (index < 0 || index >= SLOTS) return;
        this.slots[index] = null;
        this._notify();
    }

    getActive() {
        return this.slots[this.activeIndex] || null;
    }

    setActive(index) {
        if (index < 0 || index >= SLOTS) return;
        this.activeIndex = index;
        this._notify();
    }

    serialize() {
        return {
            slots: this.slots.map(s => s ? { ...s } : null),
            activeIndex: this.activeIndex,
        };
    }

    loadFromArray(data) {
        if (!data) {
            this.slots = new Array(SLOTS).fill(null);
            this.activeIndex = 0;
            this._notify();
            return;
        }
        if (Array.isArray(data.slots)) {
            this.slots = new Array(SLOTS).fill(null);
            for (let i = 0; i < Math.min(SLOTS, data.slots.length); i++) {
                this.slots[i] = data.slots[i] ? this._normalize(data.slots[i]) : null;
            }
        }
        if (Number.isFinite(data.activeIndex)) {
            this.activeIndex = Math.max(0, Math.min(SLOTS - 1, data.activeIndex));
        }
        this._notify();
    }

    clear() {
        this.slots = new Array(SLOTS).fill(null);
        this.activeIndex = 0;
        this._notify();
    }

    _normalize(item) {
        return {
            id: item.id || `inv_${Date.now()}_${(_seq++).toString(36)}`,
            kind: item.kind || 'item',
            modelTypeId: item.modelTypeId || null,
            name: item.name || 'Предмет',
            params: item.params ? { ...item.params } : {},
        };
    }
}

InventoryManager.SLOTS = SLOTS;
