/**
 * Сохранения в JSON-слотах. Хранилище инъекцией (localStorage или любой
 * Storage-подобный объект) — чтобы работать и в тестах без браузера.
 */
export interface StorageLike {
    getItem(key: string): string | null;
    setItem(key: string, value: string): void;
    removeItem(key: string): void;
    key(index: number): string | null;
    readonly length: number;
}

export class SaveManager {
    constructor(
        private storage: StorageLike,
        private prefix = 'save:'
    ) {}

    save(slot: string, data: unknown): void {
        this.storage.setItem(this.prefix + slot, JSON.stringify(data));
    }

    load<T = unknown>(slot: string): T | null {
        const raw = this.storage.getItem(this.prefix + slot);
        if (raw === null) return null;
        try {
            return JSON.parse(raw) as T;
        } catch {
            return null;
        }
    }

    delete(slot: string): void {
        this.storage.removeItem(this.prefix + slot);
    }

    /** Есть ли сохранение в слоте. */
    has(slot: string): boolean {
        return this.storage.getItem(this.prefix + slot) !== null;
    }

    /** Список занятых слотов (без префикса). */
    listSlots(): string[] {
        const out: string[] = [];
        for (let i = 0; i < this.storage.length; i++) {
            const key = this.storage.key(i);
            if (key && key.startsWith(this.prefix)) {
                out.push(key.slice(this.prefix.length));
            }
        }
        return out;
    }
}