using CashLineERP.Contracts.Finance;

namespace CashLineERP.Application.Finance;

public sealed class ForeignExchangeOverrideService : IForeignExchangeOverrideService
{
    private readonly IForeignExchangeOverrideRepository _repository;

    public ForeignExchangeOverrideService(IForeignExchangeOverrideRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<ForeignExchangeOverrideResponse> GetForeignExchangeOverrides(
        string? currencyCode = null,
        string? baseCurrencyCode = null,
        string? statusCode = null,
        DateOnly? effectiveDateFrom = null,
        DateOnly? effectiveDateTo = null) =>
        _repository.GetForeignExchangeOverrides(currencyCode, baseCurrencyCode, statusCode, effectiveDateFrom, effectiveDateTo)
            .Select(Map)
            .ToArray();

    public ForeignExchangeOverrideResponse? GetForeignExchangeOverride(long foreignExchangeOverrideId)
    {
        var overrideEntry = _repository.GetForeignExchangeOverride(foreignExchangeOverrideId);
        return overrideEntry is null ? null : Map(overrideEntry);
    }

    public ForeignExchangeOverrideResponse CreateForeignExchangeOverride(CreateForeignExchangeOverrideRequest request) =>
        Map(_repository.Create(new CreateForeignExchangeOverrideCommand(
            request.EffectiveDate,
            request.BaseCurrencyCode,
            request.CurrencyCode,
            request.OverrideRateToBase,
            request.ReasonCode,
            request.Notes)));

    public ForeignExchangeOverrideResponse SubmitForeignExchangeOverride(long foreignExchangeOverrideId, long actorUserId) =>
        Map(_repository.Submit(foreignExchangeOverrideId, actorUserId));

    public ForeignExchangeOverrideResponse ApproveForeignExchangeOverride(long foreignExchangeOverrideId, long actorUserId) =>
        Map(_repository.Approve(foreignExchangeOverrideId, actorUserId));

    private static ForeignExchangeOverrideResponse Map(ForeignExchangeOverrideDetailView overrideEntry) =>
        new(
            overrideEntry.ForeignExchangeOverrideId,
            overrideEntry.OverrideNumber,
            overrideEntry.EffectiveDate,
            overrideEntry.BaseCurrencyCode,
            overrideEntry.CurrencyCode,
            overrideEntry.OverrideRateToBase,
            overrideEntry.ReasonCode,
            overrideEntry.Notes,
            overrideEntry.StatusCode,
            overrideEntry.SubmittedAtUtc,
            overrideEntry.SubmittedByUserId,
            overrideEntry.ApprovedAtUtc,
            overrideEntry.ApprovedByUserId);
}
