using JobTrackerApi.Services;
using Xunit;

namespace JobTrackerApi.Tests;

public sealed class StageAnalyticsTests
{
    private static readonly DateTime Now = new(2026, 7, 1, 0, 0, 0, DateTimeKind.Utc);

    [Fact]
    public void Computes_median_days_per_active_stage()
    {
        var jobs = new[]
        {
            new StageOccupancy("Applied", Now.AddDays(-10)),
            new StageOccupancy("Applied", Now.AddDays(-20)),
            new StageOccupancy("Applied", Now.AddDays(-30)),
            new StageOccupancy("Interview", Now.AddDays(-4)),
        };

        var result = StageAnalytics.TimeInStage(jobs, Now);

        var applied = Assert.Single(result, p => p.Stage == "Applied");
        Assert.Equal(20, applied.MedianDays);
        Assert.Equal(3, applied.Count);

        var interview = Assert.Single(result, p => p.Stage == "Interview");
        Assert.Equal(4, interview.MedianDays);
    }

    [Fact]
    public void Excludes_closed_and_success_stages()
    {
        var jobs = new[]
        {
            new StageOccupancy("Offer", Now.AddDays(-5)),
            new StageOccupancy("Rejected", Now.AddDays(-5)),
            new StageOccupancy("Ghosted", Now.AddDays(-5)),
        };

        Assert.Empty(StageAnalytics.TimeInStage(jobs, Now));
    }

    [Fact]
    public void Normalizes_legacy_status_and_orders_by_pipeline()
    {
        var jobs = new[]
        {
            new StageOccupancy("Interviewing", Now.AddDays(-3)),
            new StageOccupancy("Applied", Now.AddDays(-1)),
            new StageOccupancy("Waiting", Now.AddDays(-2)),
        };

        var result = StageAnalytics.TimeInStage(jobs, Now);

        Assert.Equal(new[] { "Applied", "Waiting", "Interview" }, result.Select(p => p.Stage).ToArray());
    }

    [Fact]
    public void Empty_input_returns_empty()
        => Assert.Empty(StageAnalytics.TimeInStage(Array.Empty<StageOccupancy>(), Now));
}
