using System.Text.Json.Nodes;
using Eis.Infrastructure.Administration;

namespace Eis.Infrastructure.Tests.Administration;

public sealed class AdminPublicationProjectorTests
{
    [Fact]
    public void VirtualRoundUsesSettingAsPatchTargetAndSuppressesFinalDuplicate()
    {
        var setting = Record(
            "setting-1",
            "setting",
            "completed",
            new JsonObject
            {
                ["autoPublish"] = true,
                ["publicVisible"] = false,
                ["completedAt"] = "2026-06-02T00:00:00.000Z",
                ["roundPublishedAt"] = "2026-06-01T00:00:00.000Z"
            });
        var placement = Record(
            "placement-1",
            "placement",
            "final",
            new JsonObject { ["finalizedRound"] = 2 });
        var snapshot = Snapshot([setting, placement]);

        var publication = Assert.Single(AdminPublicationProjector.Build(snapshot));

        Assert.Equal("setting-1", publication["id"]?.GetValue<string>());
        Assert.Equal("admission", publication["sourceType"]?.GetValue<string>());
        Assert.Equal("示例考试第 2 轮录取名单公示", publication["title"]?.GetValue<string>());
        Assert.False(publication["visible"]?.GetValue<bool>());
        Assert.Equal("hidden", publication["status"]?.GetValue<string>());
        Assert.Same(setting, AdminPublicationProjector.FindSourceRecord(snapshot.Records, "admission", "setting-1"));
    }

    [Fact]
    public void ReportingPublicationMatchesNodeProjection()
    {
        var report = new AdminPublicationRecord(
            "report-1",
            "notification",
            "exam-1",
            null,
            "school-1",
            "approved",
            new JsonObject
            {
                ["type"] = "admission_reporting",
                ["supplementDecision"] = "supplement",
                ["approvedAt"] = "2026-06-03T00:00:00.000Z",
                ["statistics"] = new JsonObject
                {
                    ["totalQuota"] = 20,
                    ["reportedCount"] = 15,
                    ["reportingRate"] = 75
                }
            },
            "2026-06-01T00:00:00.000Z",
            "2026-06-03T00:00:00.000Z");

        var publication = Assert.Single(AdminPublicationProjector.Build(Snapshot([report])));

        Assert.Equal("reporting", publication["sourceType"]?.GetValue<string>());
        Assert.Equal("示例考试 · 示例学校考生报到情况及补录说明", publication["title"]?.GetValue<string>());
        Assert.Equal("计划 20 人，已报到 15 人，完成率 75%。", publication["summary"]?.GetValue<string>());
        Assert.True(publication["visible"]?.GetValue<bool>());
    }

    private static AdminPublicationRecord Record(string id, string kind, string status, JsonObject payload) => new(
        id,
        kind,
        "exam-1",
        null,
        null,
        status,
        payload,
        "2026-06-01T00:00:00.000Z",
        "2026-06-02T00:00:00.000Z");

    private static AdminNoticeManagementSnapshot Snapshot(IReadOnlyList<AdminPublicationRecord> records) => new(
        [],
        records,
        new Dictionary<string, string> { ["exam-1"] = "示例考试" },
        new Dictionary<string, string> { ["school-1"] = "示例学校" });
}
