using Bunit;
using Microsoft.AspNetCore.Components;
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;

namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Shared;

/// <summary>
/// Component tests for <see cref="DateTimeRangeFilter"/> — the reusable from/to
/// datetime-local input pair.  The component is INPUT-ONLY: it emits raw
/// DateTime? (Unspecified kind); UTC conversion is the page's responsibility.
/// </summary>
public class DateTimeRangeFilterTests : BunitContext
{
    [Fact]
    public void Renders_TwoInputs_WithPrefixedIdsAndTestHooks()
    {
        var cut = Render<DateTimeRangeFilter>(ps => ps
            .Add(p => p.IdPrefix, "sc"));

        var fromInput = cut.Find("[data-test='sc-from']");
        var toInput   = cut.Find("[data-test='sc-to']");

        Assert.Equal("datetime-local", fromInput.GetAttribute("type"));
        Assert.Equal("datetime-local", toInput.GetAttribute("type"));
        Assert.Equal("sc-from", fromInput.GetAttribute("id"));
        Assert.Equal("sc-to",   toInput.GetAttribute("id"));
    }

    [Fact]
    public void RendersLabels()
    {
        var cut = Render<DateTimeRangeFilter>(ps => ps
            .Add(p => p.FromLabel, "Start")
            .Add(p => p.ToLabel,   "End"));

        cut.Find("label[for='dtr-from']");   // default IdPrefix = "dtr"
        cut.Find("label[for='dtr-to']");

        Assert.Contains("Start", cut.Markup);
        Assert.Contains("End",   cut.Markup);
    }

    [Fact]
    public void SettingFromInput_InvokesFromChanged_WithParsedValue()
    {
        DateTime? captured = default;
        var cut = Render<DateTimeRangeFilter>(ps => ps
            .Add(p => p.IdPrefix, "sc")
            .Add(p => p.FromChanged,
                EventCallback.Factory.Create<DateTime?>(this, v => captured = v)));

        cut.Find("[data-test='sc-from']").Change("2026-06-01T08:30");

        Assert.NotNull(captured);
        Assert.Equal(2026, captured!.Value.Year);
        Assert.Equal(6,    captured.Value.Month);
        Assert.Equal(1,    captured.Value.Day);
        Assert.Equal(8,    captured.Value.Hour);
        Assert.Equal(30,   captured.Value.Minute);
    }

    [Fact]
    public void ClearingFromInput_InvokesFromChanged_WithNull()
    {
        DateTime? captured = new DateTime(2026, 1, 1);
        var cut = Render<DateTimeRangeFilter>(ps => ps
            .Add(p => p.IdPrefix, "sc")
            .Add(p => p.From, new DateTime(2026, 1, 1))
            .Add(p => p.FromChanged,
                EventCallback.Factory.Create<DateTime?>(this, v => captured = v)));

        cut.Find("[data-test='sc-from']").Change("");

        Assert.Null(captured);
    }

    [Fact]
    public void InitialValue_RendersInInput()
    {
        var initial = new DateTime(2025, 12, 31, 23, 59, 0);
        var cut = Render<DateTimeRangeFilter>(ps => ps
            .Add(p => p.From, initial));

        var value = cut.Find("[data-test='dtr-from']").GetAttribute("value");
        Assert.Equal("2025-12-31T23:59", value);
    }
}
