package com.salesmanager.core.business.services.catalog.product.relationship;

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import com.salesmanager.core.business.exception.ServiceException;
import com.salesmanager.core.business.repositories.catalog.product.relationship.ProductRelationshipRepository;
import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl;
import com.salesmanager.core.model.catalog.product.Product;
import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship;
import com.salesmanager.core.model.catalog.product.relationship.ProductRelationshipType;
import com.salesmanager.core.model.merchant.MerchantStore;
import com.salesmanager.core.model.reference.language.Language;

import br.ufrgs.inf.prosoft.cache.SingleCache;
import br.ufrgs.inf.prosoft.cache.Parameters;

@Service("productRelationshipService")
public class ProductRelationshipServiceImpl extends
		SalesManagerEntityServiceImpl<Long, ProductRelationship> implements
		ProductRelationshipService {

	
	private ProductRelationshipRepository productRelationshipRepository;
	
	@Inject
	public ProductRelationshipServiceImpl(
			ProductRelationshipRepository productRelationshipRepository) {
			super(productRelationshipRepository);
			this.productRelationshipRepository = productRelationshipRepository;
	}
	
	@Override
	public void saveOrUpdate(ProductRelationship relationship) throws ServiceException {
		
		if(relationship.getId()!=null && relationship.getId()>0) {
			
			this.update(relationship);
			
		} else {
			this.create(relationship);
		}
		
	}
	
	
	@Override
	public void addGroup(MerchantStore store, String groupName) throws ServiceException {
		ProductRelationship relationship = new ProductRelationship();
		relationship.setCode(groupName);
		relationship.setStore(store);
		relationship.setActive(true);
		this.save(relationship);
	}
	
	@Override
	public List<ProductRelationship> getGroups(MerchantStore store) {
		return productRelationshipRepository.getGroups(store);
	}
	
	@Override
	public void deleteGroup(MerchantStore store, String groupName) throws ServiceException {
		List<ProductRelationship> entities = productRelationshipRepository.getByGroup(store, groupName);
		for(ProductRelationship relation : entities) {
			this.delete(relation);
		}
	}
	
	@Override
	public void deactivateGroup(MerchantStore store, String groupName) throws ServiceException {
		List<ProductRelationship> entities = productRelationshipRepository.getByGroup(store, groupName);
		for(ProductRelationship relation : entities) {
			relation.setActive(false);
			this.saveOrUpdate(relation);
		}
	}
	
	@Override
	public void activateGroup(MerchantStore store, String groupName) throws ServiceException {
		List<ProductRelationship> entities = this.getByGroup(store, groupName);
		for(ProductRelationship relation : entities) {
			relation.setActive(true);
			this.saveOrUpdate(relation);
		}
	}
	
	public void delete(ProductRelationship relationship) throws ServiceException {
		
		//throws detached exception so need to query first
		relationship = this.getById(relationship.getId());
		super.delete(relationship);
		
		
	}
	
	@Override
	public List<ProductRelationship> listByProduct(Product product) throws ServiceException {

		return productRelationshipRepository.listByProducts(product);

	}
	
public static SingleCache<Parameters, List<ProductRelationship>> getByTypeCache1 = new SingleCache<>("ProductRelationshipServiceImpl.getByType1");

	@Override
	public List<ProductRelationship> getByType(MerchantStore store, Product product, ProductRelationshipType type, Language language) throws ServiceException {

return getByTypeCache1.computeIfAbsent(new Parameters(store, product, type, language),  () -> {
		return productRelationshipRepository.getByType(store, type.name(), product, language);
}, 1200000);

	}
	
public static SingleCache<Parameters, List<ProductRelationship>> getByTypeCache2 = new SingleCache<>("ProductRelationshipServiceImpl.getByType2");

	@Override
	public List<ProductRelationship> getByType(MerchantStore store, ProductRelationshipType type, Language language) throws ServiceException {
return getByTypeCache2.computeIfAbsent(new Parameters(store, type, language),  () -> {
		return productRelationshipRepository.getByType(store, type.name(), language);
}, 1200000);
	}
	
public static SingleCache<Parameters, List<ProductRelationship>> getByTypeCache3 = new SingleCache<>("ProductRelationshipServiceImpl.getByType3");
	@Override
	public List<ProductRelationship> getByType(MerchantStore store, ProductRelationshipType type) throws ServiceException {
return getByTypeCache3.computeIfAbsent(new Parameters(store, type),  () -> {

		return productRelationshipRepository.getByType(store, type.name());
}, 1200000);

	}

public static SingleCache<Parameters, List<ProductRelationship>> getByGroupCache1 = new SingleCache<>("ProductRelationshipServiceImpl.getByGroup1");
	
	@Override
	public List<ProductRelationship> getByGroup(MerchantStore store, String groupName) throws ServiceException {
return getByGroupCache1.computeIfAbsent(new Parameters(store, groupName),  () -> {

		return productRelationshipRepository.getByType(store, groupName);
}, 1200000);

	}
	
	public static SingleCache<Parameters, List<ProductRelationship>> getByGroupCache2 = new SingleCache<>("ProductRelationshipServiceImpl.getByGroup2");

	@Override
	public List<ProductRelationship> getByGroup(MerchantStore store, String groupName, Language language) throws ServiceException {
return getByGroupCache2.computeIfAbsent(new Parameters(store, groupName, language),  () -> {

		return productRelationshipRepository.getByType(store, groupName, language);
}, 1200000);

	}

	public static SingleCache<Parameters, List<ProductRelationship>> getByTypeCache4 = new SingleCache<>("ProductRelationshipServiceImpl.getByType4");
	
	@Override
	public List<ProductRelationship> getByType(MerchantStore store, Product product, ProductRelationshipType type) throws ServiceException {
		
return getByTypeCache4.computeIfAbsent(new Parameters(store, product, type),  () -> {

		return productRelationshipRepository.getByType(store, type.name(), product);
				
}, 1200000);
		
	}



}
