using Microsoft.Data.Sqlite;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using YMhut.Box.Core.App;
using YMhut.Box.Core.Logging;

namespace YMhut.Box.Tests;

[TestClass]
public sealed class LogServiceTests
{
    [TestMethod]
    public void LogDisplayLocalizerUsesEmptyDetailTextInsteadOfUnknownError()
    {
        Assert.AreEqual("暂无详情", LogDisplayLocalizer.Detail(null, "zh-CN"));
        Assert.AreEqual("No details", LogDisplayLocalizer.Detail("   ", "en-US"));
        Assert.AreEqual("真实详情", LogDisplayLocalizer.Detail("真实详情", "zh-CN"));
    }

    [TestMethod]
    public void LogDisplayLocalizerTranslatesCommonEnglishMessagesInChineseMode()
    {
        Assert.AreEqual("打开启动自检结果", LogDisplayLocalizer.Message("Open startup check results", "zh-CN"));
        Assert.AreEqual("工具目录已重建", LogDisplayLocalizer.Message("Tool catalog rebuilt", "zh-CN"));
        StringAssert.Contains(LogDisplayLocalizer.Message("External tool success: launch", "zh-CN"), "外部工具成功");
        Assert.AreEqual("外部工具成功", LogDisplayLocalizer.Message("External tool success", "zh-CN"));
        StringAssert.Contains(LogDisplayLocalizer.Message("Tool result canceled: export", "zh-CN"), "工具结果已取消");
        Assert.AreEqual("工具工作进程已就绪", LogDisplayLocalizer.Message("Tool worker ready", "zh-CN"));
        Assert.AreEqual("下载宿主进程已启动", LogDisplayLocalizer.Message("Download host process started", "zh-CN"));
        Assert.AreEqual("打开插件页面：sample/main", LogDisplayLocalizer.Message("Open plugin surface: sample/main", "zh-CN"));
        Assert.AreEqual("打开 JSON formatter", LogDisplayLocalizer.Message("Open JSON formatter", "zh-CN"));
        Assert.AreEqual("\u66f4\u65b0\u901a\u77e5\u68c0\u67e5\u5931\u8d25", LogDisplayLocalizer.Message("Update notice check failed", "zh-CN"));
        Assert.AreEqual("\u542f\u52a8\u81ea\u68c0\u7ed3\u679c\u9884\u52a0\u8f7d\u5931\u8d25", LogDisplayLocalizer.Message("Startup check result preload failed", "zh-CN"));
        Assert.AreEqual("\u8bbe\u7f6e\u9875\u52a0\u8f7d\u5931\u8d25", LogDisplayLocalizer.Message("Settings page load failed", "zh-CN"));
        Assert.AreEqual("\u5df2\u8bb0\u4f4f\u5173\u95ed\u786e\u8ba4\u9009\u62e9", LogDisplayLocalizer.Message("Close confirmation remembered", "zh-CN"));
    }

    [TestMethod]
    public void LogDisplayLocalizerTranslatesCommonDetailKeysInChineseMode()
    {
        var detail = LogDisplayLocalizer.Detail("result=success; operation=launch; elapsedMs=12; root=C:\\Tools; count=8", "zh-CN");

        StringAssert.Contains(detail, "结果=成功");
        StringAssert.Contains(detail, "操作=启动");
        StringAssert.Contains(detail, "耗时毫秒=12");
        StringAssert.Contains(detail, "根目录=C:\\Tools");
        StringAssert.Contains(detail, "数量=8");

        var windowDetail = LogDisplayLocalizer.Detail("source=tray; behavior=minimize_to_tray; result=primary; dialog=com_exception", "zh-CN");

        StringAssert.Contains(windowDetail, "来源=托盘");
        StringAssert.Contains(windowDetail, "行为=最小化到托盘");
        StringAssert.Contains(windowDetail, "结果=主按钮");
        StringAssert.Contains(windowDetail, "弹窗=COM 异常");
    }

    [TestMethod]
    public async Task ClearFilteredTodayDeletesOnlyMatchingRows()
    {
        var tempRoot = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"));
        try
        {
            var service = new SqliteLogService(AppPaths.ForCurrentUser(tempRoot));
            await service.WriteAsync("Information", "tool", "Open tool: JSON formatter");
            await service.WriteAsync("Warning", "network", "Proxy diagnostic failed");

            await service.ClearFilteredTodayAsync("Information", "JSON");

            var entries = await service.ReadAsync(take: 10);
            Assert.HasCount(1, entries);
            Assert.AreEqual("network", entries[0].Category);
        }
        finally
        {
            SqliteConnection.ClearAllPools();
            Directory.Delete(tempRoot, recursive: true);
        }
    }

    [TestMethod]
    public async Task ReadByDateReturnsAllMatchingRowsForSelectedDay()
    {
        var tempRoot = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"));
        try
        {
            var service = new SqliteLogService(AppPaths.ForCurrentUser(tempRoot));
            await service.WriteAsync("Information", "tool", "Open JSON formatter");
            await service.WriteAsync("Information", "tool", "Open URL codec");
            await service.WriteAsync("Warning", "network", "Proxy diagnostic failed");

            var allToday = await service.ReadByDateAsync(DateOnly.FromDateTime(DateTime.Now));
            var filtered = await service.ReadByDateAsync(DateOnly.FromDateTime(DateTime.Now), "Information", "Open");

            Assert.HasCount(3, allToday);
            Assert.HasCount(2, filtered);
        }
        finally
        {
            SqliteConnection.ClearAllPools();
            Directory.Delete(tempRoot, recursive: true);
        }
    }

    [TestMethod]
    public async Task ReadByDatePageReturnsStablePages()
    {
        var tempRoot = Path.Combine(Path.GetTempPath(), "ymhut-box-tests", Guid.NewGuid().ToString("N"));
        try
        {
            var service = new SqliteLogService(AppPaths.ForCurrentUser(tempRoot));
            for (var index = 0; index < 25; index++)
            {
                await service.WriteAsync("Information", "stream", $"Row {index:00}");
            }

            var today = DateOnly.FromDateTime(DateTime.Now);
            var first = await service.ReadByDatePageAsync(today, "Information", "Row", skip: 0, take: 20);
            var second = await service.ReadByDatePageAsync(today, "Information", "Row", skip: 20, take: 20);

            Assert.HasCount(20, first);
            Assert.HasCount(5, second);
            CollectionAssert.AreNotEquivalent(
                first.Select(entry => entry.Message).ToArray(),
                second.Select(entry => entry.Message).ToArray());
        }
        finally
        {
            SqliteConnection.ClearAllPools();
            Directory.Delete(tempRoot, recursive: true);
        }
    }
}
