package de.effigenix.infrastructure.config;

import de.effigenix.application.masterdata.article.*;
import de.effigenix.application.masterdata.customer.*;
import de.effigenix.application.masterdata.productcategory.CreateProductCategory;
import de.effigenix.application.masterdata.productcategory.DeleteProductCategory;
import de.effigenix.application.masterdata.productcategory.ListProductCategories;
import de.effigenix.application.masterdata.productcategory.UpdateProductCategory;
import de.effigenix.application.masterdata.supplier.*;
import de.effigenix.domain.masterdata.article.ArticleRepository;
import de.effigenix.domain.masterdata.customer.CustomerRepository;
import de.effigenix.domain.masterdata.productcategory.ProductCategoryRepository;
import de.effigenix.domain.masterdata.supplier.SupplierRepository;
import de.effigenix.shared.persistence.UnitOfWork;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MasterDataUseCaseConfiguration {

    // ==================== Article Use Cases ====================

    @Bean
    public CreateArticle createArticle(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new CreateArticle(articleRepository, unitOfWork);
    }

    @Bean
    public UpdateArticle updateArticle(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new UpdateArticle(articleRepository, unitOfWork);
    }

    @Bean
    public GetArticle getArticle(ArticleRepository articleRepository) {
        return new GetArticle(articleRepository);
    }

    @Bean
    public ListArticles listArticles(ArticleRepository articleRepository) {
        return new ListArticles(articleRepository);
    }

    @Bean
    public ActivateArticle activateArticle(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new ActivateArticle(articleRepository, unitOfWork);
    }

    @Bean
    public DeactivateArticle deactivateArticle(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new DeactivateArticle(articleRepository, unitOfWork);
    }

    @Bean
    public AddSalesUnit addSalesUnit(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new AddSalesUnit(articleRepository, unitOfWork);
    }

    @Bean
    public RemoveSalesUnit removeSalesUnit(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new RemoveSalesUnit(articleRepository, unitOfWork);
    }

    @Bean
    public UpdateSalesUnitPrice updateSalesUnitPrice(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new UpdateSalesUnitPrice(articleRepository, unitOfWork);
    }

    @Bean
    public AssignSupplier assignSupplier(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new AssignSupplier(articleRepository, unitOfWork);
    }

    @Bean
    public RemoveSupplier removeSupplier(ArticleRepository articleRepository, UnitOfWork unitOfWork) {
        return new RemoveSupplier(articleRepository, unitOfWork);
    }

    // ==================== ProductCategory Use Cases ====================

    @Bean
    public CreateProductCategory createProductCategory(ProductCategoryRepository categoryRepository, UnitOfWork unitOfWork) {
        return new CreateProductCategory(categoryRepository, unitOfWork);
    }

    @Bean
    public UpdateProductCategory updateProductCategory(ProductCategoryRepository categoryRepository, UnitOfWork unitOfWork) {
        return new UpdateProductCategory(categoryRepository, unitOfWork);
    }

    @Bean
    public ListProductCategories listProductCategories(ProductCategoryRepository categoryRepository) {
        return new ListProductCategories(categoryRepository);
    }

    @Bean
    public DeleteProductCategory deleteProductCategory(
            ProductCategoryRepository categoryRepository,
            ArticleRepository articleRepository,
            UnitOfWork unitOfWork
    ) {
        return new DeleteProductCategory(categoryRepository, articleRepository, unitOfWork);
    }

    // ==================== Supplier Use Cases ====================

    @Bean
    public CreateSupplier createSupplier(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new CreateSupplier(supplierRepository, unitOfWork);
    }

    @Bean
    public UpdateSupplier updateSupplier(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new UpdateSupplier(supplierRepository, unitOfWork);
    }

    @Bean
    public GetSupplier getSupplier(SupplierRepository supplierRepository) {
        return new GetSupplier(supplierRepository);
    }

    @Bean
    public ListSuppliers listSuppliers(SupplierRepository supplierRepository) {
        return new ListSuppliers(supplierRepository);
    }

    @Bean
    public ActivateSupplier activateSupplier(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new ActivateSupplier(supplierRepository, unitOfWork);
    }

    @Bean
    public DeactivateSupplier deactivateSupplier(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new DeactivateSupplier(supplierRepository, unitOfWork);
    }

    @Bean
    public RateSupplier rateSupplier(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new RateSupplier(supplierRepository, unitOfWork);
    }

    @Bean
    public AddCertificate addCertificate(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new AddCertificate(supplierRepository, unitOfWork);
    }

    @Bean
    public RemoveCertificate removeCertificate(SupplierRepository supplierRepository, UnitOfWork unitOfWork) {
        return new RemoveCertificate(supplierRepository, unitOfWork);
    }

    // ==================== Customer Use Cases ====================

    @Bean
    public CreateCustomer createCustomer(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new CreateCustomer(customerRepository, unitOfWork);
    }

    @Bean
    public UpdateCustomer updateCustomer(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new UpdateCustomer(customerRepository, unitOfWork);
    }

    @Bean
    public GetCustomer getCustomer(CustomerRepository customerRepository) {
        return new GetCustomer(customerRepository);
    }

    @Bean
    public ListCustomers listCustomers(CustomerRepository customerRepository) {
        return new ListCustomers(customerRepository);
    }

    @Bean
    public ActivateCustomer activateCustomer(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new ActivateCustomer(customerRepository, unitOfWork);
    }

    @Bean
    public DeactivateCustomer deactivateCustomer(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new DeactivateCustomer(customerRepository, unitOfWork);
    }

    @Bean
    public AddDeliveryAddress addDeliveryAddress(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new AddDeliveryAddress(customerRepository, unitOfWork);
    }

    @Bean
    public RemoveDeliveryAddress removeDeliveryAddress(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new RemoveDeliveryAddress(customerRepository, unitOfWork);
    }

    @Bean
    public SetFrameContract setFrameContract(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new SetFrameContract(customerRepository, unitOfWork);
    }

    @Bean
    public RemoveFrameContract removeFrameContract(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new RemoveFrameContract(customerRepository, unitOfWork);
    }

    @Bean
    public SetPreferences setPreferences(CustomerRepository customerRepository, UnitOfWork unitOfWork) {
        return new SetPreferences(customerRepository, unitOfWork);
    }
}
