using Microsoft.VisualStudio.TestTools.UnitTesting;
using YMhut.Box.Core.Settings;

namespace YMhut.Box.Tests;

[TestClass]
public sealed class AppSettingsStoreTests
{
    [TestMethod]
    public async Task NewSettingsDefaultToDashboardHome()
    {
        var root = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"));
        var store = new AppSettingsStore(root);

        var settings = await store.LoadAsync();

        Assert.AreEqual("dashboard", settings.HomePageMode);
    }

    [TestMethod]
    public async Task RecordRecentToolKeepsNewestFirstAndUnique()
    {
        var root = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"));
        var store = new AppSettingsStore(root);

        await store.RecordRecentToolAsync("json_formatter");
        await store.RecordRecentToolAsync("safe_browser");
        await store.RecordRecentToolAsync("json_formatter");

        var settings = await store.LoadAsync();
        CollectionAssert.AreEqual(
            new[] { "json_formatter", "safe_browser" },
            settings.RecentToolIds);
    }

    [TestMethod]
    public async Task LoadAsyncImportsLegacySettingsOnce()
    {
        var root = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"), "WinUI");
        var legacyPath = Path.Combine(Path.GetDirectoryName(root)!, "YMhut Box", "settings.json");
        Directory.CreateDirectory(Path.GetDirectoryName(legacyPath)!);
        await File.WriteAllTextAsync(legacyPath, """
        {
          "theme": "Dark",
          "recentToolIds": [
            "safe_browser"
          ],
          "legacyImportCompleted": false
        }
        """);

        var store = new AppSettingsStore(root);
        var settings = await store.LoadAsync();

        Assert.IsTrue(settings.LegacyImportCompleted);
        Assert.AreEqual("Dark", settings.Theme);
        CollectionAssert.AreEqual(new[] { "safe_browser" }, settings.RecentToolIds);
    }

    [TestMethod]
    public async Task LoadAsyncImportsLegacySharedPreferences()
    {
        var root = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"), "WinUI");
        var legacyPath = Path.Combine(Path.GetDirectoryName(root)!, "ymhut_box", "shared_preferences.json");
        Directory.CreateDirectory(Path.GetDirectoryName(legacyPath)!);
        var legacyPrefix = string.Concat("flut", "ter.");
        await File.WriteAllTextAsync(legacyPath, """
        {
          "__PREFIX__theme": "dark",
          "__PREFIX__pitch_black": true,
          "__PREFIX__seed_color": -10458044,
          "__PREFIX__card_opacity": 0.64,
          "__PREFIX__background_image": "D:\\Images\\wallpaper.png",
          "__PREFIX__background_opacity": 0.42,
          "__PREFIX__user_agreement_accepted": true,
          "__PREFIX__sidebar_collapsed": true,
          "__PREFIX__desktop_titlebar": false,
          "__PREFIX__recent_tool_ids": [
            "media_player",
            "safe_browser"
          ],
          "__PREFIX__pinned_tool_ids": [
            "json_formatter"
          ],
          "__PREFIX__window_x": 12.5,
          "__PREFIX__window_y": 24.5,
          "__PREFIX__window_width": 1280,
          "__PREFIX__window_height": 760,
          "__PREFIX__window_maximized": true,
          "__PREFIX__proxy_enabled": true,
          "__PREFIX__proxy_mode": "manual",
          "__PREFIX__proxy_host": "127.0.0.1",
          "__PREFIX__proxy_port": 7891,
          "__PREFIX__animations_enabled": false,
          "__PREFIX__font_size": 1.15,
          "__PREFIX__tool_display_mode": "list",
          "__PREFIX__close_behavior": "minimize_then_exit",
          "__PREFIX__restore_window_position": false,
          "__PREFIX__auto_start": true,
          "__PREFIX__log_retention_count": 300,
          "__PREFIX__data_refresh_interval": 45,
          "__PREFIX__update_notification": false,
          "__PREFIX__hardware_acceleration_enabled": false,
          "__PREFIX__proxy_test_timeout_seconds": 9
        }
        """.Replace("__PREFIX__", legacyPrefix));

        var store = new AppSettingsStore(root);
        var settings = await store.LoadAsync();

        Assert.AreEqual("Dark", settings.Theme);
        Assert.IsTrue(settings.PitchBlack);
        Assert.AreEqual(-10458044, settings.SeedColor);
        Assert.AreEqual(0.64, settings.CardOpacity, 0.001);
        Assert.AreEqual("D:\\Images\\wallpaper.png", settings.BackgroundImage);
        Assert.AreEqual(0.42, settings.BackgroundOpacity, 0.001);
        Assert.IsTrue(settings.UserAgreementAccepted);
        Assert.IsTrue(settings.SidebarCollapsed);
        Assert.IsFalse(settings.DesktopTitlebar);
        CollectionAssert.AreEqual(new[] { "media_player", "safe_browser" }, settings.RecentToolIds);
        CollectionAssert.AreEqual(new[] { "json_formatter" }, settings.PinnedToolIds);
        Assert.AreEqual(12.5, settings.WindowX);
        Assert.AreEqual(24.5, settings.WindowY);
        Assert.AreEqual(1280, settings.WindowWidth);
        Assert.AreEqual(760, settings.WindowHeight);
        Assert.IsTrue(settings.WindowMaximized);
        Assert.IsTrue(settings.ProxyEnabled);
        Assert.AreEqual("manual", settings.ProxyMode);
        Assert.AreEqual("127.0.0.1", settings.ProxyHost);
        Assert.AreEqual(7891, settings.ProxyPort);
        Assert.IsFalse(settings.AnimationsEnabled);
        Assert.AreEqual(1.15, settings.FontSize, 0.001);
        Assert.AreEqual("list", settings.ToolDisplayMode);
        Assert.AreEqual("minimize_then_exit", settings.CloseBehavior);
        Assert.IsFalse(settings.RestoreWindowPosition);
        Assert.IsTrue(settings.AutoStart);
        Assert.AreEqual(300, settings.LogRetentionCount);
        Assert.AreEqual(45, settings.DataRefreshInterval);
        Assert.IsFalse(settings.UpdateNotification);
        Assert.IsFalse(settings.HardwareAccelerationEnabled);
        Assert.AreEqual(9, settings.ProxyTestTimeoutSeconds);
    }

    [TestMethod]
    public void PinnedToolSettingsTogglesUniquelyAndTrims()
    {
        var pinned = Enumerable.Range(0, 70)
            .Select(index => $"tool_{index:00}")
            .ToList();
        pinned.Insert(10, "json_formatter");

        PinnedToolSettings.Toggle(pinned, "json_formatter", wasPinned: false);

        Assert.HasCount(64, pinned);
        Assert.AreEqual("json_formatter", pinned[0]);
        Assert.AreEqual(1, pinned.Count(id => string.Equals(id, "json_formatter", StringComparison.OrdinalIgnoreCase)));

        PinnedToolSettings.Toggle(pinned, "JSON_FORMATTER", wasPinned: true);

        Assert.HasCount(63, pinned);
        Assert.IsFalse(pinned.Any(id => string.Equals(id, "json_formatter", StringComparison.OrdinalIgnoreCase)));
    }

    [TestMethod]
    public async Task LoadAsyncNormalizesGlobalMaterialSettings()
    {
        var root = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"));
        Directory.CreateDirectory(root);
        await File.WriteAllTextAsync(Path.Combine(root, "settings.json"), """
        {
          "legacyImportCompleted": true,
          "windowBackdrop": "desktop_acrylic",
          "settingsPanelMaterial": "frosted_glass",
          "topBarMaterial": "frosted_glass"
        }
        """);

        var store = new AppSettingsStore(root);
        var settings = await store.LoadAsync();

        Assert.AreEqual("acrylic", settings.WindowBackdrop);
        Assert.AreEqual("glass", settings.SettingsPanelMaterial);
        Assert.AreEqual("glass", settings.TopBarMaterial);
    }
}
