using AyCode.Services.Nav.Ekaer.Models;

namespace AyCode.Services.Nav.Ekaer;

/// <inheritdoc cref="IEkaerSubmitService"/>
/// <remarks>
/// A NAV-küldést az <see cref="EkaerManageService"/> végzi (auth + HTTP), a validációt az
/// <see cref="IEkaerTradeCardValidator"/>. Ez az osztály csak a sorrendet (validate → send) köti egységbe.
/// </remarks>
public sealed class EkaerSubmitService : IEkaerSubmitService
{
    private readonly EkaerManageService _manageService;
    private readonly IEkaerTradeCardValidator _validator;

    public EkaerSubmitService(EkaerManageService manageService, IEkaerTradeCardValidator validator)
    {
        _manageService = manageService ?? throw new ArgumentNullException(nameof(manageService));
        _validator = validator ?? throw new ArgumentNullException(nameof(validator));
    }

    public async Task<EkaerSubmitResult> SubmitAsync(IReadOnlyList<TradeCardOperationType> operations, CancellationToken cancellationToken = default)
    {
        ArgumentNullException.ThrowIfNull(operations);

        // 1) Validáció — csak BLOKKOLÓ (error) szintű hiba esetén NEM küldünk; a warning (pl. hiányzó rendszám,
        //    ami a felrakodásig pótolható) nem blokkol. A teljes üzenetlistát visszaadjuk (warningostul).
        var errors = _validator.Validate(operations);
        if (errors.HasErrors())
            return EkaerSubmitResult.Invalid(errors);

        // 2) Request összeállítás. A Header/User példányt itt kell létrehozni (a generált ctor csak a
        //    TradeCardOperations kollekciót inicializálja); a TARTALMUKAT (requestId, timestamp, hash-ek) az
        //    ApplyAuthentication tölti a NavReportServiceBase-ben.
        var request = new ManageTradeCardsRequest
        {
            Header = new BasicHeaderType(),
            User = new UserHeaderType(),
        };
        foreach (var operation in operations)
            request.TradeCardOperations.Add(operation);

        // 3) Küldés. NAV-oldali hibánál NavReportException propagál (a hívó logolja/kezeli).
        var response = await _manageService.ManageAsync(request, cancellationToken).ConfigureAwait(false);
        return EkaerSubmitResult.Sent(response);
    }
}
