using Books.Api.Domain.Orders;
using EventFlow.Commands;

namespace Books.Api.Commands.Orders;

public class CreateOrderCommandHandler
    : CommandHandler<OrderAggregate, OrderId, CreateOrderCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        CreateOrderCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.Create(
            command.CompanyId,
            command.FiscalYearId,
            command.CustomerId,
            command.CustomerName,
            command.CustomerNumber,
            command.OrderNumber,
            command.OrderDate,
            command.ExpectedDeliveryDate,
            command.Currency,
            command.VatCode,
            command.Notes,
            command.Reference,
            command.CreatedBy);

        return Task.CompletedTask;
    }
}

public class AddOrderLineCommandHandler
    : CommandHandler<OrderAggregate, OrderId, AddOrderLineCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        AddOrderLineCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.AddLine(
            command.Description,
            command.Quantity,
            command.UnitPrice,
            command.VatCode,
            command.AccountId,
            command.Unit,
            command.DiscountPercent,
            command.ProductId);

        return Task.CompletedTask;
    }
}

public class UpdateOrderLineCommandHandler
    : CommandHandler<OrderAggregate, OrderId, UpdateOrderLineCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        UpdateOrderLineCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.UpdateLine(
            command.LineNumber,
            command.Description,
            command.Quantity,
            command.UnitPrice,
            command.VatCode,
            command.AccountId,
            command.Unit,
            command.DiscountPercent,
            command.ProductId);

        return Task.CompletedTask;
    }
}

public class RemoveOrderLineCommandHandler
    : CommandHandler<OrderAggregate, OrderId, RemoveOrderLineCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        RemoveOrderLineCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.RemoveLine(command.LineNumber);

        return Task.CompletedTask;
    }
}

public class ConfirmOrderCommandHandler
    : CommandHandler<OrderAggregate, OrderId, ConfirmOrderCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        ConfirmOrderCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.Confirm(command.ConfirmedBy);

        return Task.CompletedTask;
    }
}

public class MarkOrderLinesInvoicedCommandHandler
    : CommandHandler<OrderAggregate, OrderId, MarkOrderLinesInvoicedCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        MarkOrderLinesInvoicedCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.MarkLinesAsInvoiced(
            command.InvoiceId,
            command.InvoiceNumber,
            command.LineNumbers,
            command.InvoicedBy);

        return Task.CompletedTask;
    }
}

public class CancelOrderCommandHandler
    : CommandHandler<OrderAggregate, OrderId, CancelOrderCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        CancelOrderCommand command,
        CancellationToken cancellationToken)
    {
        aggregate.Cancel(command.Reason, command.CancelledBy);

        return Task.CompletedTask;
    }
}
