using System.Text.Json;
using Microsoft.JSInterop;

namespace WebApp;

/// <summary>
/// Service for managing browser localStorage with type-safe methods.
/// </summary>
public sealed class LocalStorageService
{
    private readonly IJSRuntime _jsRuntime;

    public LocalStorageService(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    /// <summary>
    /// Gets a boolean value from localStorage.
    /// </summary>
    /// <param name="key">The storage key.</param>
    /// <param name="defaultValue">Default value if key doesn't exist or parsing fails.</param>
    /// <returns>The stored boolean value or default value.</returns>
    public async Task<bool> GetBoolAsync(string key, bool defaultValue = false)
    {
        try
        {
            var value = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
            return value != null && bool.TryParse(value, out var result) ? result : defaultValue;
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Sets a boolean value in localStorage.
    /// </summary>
    /// <param name="key">The storage key.</param>
    /// <param name="value">The boolean value to store.</param>
    public async Task SetBoolAsync(string key, bool value)
    {
        try
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to save boolean to localStorage [{key}]: {ex.Message}");
        }
    }

    /// <summary>
    /// Gets an integer value from localStorage.
    /// </summary>
    /// <param name="key">The storage key.</param>
    /// <param name="defaultValue">Default value if key doesn't exist or parsing fails.</param>
    /// <returns>The stored integer value or default value.</returns>
    public async Task<int> GetIntAsync(string key, int defaultValue = 0)
    {
        try
        {
            var value = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
            return value != null && int.TryParse(value, out var result) ? result : defaultValue;
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Sets an integer value in localStorage.
    /// </summary>
    /// <param name="key">The storage key.</param>
    /// <param name="value">The integer value to store.</param>
    public async Task SetIntAsync(string key, int value)
    {
        try
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to save integer to localStorage [{key}]: {ex.Message}");
        }
    }

    /// <summary>
    /// Gets an array of integers from localStorage (stored as JSON).
    /// </summary>
    /// <param name="key">The storage key.</param>
    /// <returns>Array of integers or empty array if not found.</returns>
    public async Task<int[]> GetIntArrayAsync(string key)
    {
        try
        {
            var json = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
            if (!string.IsNullOrEmpty(json))
            {
                var array = JsonSerializer.Deserialize<int[]>(json);
                return array ?? Array.Empty<int>();
            }
            return Array.Empty<int>();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to load integer array from localStorage [{key}]: {ex.Message}");
            return Array.Empty<int>();
        }
    }

    /// <summary>
    /// Sets an array of integers in localStorage (stored as JSON).
    /// </summary>
    /// <param name="key">The storage key.</param>
    /// <param name="values">The integer array to store.</param>
    public async Task SetIntArrayAsync(string key, int[] values)
    {
        try
        {
            var json = JsonSerializer.Serialize(values);
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, json);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to save integer array to localStorage [{key}]: {ex.Message}");
        }
    }

    /// <summary>
    /// Removes an item from localStorage.
    /// </summary>
    /// <param name="key">The storage key to remove.</param>
    public async Task RemoveAsync(string key)
    {
        try
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to remove from localStorage [{key}]: {ex.Message}");
        }
    }

    /// <summary>
    /// Clears all items from localStorage.
    /// </summary>
    public async Task ClearAsync()
    {
        try
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.clear");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to clear localStorage: {ex.Message}");
        }
    }
}
