package de.effigenix.infrastructure.inventory.web.dto;

import de.effigenix.domain.inventory.Stock;
import io.swagger.v3.oas.annotations.media.Schema;

import java.math.BigDecimal;
import java.util.List;

@Schema(requiredProperties = {"id", "articleId", "storageLocationId", "batches", "totalQuantity", "availableQuantity", "reservations"})
public record StockResponse(
        String id,
        String articleId,
        String storageLocationId,
        @Schema(nullable = true) MinimumLevelResponse minimumLevel,
        @Schema(nullable = true) Integer minimumShelfLifeDays,
        List<StockBatchResponse> batches,
        BigDecimal totalQuantity,
        @Schema(nullable = true) String quantityUnit,
        BigDecimal availableQuantity,
        List<ReservationResponse> reservations
) {

    public static StockResponse from(Stock stock) {
        MinimumLevelResponse minimumLevel = null;
        if (stock.minimumLevel() != null) {
            minimumLevel = new MinimumLevelResponse(
                    stock.minimumLevel().quantity().amount(),
                    stock.minimumLevel().quantity().uom().name()
            );
        }

        Integer shelfLifeDays = null;
        if (stock.minimumShelfLife() != null) {
            shelfLifeDays = stock.minimumShelfLife().days();
        }

        List<StockBatchResponse> batchResponses = stock.batches().stream()
                .map(StockBatchResponse::from)
                .toList();

        BigDecimal totalQuantity = stock.batches().stream()
                .map(b -> b.quantity().amount())
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal availableQuantity = stock.availableQuantity();

        String quantityUnit = stock.uniformUnitOfMeasure()
                .map(Enum::name)
                .orElse(null);

        List<ReservationResponse> reservationResponses = stock.reservations().stream()
                .map(ReservationResponse::from)
                .toList();

        return new StockResponse(
                stock.id().value(),
                stock.articleId().value(),
                stock.storageLocationId().value(),
                minimumLevel,
                shelfLifeDays,
                batchResponses,
                totalQuantity,
                quantityUnit,
                availableQuantity,
                reservationResponses
        );
    }
}
