using CashLineERP.Contracts.Finance;

namespace CashLineERP.Application.Finance;

public sealed class PaymentChannelConfigurationService : IPaymentChannelConfigurationService
{
    private readonly IPaymentChannelConfigurationRepository _repository;

    public PaymentChannelConfigurationService(IPaymentChannelConfigurationRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<PaymentChannelConfigurationResponse> GetPaymentChannels(bool activeOnly = false, string? integrationProviderCode = null, string? channelTypeCode = null, string? usageCode = null) =>
        _repository.GetPaymentChannels(activeOnly, integrationProviderCode, channelTypeCode, usageCode)
            .Select(Map)
            .ToArray();

    public PaymentChannelConfigurationResponse? GetPaymentChannel(long paymentChannelConfigurationId)
    {
        var channel = _repository.GetPaymentChannel(paymentChannelConfigurationId);
        return channel is null ? null : Map(channel);
    }

    public PaymentChannelConfigurationResponse CreatePaymentChannel(CreatePaymentChannelConfigurationRequest request) =>
        Map(_repository.Create(new CreatePaymentChannelConfigurationCommand(
            request.ChannelName,
            request.BranchId,
            request.IntegrationProviderCode,
            request.ChannelTypeCode,
            request.UsageCode,
            request.CurrencyCode,
            request.OutboundIntegrationEndpointId,
            request.InboundIntegrationEndpointId,
            request.SupportsCardTokenReferences,
            request.UsesWalletRuleEngine,
            request.RequiresCustomerReference,
            request.MinimumAmount,
            request.MaximumAmount,
            request.SettlementLeadDays,
            request.Notes)));

    public PaymentChannelConfigurationResponse SubmitPaymentChannel(long paymentChannelConfigurationId, long actorUserId) =>
        Map(_repository.Submit(paymentChannelConfigurationId, actorUserId));

    public PaymentChannelConfigurationResponse ApprovePaymentChannel(long paymentChannelConfigurationId, long actorUserId) =>
        Map(_repository.Approve(paymentChannelConfigurationId, actorUserId));

    public PaymentChannelConfigurationResponse ActivatePaymentChannel(long paymentChannelConfigurationId, long actorUserId) =>
        Map(_repository.Activate(paymentChannelConfigurationId, actorUserId));

    private static PaymentChannelConfigurationResponse Map(PaymentChannelConfigurationDetailView channel) =>
        new(
            channel.PaymentChannelConfigurationId,
            channel.ChannelCode,
            channel.ChannelName,
            channel.BranchId,
            channel.IntegrationProviderCode,
            channel.ChannelTypeCode,
            channel.UsageCode,
            channel.CurrencyCode,
            channel.OutboundIntegrationEndpointId,
            channel.InboundIntegrationEndpointId,
            channel.SupportsCardTokenReferences,
            channel.UsesWalletRuleEngine,
            channel.RequiresCustomerReference,
            channel.MinimumAmount,
            channel.MaximumAmount,
            channel.SettlementLeadDays,
            channel.StatusCode,
            channel.IsActive,
            channel.Notes,
            channel.SubmittedAtUtc,
            channel.SubmittedByUserId,
            channel.ApprovedAtUtc,
            channel.ApprovedByUserId,
            channel.ActivatedAtUtc,
            channel.ActivatedByUserId);
}
