import type { Service } from '../types';

/** Local storage backed persistence layer used by the runtime. */
export default class StorageService implements Service
{
    public name = 'StorageService';
    public readonly serviceType = 'storage';

    private _cache: Record<string, unknown> = {};

    constructor()
    {
        this.readData();
    }

    public checkAvailable(): boolean
    {
        try
        {
            const testKey = '__storage_test__';

            window.localStorage.setItem(testKey, '1');
            window.localStorage.removeItem(testKey);

            return true;
        }
        catch
        {
            return false;
        }
    }

    public get id(): string
    {
        return __STORAGE_ID;
    }

    public get storageKey(): string
    {
        return `${this.id}${__OPTIONS__.cache_player_id}`;
    }

    public set(key: string, value: unknown): void
    {
        this._cache[key] = value;
        this.writeData();
    }

    public get<T = unknown>(key: string): T | undefined
    {
        return this._cache[key] as T | undefined;
    }

    public readData(): void
    {
        const raw = window.localStorage.getItem(this.storageKey);

        if (!raw)
        {
            this._cache = {};

            return;
        }

        try
        {
            const parsed = JSON.parse(raw) as Record<string, unknown>;

            this._cache = { ...parsed };
        }
        catch
        {
            this._cache = {};
        }
    }

    public writeData(): void
    {
        window.localStorage.setItem(this.storageKey, JSON.stringify(this._cache));
    }

    public delete(key: string): void
    {
        delete this._cache[key];
        this.writeData();
    }

    public clear(): void
    {
        window.localStorage.removeItem(this.storageKey);
        this._cache = {};
    }

    public dispose(): void
    {
        this._cache = {};
    }
}
