package de.effigenix.infrastructure.config;

import de.effigenix.application.production.ActivateRecipe;
import de.effigenix.application.production.ArchiveRecipe;
import de.effigenix.application.production.AddProductionStep;
import de.effigenix.application.production.AddRecipeIngredient;
import de.effigenix.application.production.CreateProductionOrder;
import de.effigenix.application.production.ReleaseProductionOrder;
import de.effigenix.application.production.CancelBatch;
import de.effigenix.application.production.CompleteBatch;
import de.effigenix.application.production.CreateRecipe;
import de.effigenix.application.production.FindBatchByNumber;
import de.effigenix.application.production.GetBatch;
import de.effigenix.application.production.ListBatches;
import de.effigenix.application.production.PlanBatch;
import de.effigenix.application.production.RecordConsumption;
import de.effigenix.application.production.StartBatch;
import de.effigenix.application.production.RecipeCycleChecker;
import de.effigenix.application.production.GetRecipe;
import de.effigenix.application.production.ListRecipes;
import de.effigenix.application.production.RemoveProductionStep;
import de.effigenix.application.production.RemoveRecipeIngredient;
import de.effigenix.domain.production.BatchNumberGenerator;
import de.effigenix.domain.production.BatchRepository;
import de.effigenix.domain.production.ProductionOrderRepository;
import de.effigenix.domain.production.RecipeRepository;
import de.effigenix.shared.security.AuthorizationPort;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ProductionUseCaseConfiguration {

    @Bean
    public CreateRecipe createRecipe(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new CreateRecipe(recipeRepository, authorizationPort);
    }

    @Bean
    public RecipeCycleChecker recipeCycleChecker(RecipeRepository recipeRepository) {
        return new RecipeCycleChecker(recipeRepository);
    }

    @Bean
    public AddRecipeIngredient addRecipeIngredient(RecipeRepository recipeRepository, AuthorizationPort authorizationPort,
                                                   RecipeCycleChecker recipeCycleChecker) {
        return new AddRecipeIngredient(recipeRepository, authorizationPort, recipeCycleChecker);
    }

    @Bean
    public RemoveRecipeIngredient removeRecipeIngredient(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new RemoveRecipeIngredient(recipeRepository, authorizationPort);
    }

    @Bean
    public AddProductionStep addProductionStep(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new AddProductionStep(recipeRepository, authorizationPort);
    }

    @Bean
    public RemoveProductionStep removeProductionStep(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new RemoveProductionStep(recipeRepository, authorizationPort);
    }

    @Bean
    public GetRecipe getRecipe(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new GetRecipe(recipeRepository, authorizationPort);
    }

    @Bean
    public ListRecipes listRecipes(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new ListRecipes(recipeRepository, authorizationPort);
    }

    @Bean
    public ActivateRecipe activateRecipe(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new ActivateRecipe(recipeRepository, authorizationPort);
    }

    @Bean
    public ArchiveRecipe archiveRecipe(RecipeRepository recipeRepository, AuthorizationPort authorizationPort) {
        return new ArchiveRecipe(recipeRepository, authorizationPort);
    }

    @Bean
    public PlanBatch planBatch(BatchRepository batchRepository, RecipeRepository recipeRepository,
                               BatchNumberGenerator batchNumberGenerator, AuthorizationPort authorizationPort) {
        return new PlanBatch(batchRepository, recipeRepository, batchNumberGenerator, authorizationPort);
    }

    @Bean
    public GetBatch getBatch(BatchRepository batchRepository, AuthorizationPort authorizationPort) {
        return new GetBatch(batchRepository, authorizationPort);
    }

    @Bean
    public ListBatches listBatches(BatchRepository batchRepository, RecipeRepository recipeRepository,
                                   AuthorizationPort authorizationPort) {
        return new ListBatches(batchRepository, recipeRepository, authorizationPort);
    }

    @Bean
    public FindBatchByNumber findBatchByNumber(BatchRepository batchRepository, AuthorizationPort authorizationPort) {
        return new FindBatchByNumber(batchRepository, authorizationPort);
    }

    @Bean
    public StartBatch startBatch(BatchRepository batchRepository, AuthorizationPort authorizationPort) {
        return new StartBatch(batchRepository, authorizationPort);
    }

    @Bean
    public RecordConsumption recordConsumption(BatchRepository batchRepository, AuthorizationPort authorizationPort) {
        return new RecordConsumption(batchRepository, authorizationPort);
    }

    @Bean
    public CompleteBatch completeBatch(BatchRepository batchRepository, AuthorizationPort authorizationPort) {
        return new CompleteBatch(batchRepository, authorizationPort);
    }

    @Bean
    public CancelBatch cancelBatch(BatchRepository batchRepository, AuthorizationPort authorizationPort) {
        return new CancelBatch(batchRepository, authorizationPort);
    }

    @Bean
    public CreateProductionOrder createProductionOrder(ProductionOrderRepository productionOrderRepository,
                                                        RecipeRepository recipeRepository,
                                                        AuthorizationPort authorizationPort) {
        return new CreateProductionOrder(productionOrderRepository, recipeRepository, authorizationPort);
    }

    @Bean
    public ReleaseProductionOrder releaseProductionOrder(ProductionOrderRepository productionOrderRepository,
                                                          RecipeRepository recipeRepository,
                                                          AuthorizationPort authorizationPort) {
        return new ReleaseProductionOrder(productionOrderRepository, recipeRepository, authorizationPort);
    }
}
