package de.effigenix.application.inventory;

import de.effigenix.domain.inventory.Stock;
import de.effigenix.domain.inventory.StockError;
import de.effigenix.domain.inventory.StockRepository;
import de.effigenix.domain.inventory.StorageLocationId;
import de.effigenix.domain.masterdata.article.ArticleId;
import de.effigenix.shared.common.RepositoryError;
import de.effigenix.shared.common.Result;

import java.util.List;

public class ListStocks {

    private final StockRepository stockRepository;

    public ListStocks(StockRepository stockRepository) {
        this.stockRepository = stockRepository;
    }

    public Result<StockError, List<Stock>> execute(String storageLocationId, String articleId) {
        if (storageLocationId != null && articleId != null) {
            return Result.failure(new StockError.InvalidFilterCombination(
                    "Only one filter parameter allowed: storageLocationId or articleId"));
        }

        if (storageLocationId != null) {
            StorageLocationId locId;
            try {
                locId = StorageLocationId.of(storageLocationId);
            } catch (IllegalArgumentException e) {
                return Result.failure(new StockError.InvalidStorageLocationId(e.getMessage()));
            }
            return mapResult(stockRepository.findAllByStorageLocationId(locId));
        }

        if (articleId != null) {
            ArticleId artId;
            try {
                artId = ArticleId.of(articleId);
            } catch (IllegalArgumentException e) {
                return Result.failure(new StockError.InvalidArticleId(e.getMessage()));
            }
            return mapResult(stockRepository.findAllByArticleId(artId));
        }

        return mapResult(stockRepository.findAll());
    }

    private Result<StockError, List<Stock>> mapResult(Result<RepositoryError, List<Stock>> result) {
        return switch (result) {
            case Result.Failure(var err) -> Result.failure(new StockError.RepositoryFailure(err.message()));
            case Result.Success(var stocks) -> Result.success(stocks);
        };
    }
}
