package de.effigenix.infrastructure.config;

import de.effigenix.application.inventory.GetStockMovement;
import de.effigenix.application.inventory.ListStockMovements;
import de.effigenix.application.inventory.RecordStockMovement;
import de.effigenix.application.inventory.ActivateStorageLocation;
import de.effigenix.application.inventory.AddStockBatch;
import de.effigenix.application.inventory.BlockStockBatch;
import de.effigenix.application.inventory.CheckStockExpiry;
import de.effigenix.application.inventory.CreateStock;
import de.effigenix.application.inventory.GetStock;
import de.effigenix.application.inventory.UpdateStock;
import de.effigenix.application.inventory.ListStocks;
import de.effigenix.application.inventory.ListStocksBelowMinimum;
import de.effigenix.application.inventory.RemoveStockBatch;
import de.effigenix.application.inventory.ReleaseReservation;
import de.effigenix.application.inventory.ReserveStock;
import de.effigenix.application.inventory.UnblockStockBatch;
import de.effigenix.application.inventory.CreateStorageLocation;
import de.effigenix.application.inventory.DeactivateStorageLocation;
import de.effigenix.application.inventory.GetStorageLocation;
import de.effigenix.application.inventory.ListStorageLocations;
import de.effigenix.application.inventory.UpdateStorageLocation;
import de.effigenix.application.usermanagement.AuditLogger;
import de.effigenix.domain.inventory.StockMovementRepository;
import de.effigenix.domain.inventory.StockRepository;
import de.effigenix.domain.inventory.StorageLocationRepository;
import de.effigenix.shared.security.AuthorizationPort;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class InventoryUseCaseConfiguration {

    // ==================== StorageLocation Use Cases ====================

    @Bean
    public CreateStorageLocation createStorageLocation(StorageLocationRepository storageLocationRepository) {
        return new CreateStorageLocation(storageLocationRepository);
    }

    @Bean
    public UpdateStorageLocation updateStorageLocation(StorageLocationRepository storageLocationRepository) {
        return new UpdateStorageLocation(storageLocationRepository);
    }

    @Bean
    public DeactivateStorageLocation deactivateStorageLocation(StorageLocationRepository storageLocationRepository, StockRepository stockRepository) {
        return new DeactivateStorageLocation(storageLocationRepository, stockRepository);
    }

    @Bean
    public ActivateStorageLocation activateStorageLocation(StorageLocationRepository storageLocationRepository) {
        return new ActivateStorageLocation(storageLocationRepository);
    }

    @Bean
    public GetStorageLocation getStorageLocation(StorageLocationRepository storageLocationRepository, AuthorizationPort authorizationPort) {
        return new GetStorageLocation(storageLocationRepository, authorizationPort);
    }

    @Bean
    public ListStorageLocations listStorageLocations(StorageLocationRepository storageLocationRepository) {
        return new ListStorageLocations(storageLocationRepository);
    }

    // ==================== Stock Use Cases ====================

    @Bean
    public CreateStock createStock(StockRepository stockRepository) {
        return new CreateStock(stockRepository);
    }

    @Bean
    public UpdateStock updateStock(StockRepository stockRepository) {
        return new UpdateStock(stockRepository);
    }

    @Bean
    public GetStock getStock(StockRepository stockRepository) {
        return new GetStock(stockRepository);
    }

    @Bean
    public ListStocks listStocks(StockRepository stockRepository) {
        return new ListStocks(stockRepository);
    }

    @Bean
    public AddStockBatch addStockBatch(StockRepository stockRepository) {
        return new AddStockBatch(stockRepository);
    }

    @Bean
    public RemoveStockBatch removeStockBatch(StockRepository stockRepository) {
        return new RemoveStockBatch(stockRepository);
    }

    @Bean
    public BlockStockBatch blockStockBatch(StockRepository stockRepository, AuditLogger auditLogger) {
        return new BlockStockBatch(stockRepository, auditLogger);
    }

    @Bean
    public UnblockStockBatch unblockStockBatch(StockRepository stockRepository, AuditLogger auditLogger) {
        return new UnblockStockBatch(stockRepository, auditLogger);
    }

    @Bean
    public ReserveStock reserveStock(StockRepository stockRepository) {
        return new ReserveStock(stockRepository);
    }

    @Bean
    public ReleaseReservation releaseReservation(StockRepository stockRepository) {
        return new ReleaseReservation(stockRepository);
    }

    @Bean
    public CheckStockExpiry checkStockExpiry(StockRepository stockRepository) {
        return new CheckStockExpiry(stockRepository);
    }

    @Bean
    public ListStocksBelowMinimum listStocksBelowMinimum(StockRepository stockRepository, AuthorizationPort authorizationPort) {
        return new ListStocksBelowMinimum(stockRepository, authorizationPort);
    }

    // ==================== StockMovement Use Cases ====================

    @Bean
    public RecordStockMovement recordStockMovement(StockMovementRepository stockMovementRepository, AuthorizationPort authorizationPort) {
        return new RecordStockMovement(stockMovementRepository, authorizationPort);
    }

    @Bean
    public GetStockMovement getStockMovement(StockMovementRepository stockMovementRepository, AuthorizationPort authorizationPort) {
        return new GetStockMovement(stockMovementRepository, authorizationPort);
    }

    @Bean
    public ListStockMovements listStockMovements(StockMovementRepository stockMovementRepository, AuthorizationPort authorizationPort) {
        return new ListStockMovements(stockMovementRepository, authorizationPort);
    }
}
