using ColaFlow.Shared.Kernel.Common;

namespace ColaFlow.Modules.Identity.Domain.Aggregates.Tenants;

public sealed class SsoConfiguration : ValueObject
{
    public SsoProvider Provider { get; }
    public string Authority { get; }
    public string ClientId { get; }
    public string ClientSecret { get; } // Encrypted in database
    public string? MetadataUrl { get; }

    // SAML-specific
    public string? EntityId { get; }
    public string? SignOnUrl { get; }
    public string? Certificate { get; }

    private SsoConfiguration(
        SsoProvider provider,
        string authority,
        string clientId,
        string clientSecret,
        string? metadataUrl = null,
        string? entityId = null,
        string? signOnUrl = null,
        string? certificate = null)
    {
        Provider = provider;
        Authority = authority;
        ClientId = clientId;
        ClientSecret = clientSecret;
        MetadataUrl = metadataUrl;
        EntityId = entityId;
        SignOnUrl = signOnUrl;
        Certificate = certificate;
    }

    public static SsoConfiguration CreateOidc(
        SsoProvider provider,
        string authority,
        string clientId,
        string clientSecret,
        string? metadataUrl = null)
    {
        if (provider == SsoProvider.GenericSaml)
            throw new ArgumentException("Use CreateSaml for SAML configuration");

        if (string.IsNullOrWhiteSpace(authority))
            throw new ArgumentException("Authority is required", nameof(authority));

        if (string.IsNullOrWhiteSpace(clientId))
            throw new ArgumentException("Client ID is required", nameof(clientId));

        if (string.IsNullOrWhiteSpace(clientSecret))
            throw new ArgumentException("Client secret is required", nameof(clientSecret));

        return new SsoConfiguration(provider, authority, clientId, clientSecret, metadataUrl);
    }

    public static SsoConfiguration CreateSaml(
        string entityId,
        string signOnUrl,
        string certificate,
        string? metadataUrl = null)
    {
        if (string.IsNullOrWhiteSpace(entityId))
            throw new ArgumentException("Entity ID is required", nameof(entityId));

        if (string.IsNullOrWhiteSpace(signOnUrl))
            throw new ArgumentException("Sign-on URL is required", nameof(signOnUrl));

        if (string.IsNullOrWhiteSpace(certificate))
            throw new ArgumentException("Certificate is required", nameof(certificate));

        return new SsoConfiguration(
            SsoProvider.GenericSaml,
            signOnUrl,
            entityId,
            string.Empty, // No client secret for SAML
            metadataUrl,
            entityId,
            signOnUrl,
            certificate);
    }

    protected override IEnumerable<object> GetAtomicValues()
    {
        yield return Provider;
        yield return Authority;
        yield return ClientId;
        yield return EntityId ?? string.Empty;
    }
}
