using CashLineERP.Contracts.Sales;

namespace CashLineERP.Application.Sales;

public sealed class SalesReturnService : ISalesReturnService
{
    private readonly ISalesReturnRepository _repository;

    public SalesReturnService(ISalesReturnRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<SalesReturnResponse> GetSalesReturns() =>
        _repository.GetSalesReturns().Select(Map).ToArray();

    public SalesReturnResponse? GetSalesReturn(long salesReturnId)
    {
        var salesReturn = _repository.GetSalesReturn(salesReturnId);
        return salesReturn is null ? null : Map(salesReturn);
    }

    public SalesReturnResponse CreateSalesReturn(CreateSalesReturnRequest request)
    {
        var salesReturn = _repository.Create(new CreateSalesReturnCommand(
            request.BranchId,
            request.CustomerId,
            request.SalesOrderId,
            request.DispatchOrderId,
            request.ReturnDate,
            request.ReturnWarehouseId,
            request.ReasonCode,
            request.Notes,
            request.Lines.Select(line => new CreateSalesReturnLineCommand(
                line.DispatchOrderLineId,
                line.SalesOrderLineId,
                line.ItemId,
                line.QuantityReturned,
                line.WarehouseLocationId,
                line.BatchNumber,
                line.SerialNumber,
                line.Notes)).ToArray()));

        return Map(salesReturn);
    }

    public SalesReturnResponse SubmitSalesReturn(long salesReturnId, long actorUserId) =>
        Map(_repository.Submit(salesReturnId, actorUserId));

    public SalesReturnResponse PostSalesReturn(long salesReturnId, long actorUserId) =>
        Map(_repository.Post(salesReturnId, actorUserId));

    public SalesReturnResponse IssueCreditNote(long salesReturnId, IssueSalesReturnCreditNoteRequest request) =>
        Map(_repository.IssueCreditNote(salesReturnId, request));

    private static SalesReturnResponse Map(SalesReturnDetailView salesReturn) =>
        new(
            salesReturn.SalesReturnId,
            salesReturn.SalesReturnNumber,
            salesReturn.BranchId,
            salesReturn.CustomerId,
            salesReturn.SalesOrderId,
            salesReturn.DispatchOrderId,
            salesReturn.ReturnDate,
            salesReturn.ReturnWarehouseId,
            salesReturn.ReasonCode,
            salesReturn.Notes,
            salesReturn.StatusCode,
            salesReturn.TotalReturnedQuantity,
            salesReturn.CreditNoteInvoiceId,
            salesReturn.CreditNoteIssuedAtUtc,
            salesReturn.Lines.Select(line => new SalesReturnLineResponse(
                line.SalesReturnLineId,
                line.LineNumber,
                line.DispatchOrderLineId,
                line.SalesOrderLineId,
                line.ItemId,
                line.QuantityReturned,
                line.WarehouseLocationId,
                line.BatchNumber,
                line.SerialNumber,
                line.Notes)).ToArray());
}
