package io.core9.commerce.checkout;

import io.core9.commerce.CommerceDataHandlerHelper;
import io.core9.plugin.database.repository.CrudRepository;
import io.core9.plugin.database.repository.NoCollectionNamePresentException;
import io.core9.plugin.database.repository.RepositoryFactory;
import io.core9.plugin.server.request.Request;
import io.core9.plugin.widgets.datahandler.DataHandler;
import io.core9.plugin.widgets.datahandler.DataHandlerDefaultConfig;
import io.core9.plugin.widgets.datahandler.DataHandlerFactoryConfig;
import io.core9.plugin.widgets.widget.Widget;
import io.core9.plugin.widgets.widget.WidgetFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.xeoh.plugins.base.annotations.PluginImplementation;
import net.xeoh.plugins.base.annotations.events.PluginLoaded;
import net.xeoh.plugins.base.annotations.injections.InjectPlugin;

@PluginImplementation
public class PaymentDataHandlerImpl<T extends DataHandlerDefaultConfig> implements PaymentDataHandler<T> {
	
	@InjectPlugin
	private CommerceDataHandlerHelper helper;
	
	@InjectPlugin
	private WidgetFactory widgets;

	private CrudRepository<PaymentMethod> methods;
	
	@PluginLoaded
	public void onRepositoryFactory(RepositoryFactory factory) throws NoCollectionNamePresentException {
		methods = factory.getRepository(PaymentMethod.class);
	}
	
	@Override
	public String getName() {
		return "Commerce-Payment";
	}

	@Override
	public Class<? extends DataHandlerFactoryConfig> getConfigClass() {
		return DataHandlerDefaultConfig.class;
	}

	@Override
	public DataHandler<T> createDataHandler(DataHandlerFactoryConfig options) {
		return new DataHandler<T>() {

			@Override
			public Map<String, Object> handle(Request req) {
				Order order = helper.getOrder(req);
				DataHandler<?> handler = getPaymentDataHandler(req, order);
				Map<String, Object> result = new HashMap<String, Object>(2);
				result.put("payment", order.getPaymentmethod());
				if(handler != null) {
					Map<String,Object> paymentData = handler.handle(req);
					order.setPaymentData(paymentData);
					helper.saveOrder(req, order);
					result.put("paymentData", handler.handle(req));
				} else {
					result.put("paymentData", new HashMap<String, Object>(0));
				}
				return result;
			}

			@SuppressWarnings("unchecked")
			@Override
			public T getOptions() {
				return (T) options;
			}
		};
	}
	
	private DataHandler<?> getPaymentDataHandler(Request req, Order order) {
		Map<String, Object> query = new HashMap<String, Object>();
		query.put("name", order.getPaymentmethod());
		List<PaymentMethod> foundMethods = methods.query(req.getVirtualHost(), query);
		if(foundMethods.size() == 1) {
			Widget widget = widgets.getRegistry(req.getVirtualHost()).get(foundMethods.get(0).getWidget());
			if(widget == null) {
				return null;
			}
			return widget.getDataHandler();
		} else {
			return null;
		}
	}

}

@@ -137,24 +137,78 @@
 Repository;%0A
+import io.core9.plugin.database.repository.DataUtils;%0A
 import io.co
@@ -330,24 +330,67 @@
 oryFactory;%0A
+import io.core9.plugin.server.VirtualHost;%0A
 import io.co
@@ -1839,98 +1839,139 @@
 %09%09%09%09
-Order order = helper.getOrder(req);%0A%09%09%09%09DataHandler%3C?%3E handler = getPaymentDataHandler(req
+VirtualHost vhost = req.getVirtualHost();%0A%09%09%09%09Order order = helper.getOrder(req);%0A%09%09%09%09PaymentMethod method = getPaymentMethod(vhost
 , or
@@ -1972,24 +1972,29 @@
 st, order);%0A
+%09%09%09%09%0A
 %09%09%09%09Map%3CStri
@@ -2076,32 +2076,98 @@
 t%22, 
-order.getPayment
+DataUtils.toMap(method));%0A%09%09%09%09DataHandler%3C?%3E handler = getPaymentDataHandler(vhost, 
 method
-()
 );%0A%09
@@ -2356,35 +2356,27 @@
 tData%22, 
-handler.handle(req)
+paymentData
 );%0A%09%09%09%09%7D
@@ -2637,27 +2637,311 @@
 Handler(
-Request req
+VirtualHost vhost, PaymentMethod method) %7B%0A%09%09if(method == null) %7B%0A%09%09%09return null;%0A%09%09%7D%0A%09%09Widget widget = widgets.getRegistry(vhost).get(method.getWidget());%0A%09%09if(widget == null) %7B%0A%09%09%09return null;%0A%09%09%7D%0A%09%09return widget.getDataHandler();%0A%09%7D%0A%09%0A%09private PaymentMethod getPaymentMethod(VirtualHost vhost
 , Order 
@@ -3108,36 +3108,21 @@
 s.query(
-req.getVirtualH
+vh
 ost
-()
 , query)
@@ -3163,197 +3163,40 @@
 %0A%09%09%09
-Widget widget = widgets.getRegistry(req.getVirtualHost()).get(foundMethods.get(0).getWidget());%0A%09%09%09if(widget == null) %7B%0A%09%09%09%09return null;%0A%09%09%09%7D%0A%09%09%09return widget.getDataHandler();%0A%09%09%7D else %7B%0A%09
+return foundMethods.get(0);%0A%09%09%7D%0A
 %09%09re
@@ -3206,18 +3206,14 @@
 n null;%0A
-%09%09%7D%0A
 %09%7D%0A%0A%7D%0A

handle payment