package com.ferienclub.admin.actions;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.mule.extras.client.MuleClient;
import org.mule.umo.UMOException;
import org.mule.umo.UMOMessage;

import com.ferienclub.admin.forms.UserForm;
import com.ferienclub.admin.valueobjs.UserContainer;
import com.ferienclub.custadmin.beans.Address;
import com.ferienclub.custadmin.beans.User;
import com.ferienclub.vacancymgm.beans.Booking;

public class CustomerAdminAction extends Action {

	Logger log = Logger.getLogger(CustomerAdminAction.class);
	
	public ActionForward perform(ActionMapping mapping,
			 ActionForm form,
			 HttpServletRequest request,
			 HttpServletResponse response){
		log.info(this.getClass() + " : Returning Forward \"success\"");
		
		String mode = request.getParameter("mode");
		ActionErrors errors = new ActionErrors();
		
		UserForm uf = (UserForm)form;
		
		if (mode.equals("init"))
		{
			// Get all users
			try {
				MuleClient client = new MuleClient();
				UMOMessage result = client.send("axis:http://localhost:8081/axis/services/UserManagementPM?method=getUsers","",null);
				User[] users = (User[])result.getPayload();
				log.info(this.getClass() + " : Got " + users.length + " users from MULE");
				
			// Get all bookings
				result = client.send("axis:http://localhost:8081/axis/services/GetBookingsPM?method=getBookings","",null);
				Booking[] bookings = (Booking[])result.getPayload();
				log.info("Got " + bookings.length + " bookings from MULE");
				
		    // cache all bookings
				Map bCache = new HashMap();
				for (int i = 0; i < bookings.length; i++)
				{
					Booking b = bookings[i];
					bCache.put(b.getBookingUser().getUserId(),b);
				}
				log.info("Cached all bookings");
				
				Date d = new Date();
				long now = d.getTime();
				long tolerance = 86400000;
				Map userCache = new HashMap();
				
				for (int i = 0; i < users.length; i++)
				{
					User u = users[i];
					Booking b = (Booking)bCache.get(u.getUserId());
					if (b == null)
					{ // User has no booking 
						userCache.put(u,null);
					} else {
						log.info("User: " + u.getFirstName() + " " + u.getName() + " made a booking.");
						long time = b.getFromDate().getTime();
						log.info("Fromdate in ms: " + time);
						long timeTo = b.getToDate().getTime();
						log.info("ToDate in ms:   " + timeTo);
						
						if ((now >= (time - tolerance)) && (now <= (timeTo + tolerance)))
						{
							// User is in the time interval.
							// Now determine wheter he is able to check in or out
							if (b.getStatus().equals("OPEN")){
								log.info("User " + u.getFirstName() + " " + u.getName() + " is able to check in.");
								userCache.put(u,new Boolean(true));
							}
							
							if (b.getStatus().equals("ACTIVE")){
								log.info("User " + u.getFirstName() + " " + u.getName() + " is able to check out.");
								userCache.put(u,new Boolean(false));
							}
							
							if (!(b.getStatus().equals("ACTIVE")) && !(b.getStatus().equals("OPEN"))){
								userCache.put(u,null);
							}
						}
					}
						
				}
				
				// Now userCache is filled
				log.info(this.getClass() + " : filled the userTableDataModel");
				
				UserContainer cont = new UserContainer();
				cont.setUsers(userCache);
				request.getSession().setAttribute("userTableDataModel", cont);
			} catch (UMOException e) {
				errors.add("technicalError",new ActionError("technical.error.mule"));
				saveErrors(request,errors);
				return (new ActionForward(mapping.getInput()));
			}
		}	

		if (mode.equals("userDetail"))
		{
			log.info(this.getClass() + " : mode == userDetail");
			String userId = uf.getUserId();
			UserContainer cont = (UserContainer)request.getSession().getAttribute("userTableDataModel");
			User detailUser = null;
			for (Iterator itor = cont.getUsers().keySet().iterator(); itor.hasNext();)
			{
				User cu = (User)itor.next();
				if (cu.getUserId().equals(userId))
					detailUser = cu;
			}
			request.setAttribute("detailUser",detailUser);
			if (uf.getUserId() != null && uf.getUserId().equals(""))
			{
				errors.add("error",new ActionError("no.user.selected"));
				saveErrors(request,errors);
				return (new ActionForward(mapping.getInput()));
			}
			return mapping.findForward("userDetail");
		}
		
		if (mode.equals("createUser"))
		{
			log.info(this.getClass() + " : mode == createUser");
			User u = new User();
			Address a = new Address();
			a.setCountry(uf.getCountry());
			a.setEmail(uf.getEmail());
			a.setPhone(uf.getPhone());
			a.setProvince(uf.getProvince());
			a.setStreet(uf.getStreet());
			a.setZipCode(uf.getZipcode());
			u.setFirstName(uf.getFirstName());
			u.setName(uf.getName());
			u.setPassword(uf.getPassword());
			u.setAddress(a);
			try {
				MuleClient client = new MuleClient();
				UMOMessage result = client.send("axis:http://localhost:8081/axis/services/UserManagementPM?method=enterNewUser",u,null);
				int rv = ((Integer)result.getPayload()).intValue();
				if (rv < 0){
					errors.add("error",new ActionError("could.not.create.user"));
					saveErrors(request,errors);
					return (new ActionForward(mapping.getInput()));	
				}
			} catch (UMOException e) {
				errors.add("technicalError",new ActionError("technical.error.mule"));
				saveErrors(request,errors);
				return (new ActionForward(mapping.getInput()));
			}
			return mapping.findForward("success");
		}
		
		if (mode.equals("deleteUser"))
		{
			log.info(this.getClass() + " : mode == deleteUser");
			errors.add("error",new ActionError("not.yet.implemented"));
			saveErrors(request,errors);
			return (new ActionForward(mapping.getInput()));	
		}
		
		if (mode.equals("checkOut"))
		{
			log.info(this.getClass() + " : mode == checkOut");
			try {
				MuleClient client = new MuleClient();
				User u = new User();
				u.setUserId(uf.getUserId());
				UMOMessage result = client.send("axis:http://localhost:8081/axis/services/UserManagementPM?method=checkOut",u,null);
				int rv = ((Integer)result.getPayload()).intValue();
				if (rv < 0){
					errors.add("error",new ActionError("could.not.checkout.user"));
					saveErrors(request,errors);
					return (new ActionForward(mapping.getInput()));	
				}
			} catch (UMOException e) {
				errors.add("technicalError",new ActionError("technical.error.mule"));
				saveErrors(request,errors);
				return (new ActionForward(mapping.getInput()));
			}
		}
		
		if (mode.equals("checkIn"))
		{
			log.info(this.getClass() + " : mode == checkIn");
			try {
				MuleClient client = new MuleClient();
				User u = new User();
				u.setUserId(uf.getUserId());
				UMOMessage result = client.send("axis:http://localhost:8081/axis/services/UserManagementPM?method=checkIn",u,null);
				int rv = ((Integer)result.getPayload()).intValue();
				if (rv < 0){
					errors.add("error",new ActionError("could.not.checkin.user"));
					saveErrors(request,errors);
					return (new ActionForward(mapping.getInput()));	
				}
			} catch (UMOException e) {
				errors.add("technicalError",new ActionError("technical.error.mule"));
				saveErrors(request,errors);
				return (new ActionForward(mapping.getInput()));
			}
		}
		
		log.info(this.getClass() + " : Returning forward \"success\"");	
		return mapping.findForward("success");
	}
	
}
