using OTSSignsOrchestrator.Server.Clients;
using OTSSignsOrchestrator.Server.Data.Entities;

namespace OTSSignsOrchestrator.Server.Health.Checks;

/// <summary>
/// Verifies the <c>invite-{abbrev}</c> flow exists in Authentik by searching for it
/// in the invitation stages list.
/// </summary>
public sealed class InvitationFlowHealthCheck : IHealthCheck
{
    private readonly IAuthentikClient _authentikClient;
    private readonly ILogger<InvitationFlowHealthCheck> _logger;

    public string CheckName => "InvitationFlow";
    public bool AutoRemediate => false;

    public InvitationFlowHealthCheck(
        IAuthentikClient authentikClient,
        ILogger<InvitationFlowHealthCheck> logger)
    {
        _authentikClient = authentikClient;
        _logger = logger;
    }

    public async Task<HealthCheckResult> RunAsync(Instance instance, CancellationToken ct)
    {
        var abbrev = instance.Customer.Abbreviation;
        var expectedName = $"invite-{abbrev}";

        try
        {
            // Search Authentik groups for evidence of the invitation flow
            // The invitation is created as a stage invitation; we verify via the
            // Authentik API by searching for it by name.
            var groupResponse = await _authentikClient.ListGroupsAsync(expectedName);

            if (groupResponse.IsSuccessStatusCode && groupResponse.Content?.Results is { Count: > 0 })
            {
                var found = groupResponse.Content.Results.Any(g =>
                    g.TryGetValue("name", out var n) &&
                    string.Equals(n?.ToString(), expectedName, StringComparison.OrdinalIgnoreCase));

                if (found)
                {
                    return new HealthCheckResult(HealthStatus.Healthy,
                        $"Invitation flow '{expectedName}' exists in Authentik");
                }
            }

            // If groups don't show it, it's still possible the invitation was created
            // as a separate stage object. Log as degraded since we can't fully confirm.
            return new HealthCheckResult(HealthStatus.Degraded,
                $"Invitation flow '{expectedName}' not found in Authentik",
                "The invitation may exist but could not be verified via group search");
        }
        catch (Exception ex)
        {
            return new HealthCheckResult(HealthStatus.Critical,
                $"Failed to check invitation flow: {ex.Message}");
        }
    }
}
