using CashLineERP.Contracts.Finance;

namespace CashLineERP.Application.Finance;

public sealed class ForeignExchangeQuoteService : IForeignExchangeQuoteService
{
    private readonly IForeignExchangeQuoteRepository _repository;

    public ForeignExchangeQuoteService(IForeignExchangeQuoteRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<ForeignExchangeQuoteResponse> GetForeignExchangeQuotes(
        string? currencyCode = null,
        string? baseCurrencyCode = null,
        long? integrationEndpointId = null,
        DateOnly? dateFrom = null,
        DateOnly? dateTo = null) =>
        _repository.GetForeignExchangeQuotes(currencyCode, baseCurrencyCode, integrationEndpointId, dateFrom, dateTo)
            .Select(Map)
            .ToArray();

    public ForeignExchangeQuoteResponse? GetLatestForeignExchangeQuote(
        string currencyCode,
        string? baseCurrencyCode = null,
        DateOnly? asOfDate = null,
        long? integrationEndpointId = null)
    {
        var quote = _repository.GetLatestForeignExchangeQuote(currencyCode, baseCurrencyCode, asOfDate, integrationEndpointId);
        return quote is null ? null : Map(quote);
    }

    public IReadOnlyCollection<ForeignExchangeQuoteResponse> IngestQuotes(long actorUserId, IngestForeignExchangeQuotesRequest request) =>
        _repository.IngestQuotes(actorUserId, new IngestForeignExchangeQuotesCommand(
                request.IntegrationEndpointId,
                request.QuoteDate,
                request.BaseCurrencyCode,
                request.SourceBatchReference,
                request.Notes,
                request.Quotes.Select(line => new IngestForeignExchangeQuoteLineCommand(
                    line.CurrencyCode,
                    line.RateToBase,
                    line.ExternalQuoteReference,
                    line.Notes)).ToArray()))
            .Select(Map)
            .ToArray();

    private static ForeignExchangeQuoteResponse Map(ForeignExchangeQuoteDetailView quote) =>
        new(
            quote.ForeignExchangeQuoteId,
            quote.QuoteNumber,
            quote.IntegrationEndpointId,
            quote.IntegrationEndpointCode,
            quote.SourceProviderCode,
            quote.QuoteDate,
            quote.BaseCurrencyCode,
            quote.CurrencyCode,
            quote.RateToBase,
            quote.SourceBatchReference,
            quote.ExternalQuoteReference,
            quote.Notes,
            quote.IngestedAtUtc,
            quote.IngestedByUserId);
}
