using System.Text.Json;
using PersonalToolBox.Models;

namespace PersonalToolBox.Tests.Models;

public class ModelSerializationTests
{
    private static readonly JsonSerializerOptions Options = new()
    {
        WriteIndented = true,
        PropertyNameCaseInsensitive = true
    };

    [Fact]
    public void AppConfig_Serialize_ProducesValidJson()
    {
        var config = new AppConfig
        {
            Theme = "Dark",
            AutoStart = true,
            Categories =
            [
                new() { Id = "1", Name = "开发工具" },
                new() { Id = "2", Name = "常用脚本" }
            ],
            Tools =
            [
                new()
                {
                    Id = "tool-1",
                    Name = "Postman",
                    IconCode = "f0c2",
                    ExecutablePath = @"D:\tools\postman.exe",
                    Arguments = "",
                    CategoryId = "1",
                    HotKey = "Ctrl+Alt+P"
                }
            ]
        };

        var json = JsonSerializer.Serialize(config, Options);
        var deserialized = JsonSerializer.Deserialize<AppConfig>(json, Options);

        Assert.NotNull(deserialized);
        Assert.Equal("Dark", deserialized.Theme);
        Assert.True(deserialized.AutoStart);
        Assert.Equal(2, deserialized.Categories.Count);
        Assert.Single(deserialized.Tools);
    }

    [Fact]
    public void ToolItem_IsValid_NotIncludedInJson()
    {
        var tool = new ToolItem
        {
            Name = "TestTool",
            ExecutablePath = @"C:\nonexistent.exe",
            IsValid = false
        };

        var json = JsonSerializer.Serialize(tool, Options);

        Assert.DoesNotContain("IsValid", json);
    }

    [Fact]
    public void ToolItem_DefaultValues_AreCorrect()
    {
        var tool = new ToolItem();

        Assert.NotEmpty(tool.Id);
        Assert.Empty(tool.Name);
        Assert.True(tool.IsValid);
    }

    [Fact]
    public void Category_DefaultId_IsNotEmpty()
    {
        var cat = new Category();
        Assert.NotEmpty(cat.Id);
    }

    [Fact]
    public void AppConfig_DefaultValues_AreCorrect()
    {
        var config = new AppConfig();

        Assert.Equal("Dark", config.Theme);
        Assert.False(config.AutoStart);
        Assert.NotNull(config.Categories);
        Assert.NotNull(config.Tools);
        Assert.Empty(config.Categories);
        Assert.Empty(config.Tools);
    }

    [Fact]
    public void Deserialize_EmptyJson_ProducesValidConfig()
    {
        var json = "{}";
        var config = JsonSerializer.Deserialize<AppConfig>(json, Options);

        Assert.NotNull(config);
        Assert.Equal("Dark", config.Theme);
        Assert.False(config.AutoStart);
        Assert.Empty(config.Categories);
        Assert.Empty(config.Tools);
    }

    [Fact]
    public void Deserialize_WithUnknownProperty_IgnoresIt()
    {
        var json = """{"unknownField": 123, "Theme": "Light"}""";
        var config = JsonSerializer.Deserialize<AppConfig>(json, Options);

        Assert.NotNull(config);
        Assert.Equal("Light", config.Theme);
    }
}
