using Refit;

namespace OTSSignsOrchestrator.Server.Clients;

// ── Configuration ───────────────────────────────────────────────────────────
public sealed class AuthentikOptions
{
    public const string Section = "Authentik";

    public string BaseUrl { get; set; } = string.Empty;
    public string ApiToken { get; set; } = string.Empty;

    /// <summary>UUID of the OTS signing certificate-key pair used for all SAML sources.</summary>
    public string OtsSigningKpId { get; set; } = string.Empty;

    /// <summary>Authentik pre-authentication flow slug for SAML sources (e.g. "default-source-pre-authentication").</summary>
    public string SourcePreAuthFlowSlug { get; set; } = "default-source-pre-authentication";

    /// <summary>Authentik authentication flow slug for SAML sources (e.g. "default-source-authentication").</summary>
    public string SourceAuthFlowSlug { get; set; } = "default-source-authentication";
}

// ── Request DTOs ────────────────────────────────────────────────────────────
public record CreateSamlProviderRequest(
    string Name,
    string AuthorizationFlow,
    string AcsUrl,
    string Issuer,
    string SpBinding,
    string Audience,
    string? SigningKp);

public record CreateAuthentikApplicationRequest(
    string Name,
    string Slug,
    string Provider,
    string? MetaLaunchUrl);

public record CreateAuthentikGroupRequest(
    string Name,
    bool? IsSuperuser,
    string? Parent);

public record CreateFlowRequest(
    string Name,
    bool? SingleUse,
    DateTimeOffset? Expires);

public record CreateAuthentikUserRequest(
    string Username,
    string Name,
    string Email,
    string[] Groups);

public record ImportCertRequest(
    string Name,
    string CertificateData,
    string? KeyData);

public record CreateSamlSourceRequest(
    string Name,
    string Slug,
    string SsoUrl,
    string? SloUrl,
    string Issuer,
    string? SigningKp,
    string? VerificationKp,
    string BindingType,
    string NameIdPolicy,
    string PreAuthenticationFlow,
    string AuthenticationFlow,
    bool AllowIdpInitiated);

// ── Response DTOs ───────────────────────────────────────────────────────────
/// <summary>Authentik paginated list response. Results contain dictionaries with entity fields.</summary>
public record AuthentikPagedResult(
    List<Dictionary<string, object>> Results);

// ── Authentik Refit Interface ───────────────────────────────────────────────
// One global Authentik instance serves all tenants.
[Headers("Authorization: Bearer")]
public interface IAuthentikClient
{
    // ── SAML Providers ──────────────────────────────────────────────────────
    [Post("/api/v3/providers/saml/")]
    Task<ApiResponse<Dictionary<string, object>>> CreateSamlProviderAsync(
        [Body] CreateSamlProviderRequest body);

    [Get("/api/v3/providers/saml/{id}/")]
    Task<ApiResponse<Dictionary<string, object>>> GetSamlProviderAsync(int id);

    [Delete("/api/v3/providers/saml/{id}/")]
    Task DeleteSamlProviderAsync(int id);

    // ── Applications ────────────────────────────────────────────────────────
    [Post("/api/v3/core/applications/")]
    Task<ApiResponse<Dictionary<string, object>>> CreateApplicationAsync(
        [Body] CreateAuthentikApplicationRequest body);

    [Delete("/api/v3/core/applications/{slug}/")]
    Task DeleteApplicationAsync(string slug);

    // ── Groups ──────────────────────────────────────────────────────────────
    [Get("/api/v3/core/groups/")]
    Task<ApiResponse<AuthentikPagedResult>> ListGroupsAsync([AliasAs("search")] string? search = null);

    [Post("/api/v3/core/groups/")]
    Task<ApiResponse<Dictionary<string, object>>> CreateGroupAsync(
        [Body] CreateAuthentikGroupRequest body);

    [Delete("/api/v3/core/groups/{id}/")]
    Task DeleteGroupAsync(string id);

    // ── Invitations ─────────────────────────────────────────────────────────
    [Post("/api/v3/stages/invitation/invitations/")]
    Task<ApiResponse<Dictionary<string, object>>> CreateInvitationAsync(
        [Body] CreateFlowRequest body);

    // ── Users ───────────────────────────────────────────────────────────────
    [Post("/api/v3/core/users/")]
    Task<ApiResponse<Dictionary<string, object>>> CreateUserAsync(
        [Body] CreateAuthentikUserRequest body);

    // ── Health ──────────────────────────────────────────────────────────────
    [Get("/api/v3/-/health/ready/")]
    Task<ApiResponse<object>> CheckHealthAsync();

    // ── Certificates ────────────────────────────────────────────────────────
    [Get("/api/v3/crypto/certificatekeypairs/{kpId}/")]
    Task<ApiResponse<Dictionary<string, object>>> GetCertificateKeyPairAsync(string kpId);

    [Post("/api/v3/crypto/certificatekeypairs/")]
    Task<ApiResponse<Dictionary<string, object>>> ImportCertificateAsync(
        [Body] ImportCertRequest body);

    // ── SAML Sources ────────────────────────────────────────────────────────
    [Post("/api/v3/sources/saml/")]
    Task<ApiResponse<Dictionary<string, object>>> CreateSamlSourceAsync(
        [Body] CreateSamlSourceRequest body);

    [Get("/api/v3/sources/saml/{slug}/metadata/")]
    Task<ApiResponse<string>> GetSamlSourceMetadataAsync(string slug);

    [Delete("/api/v3/sources/saml/{slug}/")]
    Task DeleteSamlSourceAsync(string slug);
}
