using CashLineERP.Contracts.Inventory;

namespace CashLineERP.Application.Inventory;

public sealed class StockCountService : IStockCountService
{
    private readonly IStockCountRepository _repository;

    public StockCountService(IStockCountRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<StockCountResponse> GetStockCounts() =>
        _repository.GetStockCounts().Select(Map).ToArray();

    public StockCountResponse? GetStockCount(long stockCountId)
    {
        var stockCount = _repository.GetStockCount(stockCountId);
        return stockCount is null ? null : Map(stockCount);
    }

    public StockCountResponse CreateStockCount(CreateStockCountRequest request)
    {
        var stockCount = _repository.Create(new CreateStockCountCommand(
            request.BranchId,
            request.WarehouseId,
            request.CountDate,
            request.CountTypeCode,
            request.Notes,
            request.Lines.Select(line => new CreateStockCountLineCommand(
                line.ItemId,
                line.WarehouseLocationId,
                line.BookQuantity,
                line.CountedQuantity,
                line.UnitOfMeasureCode,
                line.UnitCost,
                line.StockStatus,
                line.BatchNumber,
                line.SerialNumber,
                line.Notes)).ToArray()));

        return Map(stockCount);
    }

    public StockCountResponse SubmitStockCount(long stockCountId, long actorUserId) =>
        Map(_repository.Submit(stockCountId, actorUserId));

    public StockCountResponse ApproveStockCount(long stockCountId, long actorUserId) =>
        Map(_repository.Approve(stockCountId, actorUserId));

    public StockCountResponse PostStockCount(long stockCountId, long actorUserId) =>
        Map(_repository.Post(stockCountId, actorUserId));

    private static StockCountResponse Map(StockCountDetailView stockCount) =>
        new(
            stockCount.StockCountId,
            stockCount.CountNumber,
            stockCount.BranchId,
            stockCount.WarehouseId,
            stockCount.CountDate,
            stockCount.CountTypeCode,
            stockCount.Notes,
            stockCount.StatusCode,
            stockCount.TotalVarianceAmount,
            stockCount.SubmittedAtUtc,
            stockCount.SubmittedByUserId,
            stockCount.ApprovedAtUtc,
            stockCount.ApprovedByUserId,
            stockCount.PostedAtUtc,
            stockCount.PostedByUserId,
            stockCount.InventoryAdjustmentId,
            stockCount.GeneralLedgerBatchId,
            stockCount.Lines.Select(line => new StockCountLineResponse(
                line.StockCountLineId,
                line.LineNumber,
                line.ItemId,
                line.WarehouseLocationId,
                line.BookQuantity,
                line.CountedQuantity,
                line.VarianceQuantity,
                line.UnitOfMeasureCode,
                line.UnitCost,
                line.VarianceAmount,
                line.StockStatus,
                line.BatchNumber,
                line.SerialNumber,
                line.Notes)).ToArray());
}
