package com.salesmanager.core.business.services.customer;

import java.util.List;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.salesmanager.core.business.exception.ServiceException;
import com.salesmanager.core.business.repositories.customer.CustomerRepository;
import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl;
import com.salesmanager.core.business.services.customer.attribute.CustomerAttributeService;
import com.salesmanager.core.model.common.Address;
import com.salesmanager.core.model.customer.Customer;
import com.salesmanager.core.model.customer.CustomerCriteria;
import com.salesmanager.core.model.customer.CustomerList;
import com.salesmanager.core.model.customer.attribute.CustomerAttribute;
import com.salesmanager.core.model.merchant.MerchantStore;
import com.salesmanager.core.modules.utils.GeoLocation;

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


@Service("customerService")
public class CustomerServiceImpl extends SalesManagerEntityServiceImpl<Long, Customer> implements CustomerService {

	private static final Logger LOGGER = LoggerFactory.getLogger(CustomerServiceImpl.class);
	
	private CustomerRepository customerRepository;
	
	@Inject
	private CustomerAttributeService customerAttributeService;
	
	@Inject
	private GeoLocation geoLocation;

	
	@Inject
	public CustomerServiceImpl(CustomerRepository customerRepository) {
		super(customerRepository);
		this.customerRepository = customerRepository;
	}

	@Override
	public List<Customer> getByName(String firstName) {
		return customerRepository.findByName(firstName);
	}
	
	@Override
	public Customer getById(Long id) {
			return customerRepository.findOne(id);		
	}
	
// public static SingleCache<String, Customer> getByNickCache1 = new SingleCache<>("static-single:7#CustomerServiceImpl.getByNick1");

	@Override
	public Customer getByNick(String nick) {
// return getByNickCache1.computeIfAbsent(nick,  () -> {
		return customerRepository.findByNick(nick);	
// }, 1200000);
	}
	
// public static SingleCache<Parameters, Customer> getByNickCache2 = new SingleCache<>("static-single:7#CustomerServiceImpl.getByNick2");
	@Override
	public Customer getByNick(String nick, int storeId) {
// return getByNickCache2.computeIfAbsent(new Parameters(nick, storeId),  () -> {
		return customerRepository.findByNick(nick, storeId);	
// }, 1200000);
	}
	
	@Override
	public List<Customer> listByStore(MerchantStore store) {
		return customerRepository.findByStore(store.getId());
	}
	
	@Override
	public CustomerList listByStore(MerchantStore store, CustomerCriteria criteria) {
		return customerRepository.listByStore(store,criteria);
	}
	
public static SingleCache<Parameters, Address> getCustomerAddressCache = new SingleCache<>("static-single:17#CustomerServiceImpl.getCustomerAddress");

	@Override
	public Address getCustomerAddress(MerchantStore store, String ipAddress) throws ServiceException {
		
return getCustomerAddressCache.computeIfAbsent(new Parameters(store, ipAddress),  () -> {
		try {
			return geoLocation.getAddress(ipAddress);
		} catch(Exception e) {
			// throw new ServiceException(e);
			return new Address();
		}
}, 1200000);
		
	}

	@Override	
	public void saveOrUpdate(Customer customer) throws ServiceException {

		LOGGER.debug("Creating Customer");
		
		if(customer.getId()!=null && customer.getId()>0) {
			super.update(customer);
		} else {			
		
			super.create(customer);

		}
	}

	public void delete(Customer customer) throws ServiceException {
		customer = getById(customer.getId());
		
		//delete attributes
		List<CustomerAttribute> attributes =customerAttributeService.getByCustomer(customer.getMerchantStore(), customer);
		if(attributes!=null) {
			for(CustomerAttribute attribute : attributes) {
				customerAttributeService.delete(attribute);
			}
		}
		customerRepository.delete(customer);

	}
	

}
