using Microsoft.JSInterop;

namespace RolemasterDb.App.Frontend.AppState;

public sealed class ThemeState(BrowserStorageService browserStorage, IJSRuntime jsRuntime)
{
    private bool isInitialized;

    public ThemeMode CurrentMode { get; private set; } = ThemeMode.System;

    public event Action? Changed;

    public async Task InitializeAsync()
    {
        if (isInitialized)
        {
            return;
        }

        try
        {
            var storedMode = await browserStorage.GetItemAsync(BrowserStorageKeys.ThemeMode);
            CurrentMode = ParseMode(storedMode);
            await ApplyThemeAsync(CurrentMode);
            isInitialized = true;
            Changed?.Invoke();
        }
        catch (InvalidOperationException)
        {
            // JS interop is unavailable during prerender. Retry on the next interactive render.
        }
    }

    public async Task SetModeAsync(ThemeMode mode)
    {
        if (isInitialized && CurrentMode == mode)
        {
            return;
        }

        CurrentMode = mode;
        await ApplyThemeAsync(mode);
        await browserStorage.SetItemAsync(BrowserStorageKeys.ThemeMode, ToStorageValue(mode));
        isInitialized = true;
        Changed?.Invoke();
    }

    private Task ApplyThemeAsync(ThemeMode mode) =>
        jsRuntime.InvokeVoidAsync("rolemasterTheme.apply", ToStorageValue(mode)).AsTask();

    private static ThemeMode ParseMode(string? value) =>
        value?.Trim().ToLowerInvariant() switch
        {
            "light" => ThemeMode.Light,
            "dark" => ThemeMode.Dark,
            _ => ThemeMode.System
        };

    private static string ToStorageValue(ThemeMode mode) =>
        mode switch
        {
            ThemeMode.Light => "light",
            ThemeMode.Dark => "dark",
            _ => "system"
        };
}
