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

namespace YMhut.Box.Tests;

[TestClass]
public sealed class AgreementAcceptanceStoreTests
{
    [TestMethod]
    public void OldBooleanAgreementSettingRequiresResign()
    {
        var settings = new AppSettings
        {
            UserAgreementAccepted = true
        };

        Assert.IsFalse(AgreementDocument.SettingsMatchCurrent(settings));

        settings.UserAgreementVersion = AgreementDocument.CurrentVersion;

        Assert.IsTrue(AgreementDocument.SettingsMatchCurrent(settings));
    }

    [TestMethod]
    public async Task AgreementAcceptanceUsesMainSqliteAndSurvivesLogCleanup()
    {
        using var workspace = TestWorkspace.Create("ymhut-agreement-store");
        var paths = AppPaths.ForCurrentUser(workspace.Root);
        var store = new AgreementAcceptanceStore(paths);
        var logService = new SqliteLogService(paths);
        var acceptedAt = new DateTimeOffset(2026, 6, 15, 9, 30, 0, TimeSpan.Zero);

        await store.RecordAcceptedAsync(
            AgreementDocument.CurrentVersion,
            AgreementDocument.CurrentRevision,
            "2.0.6.2",
            "zh-CN",
            acceptedAt);
        await logService.WriteAsync("Information", "test", "log before cleanup");
        await logService.ClearAllAsync();

        var latest = await store.GetLatestAsync();

        Assert.AreEqual(Path.Combine(paths.Logs, AppDatabasePaths.MainDatabaseFileName), store.DatabasePath);
        Assert.IsNotNull(latest);
        Assert.AreEqual(AgreementDocument.CurrentVersion, latest.Version);
        Assert.AreEqual(AgreementDocument.CurrentRevision, latest.Revision);
        Assert.AreEqual("2.0.6.2", latest.AppVersion);
        Assert.AreEqual("zh-CN", latest.Language);
        Assert.AreEqual(acceptedAt, latest.AcceptedAt);
    }

    private sealed class TestWorkspace : IDisposable
    {
        private TestWorkspace(string root)
        {
            Root = root;
        }

        public string Root { get; }

        public static TestWorkspace Create(string prefix)
        {
            var root = Path.Combine(Path.GetTempPath(), prefix, Guid.NewGuid().ToString("N"));
            Directory.CreateDirectory(root);
            return new TestWorkspace(root);
        }

        public void Dispose()
        {
            SqliteConnection.ClearAllPools();
            if (Directory.Exists(Root))
            {
                Directory.Delete(Root, recursive: true);
            }
        }
    }
}
