using CashLineERP.Contracts.Integration;

namespace CashLineERP.Application.Integration;

public sealed class IntegrationEndpointRegistryService : IIntegrationEndpointRegistryService
{
    private readonly IIntegrationEndpointRegistryRepository _repository;

    public IntegrationEndpointRegistryService(IIntegrationEndpointRegistryRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<IntegrationEndpointResponse> GetIntegrationEndpoints(
        bool activeOnly = false,
        string? integrationProviderCode = null,
        string? environmentCode = null) =>
        _repository.GetIntegrationEndpoints(activeOnly, integrationProviderCode, environmentCode)
            .Select(Map)
            .ToArray();

    public IntegrationEndpointResponse? GetIntegrationEndpoint(long integrationEndpointId)
    {
        var endpoint = _repository.GetIntegrationEndpoint(integrationEndpointId);
        return endpoint is null ? null : Map(endpoint);
    }

    public IntegrationEndpointResponse CreateIntegrationEndpoint(CreateIntegrationEndpointRequest request) =>
        Map(_repository.Create(new CreateIntegrationEndpointCommand(
            request.EndpointName,
            request.IntegrationProviderCode,
            request.EnvironmentCode,
            request.DirectionCode,
            request.TransportCode,
            request.HttpMethodCode,
            request.BaseUrl,
            request.RelativePath,
            request.AuthenticationModeCode,
            request.CredentialReference,
            request.TimeoutSeconds,
            request.RetryPolicyCode,
            request.MaxRetryCount,
            request.IsIdempotencyKeyRequired,
            request.Notes)));

    public IntegrationEndpointResponse SubmitIntegrationEndpoint(long integrationEndpointId, long actorUserId) =>
        Map(_repository.Submit(integrationEndpointId, actorUserId));

    public IntegrationEndpointResponse ApproveIntegrationEndpoint(long integrationEndpointId, long actorUserId) =>
        Map(_repository.Approve(integrationEndpointId, actorUserId));

    public IntegrationEndpointResponse ActivateIntegrationEndpoint(long integrationEndpointId, long actorUserId) =>
        Map(_repository.Activate(integrationEndpointId, actorUserId));

    private static IntegrationEndpointResponse Map(IntegrationEndpointDetailView endpoint) =>
        new(
            endpoint.IntegrationEndpointId,
            endpoint.EndpointCode,
            endpoint.EndpointName,
            endpoint.IntegrationProviderCode,
            endpoint.EnvironmentCode,
            endpoint.DirectionCode,
            endpoint.TransportCode,
            endpoint.HttpMethodCode,
            endpoint.BaseUrl,
            endpoint.RelativePath,
            endpoint.AuthenticationModeCode,
            endpoint.CredentialReference,
            endpoint.TimeoutSeconds,
            endpoint.RetryPolicyCode,
            endpoint.MaxRetryCount,
            endpoint.IsIdempotencyKeyRequired,
            endpoint.StatusCode,
            endpoint.IsActive,
            endpoint.Notes,
            endpoint.SubmittedAtUtc,
            endpoint.SubmittedByUserId,
            endpoint.ApprovedAtUtc,
            endpoint.ApprovedByUserId,
            endpoint.ActivatedAtUtc,
            endpoint.ActivatedByUserId);
}
