using CashLineERP.Contracts.Finance;

namespace CashLineERP.Application.Finance;

public sealed class TreasuryTransferService : ITreasuryTransferService
{
    private readonly ITreasuryTransferRepository _repository;

    public TreasuryTransferService(ITreasuryTransferRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<TreasuryTransferResponse> GetTreasuryTransfers() =>
        _repository.GetTreasuryTransfers().Select(Map).ToArray();

    public TreasuryTransferResponse? GetTreasuryTransfer(long treasuryTransferId)
    {
        var transfer = _repository.GetTreasuryTransfer(treasuryTransferId);
        return transfer is null ? null : Map(transfer);
    }

    public TreasuryTransferResponse CreateTreasuryTransfer(CreateTreasuryTransferRequest request) =>
        Map(_repository.Create(new CreateTreasuryTransferCommand(
            request.FromCashAccountId,
            request.ToCashAccountId,
            request.TransferDate,
            request.CurrencyCode,
            request.AmountAmount,
            request.ReferenceNumber,
            request.Notes)));

    public TreasuryTransferResponse SubmitTreasuryTransfer(long treasuryTransferId, long actorUserId) =>
        Map(_repository.Submit(treasuryTransferId, actorUserId));

    public TreasuryTransferResponse ApproveTreasuryTransfer(long treasuryTransferId, long actorUserId) =>
        Map(_repository.Approve(treasuryTransferId, actorUserId));

    public TreasuryTransferResponse PostTreasuryTransfer(long treasuryTransferId, long actorUserId) =>
        Map(_repository.Post(treasuryTransferId, actorUserId));

    private static TreasuryTransferResponse Map(TreasuryTransferDetailView transfer) =>
        new(
            transfer.TreasuryTransferId,
            transfer.TransferNumber,
            transfer.FromCashAccountId,
            transfer.FromCashAccountCode,
            transfer.ToCashAccountId,
            transfer.ToCashAccountCode,
            transfer.TransferDate,
            transfer.CurrencyCode,
            transfer.AmountAmount,
            transfer.BaseCurrencyCode,
            transfer.FxRateToBase,
            transfer.BaseAmount,
            transfer.ReferenceNumber,
            transfer.Notes,
            transfer.StatusCode,
            transfer.SubmittedAtUtc,
            transfer.SubmittedByUserId,
            transfer.ApprovedAtUtc,
            transfer.ApprovedByUserId,
            transfer.PostedAtUtc,
            transfer.PostedByUserId,
            transfer.GeneralLedgerBatchId);
}
