using CashLineERP.Contracts.Inventory;

namespace CashLineERP.Application.Inventory;

public sealed class InventoryStatusControlService : IInventoryStatusControlService
{
    private readonly IInventoryStatusControlRepository _repository;

    public InventoryStatusControlService(IInventoryStatusControlRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<InventoryStatusControlResponse> GetInventoryStatusControls() =>
        _repository.GetInventoryStatusControls().Select(Map).ToArray();

    public InventoryStatusControlResponse? GetInventoryStatusControl(long inventoryStatusControlId)
    {
        var control = _repository.GetInventoryStatusControl(inventoryStatusControlId);
        return control is null ? null : Map(control);
    }

    public InventoryStatusControlResponse CreateInventoryStatusControl(CreateInventoryStatusControlRequest request) =>
        Map(_repository.Create(new CreateInventoryStatusControlCommand(
            request.BranchId,
            request.WarehouseId,
            request.ControlDate,
            request.ReasonCode,
            request.Notes,
            request.Lines.Select(line => new CreateInventoryStatusControlLineCommand(
                line.ItemId,
                line.WarehouseLocationId,
                line.QuantityAffected,
                line.UnitOfMeasureCode,
                line.UnitCost,
                line.CurrentStockStatus,
                line.TargetStockStatus,
                line.BatchNumber,
                line.SerialNumber,
                line.ExpiryDate,
                line.Notes)).ToArray())));

    public InventoryStatusControlResponse SubmitInventoryStatusControl(long inventoryStatusControlId, long actorUserId) =>
        Map(_repository.Submit(inventoryStatusControlId, actorUserId));

    public InventoryStatusControlResponse ApproveInventoryStatusControl(long inventoryStatusControlId, long actorUserId) =>
        Map(_repository.Approve(inventoryStatusControlId, actorUserId));

    public InventoryStatusControlResponse PostInventoryStatusControl(long inventoryStatusControlId, long actorUserId) =>
        Map(_repository.Post(inventoryStatusControlId, actorUserId));

    private static InventoryStatusControlResponse Map(InventoryStatusControlDetailView control) =>
        new(
            control.InventoryStatusControlId,
            control.ControlNumber,
            control.BranchId,
            control.WarehouseId,
            control.ControlDate,
            control.ReasonCode,
            control.Notes,
            control.StatusCode,
            control.TotalQuantityAffected,
            control.SubmittedAtUtc,
            control.SubmittedByUserId,
            control.ApprovedAtUtc,
            control.ApprovedByUserId,
            control.PostedAtUtc,
            control.PostedByUserId,
            control.Lines.Select(line => new InventoryStatusControlLineResponse(
                line.InventoryStatusControlLineId,
                line.LineNumber,
                line.ItemId,
                line.WarehouseLocationId,
                line.QuantityAffected,
                line.UnitOfMeasureCode,
                line.UnitCost,
                line.CurrentStockStatus,
                line.TargetStockStatus,
                line.BatchNumber,
                line.SerialNumber,
                line.ExpiryDate,
                line.Notes)).ToArray());
}
