using ClawdDotNet.Core.Scheduling;
using Shouldly;

namespace ClawdDotNet.Core.Tests.Scheduling;

/// <summary>
/// Zeitzonen heißen auf Windows und Linux verschieden. Task-Dateien wandern zwischen
/// beiden — also muss jede Seite die Schreibweise der anderen deuten können.
///
/// Die Tests laufen bewusst auf beiden Plattformen mit denselben Erwartungen: Genau
/// das ist die Eigenschaft, die wir brauchen.
/// </summary>
public sealed class TimeZonesTests
{
    [Theory]
    [InlineData("Europe/Berlin")]
    [InlineData("W. Europe Standard Time")]
    [InlineData("America/New_York")]
    [InlineData("Eastern Standard Time")]
    [InlineData("UTC")]
    public void Beide_Schreibweisen_sind_aufloesbar(string id)
    {
        TimeZones.TryResolve(id).ShouldNotBeNull();
        TimeZones.IsKnown(id).ShouldBeTrue();
    }

    [Fact]
    public void Beide_Schreibweisen_meinen_dieselbe_Zone()
    {
        var iana = TimeZones.TryResolve("Europe/Berlin");
        var windows = TimeZones.TryResolve("W. Europe Standard Time");

        var sommer = new DateTime(2026, 7, 31, 12, 0, 0, DateTimeKind.Utc);

        iana!.GetUtcOffset(sommer).ShouldBe(windows!.GetUtcOffset(sommer));
        iana.GetUtcOffset(sommer).ShouldBe(TimeSpan.FromHours(2)); // MESZ
    }

    [Theory]
    [InlineData("Phantasie/Ort")]
    [InlineData("Nicht Existierende Standard Time")]
    [InlineData("völliger Unsinn")]
    public void Unbekannte_Kennungen_werden_gemeldet_statt_geraten(string id)
    {
        TimeZones.TryResolve(id).ShouldBeNull();
        TimeZones.IsKnown(id).ShouldBeFalse();
    }

    [Fact]
    public void Leer_gilt_als_gueltig_denn_es_bedeutet_keine_Angabe()
    {
        TimeZones.IsKnown("").ShouldBeTrue();
        TimeZones.IsKnown(null).ShouldBeTrue();
        TimeZones.IsKnown("   ").ShouldBeTrue();
    }

    [Theory]
    [InlineData("W. Europe Standard Time", "Europe/Berlin")]
    [InlineData("Europe/Berlin", "Europe/Berlin")]
    [InlineData("", "")]
    public void Normalisieren_ergibt_die_IANA_Schreibweise(string input, string expected)
    {
        TimeZones.ToIana(input).ShouldBe(expected);
    }

    [Fact]
    public void Eine_nicht_umsetzbare_Kennung_bleibt_unveraendert()
    {
        // Verfälschen wäre schlimmer als durchreichen — so bleibt im Zweifel sichtbar,
        // was ursprünglich dastand.
        TimeZones.ToIana("Phantasie Standard Time").ShouldBe("Phantasie Standard Time");
    }

    [Fact]
    public void Die_lokale_Zone_wird_in_IANA_Schreibweise_geliefert()
    {
        var local = TimeZones.LocalIanaId;

        local.ShouldNotBeNullOrWhiteSpace();
        TimeZones.IsKnown(local).ShouldBeTrue();

        // Der eigentliche Punkt: Was hier herauskommt, wird in Task-Dateien geschrieben
        // und muss auf der anderen Plattform lesbar sein. IANA-Kennungen enthalten einen
        // Schrägstrich, Windows-Kennungen nie — UTC ist die Ausnahme ohne beides.
        if (local != "UTC")
            local.ShouldContain("/");
    }
}
