/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.web.room;

import static org.apache.openmeetings.util.LinkHelper.getInvitationLink;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
import static org.apache.openmeetings.web.app.Application.getBean;
import static org.apache.openmeetings.web.app.WebSession.AVAILABLE_TIMEZONES;
import static org.apache.openmeetings.web.app.WebSession.getUserId;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;

import org.apache.openmeetings.data.conference.InvitationManager;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.calendar.IInvitationManager.MessageType;
import org.apache.openmeetings.db.dao.room.InvitationDao;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.user.OrganisationDao;
import org.apache.openmeetings.db.dao.user.OrganisationUserDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.room.Invitation;
import org.apache.openmeetings.db.entity.room.Invitation.Valid;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.user.Organisation;
import org.apache.openmeetings.db.entity.user.Organisation_Users;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Type;
import org.apache.openmeetings.util.crypt.MD5;
import org.apache.openmeetings.util.crypt.ManageCryptStyle;
import org.apache.openmeetings.web.app.Application;
import org.apache.openmeetings.web.app.WebSession;
import org.apache.openmeetings.web.common.LanguageDropDown;
import org.apache.openmeetings.web.util.UserMultiChoice;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.util.CollectionModel;
import org.apache.wicket.util.string.Strings;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.wicketstuff.select2.Response;
import org.wicketstuff.select2.Select2MultiChoice;
import org.wicketstuff.select2.TextChoiceProvider;

import com.googlecode.wicket.jquery.core.Options;
import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
import com.googlecode.wicket.kendo.ui.form.datetime.AjaxDateTimePicker;
import com.googlecode.wicket.kendo.ui.form.datetime.DateTimePicker;
import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;

public class InvitationDialog extends AbstractFormDialog<Invitation> {
	private static final long serialVersionUID = 1L;
	private static final Logger log = Red5LoggerFactory.getLogger(InvitationDialog.class, webAppRootKey);
	private final DialogButton generate = new DialogButton("generate", Application.getString(1526));
	private final DialogButton send = new DialogButton("send", Application.getString(218));
	private final DialogButton cancel = new DialogButton("cancel", Application.getString(219));
	private final InvitationForm form;
	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
	private final long roomId;
	private final IModel<String> subject = Model.of((String)null);
	private final IModel<String> message = Model.of((String)null);
	private final IModel<String> tzId = Model.of((String)null);
	private final IModel<InviteeType> inviteeType = Model.of(InviteeType.user);
	private Long lang;
	private final TextField<String> url = new TextField<String>("url", Model.of((String)null));
	enum InviteeType {
		user
		, group
	}
	private final UserMultiChoice recipients = new UserMultiChoice("recipients", new CollectionModel<User>(new ArrayList<User>()));
	private final Select2MultiChoice<Organisation> groups = new Select2MultiChoice<Organisation>("groups"
			, new CollectionModel<Organisation>(new ArrayList<Organisation>())
			, new TextChoiceProvider<Organisation>() {
				private static final long serialVersionUID = 1L;

				@Override
				public void query(String term, int page, Response<Organisation> response) {
					if (WebSession.getRights().contains(User.Right.Admin)) {
						List<Organisation> groups = getBean(OrganisationDao.class).get(0, Integer.MAX_VALUE);
						for (Organisation g : groups) {
							if (g.getName().toLowerCase().contains(term.toLowerCase())) {
								response.add(g);
							}
						}
					} else {
						User u = getBean(UserDao.class).get(getUserId());
						for (Organisation_Users ou : u.getOrganisation_users()) {
							if (ou.getOrganisation().getName().toLowerCase().contains(term.toLowerCase())) {
								response.add(ou.getOrganisation());
							}
						}
					}
				}

				@Override
				public Collection<Organisation> toChoices(Collection<String> ids) {
					Collection<Organisation> c = new ArrayList<>();
					for (String id : ids) {
						c.add(getBean(OrganisationDao.class).get(Long.valueOf(id)));
					}
					return c;
				}

				@Override
				protected String getDisplayText(Organisation choice) {
					return choice.getName();
				}

				@Override
				protected Object getId(Organisation choice) {
					return choice.getOrganisation_id();
				}
			});

	public InvitationDialog(String id, long roomId) {
		super(id, Application.getString(214), new CompoundPropertyModel<Invitation>(new Invitation()));
		this.roomId = roomId;
		add(form = new InvitationForm("form", getModel()));
	}

	@Override
	public int getWidth() {
		return 500;
	}

	public void updateModel(AjaxRequestTarget target) {
		Invitation i = new Invitation();
		User u = getBean(UserDao.class).get(getUserId());
		i.setInvitedBy(u);
		Room r = getBean(RoomDao.class).get(roomId);
		i.setRoom(r);
		Calendar d = Calendar.getInstance();
		i.setValidFrom(d.getTime());
		d.add(Calendar.DATE, 1);
		i.setValidTo(d.getTime());
		i.setPassword("ASDDF");
		String hashRaw = "HASH" + (System.currentTimeMillis());
		try {
			i.setHash(MD5.do_checksum(hashRaw));
		} catch (NoSuchAlgorithmException e) {
			log.error("Unexpected error while creating invitation", e);
			throw new RuntimeException(e);
		}
		subject.setObject(null);
		message.setObject(null);
		recipients.setModelObject(new ArrayList<User>());
		recipients.setEnabled(true);
		groups.setModelObject(new ArrayList<Organisation>());
		groups.setEnabled(false);
		tzId.setObject(u.getTimeZoneId());
		lang = u.getLanguage_id();
		url.setModelObject(null);
		inviteeType.setObject(InviteeType.user);
		form.setModelObject(i);
		send.setEnabled(false, target);
		generate.setEnabled(false, target);
		target.add(form);
	}

	@Override
	protected Form<?> getForm(DialogButton button) {
		if (button.equals(generate) || button.equals(send)) {
			return form;
		}
		return super.getForm(button);
	}
	
	@Override
	public InvitationForm getForm() {
		return form;
	}

	@Override
	protected DialogButton getSubmitButton() {
		return send;
	}

	@Override
	protected List<DialogButton> getButtons() {
		return Arrays.asList(generate, send, cancel);
	}
	
	@Override
	protected void onError(AjaxRequestTarget target) {
		target.add(feedback);
	}

	@Override
	public void onClick(AjaxRequestTarget target, DialogButton button) {
		//TODO need to be reviewed
		if (button.equals(cancel)) {
			super.onClick(target, button);
		} else if (button.equals(generate)) {
			Invitation i = create(recipients.getModelObject().iterator().next());
			form.setModelObject(i);
			url.setModelObject(getInvitationLink(getBean(ConfigurationDao.class).getBaseUrl(), i));
			target.add(url);
		} else if (button.equals(send)) {
			if (Strings.isEmpty(url.getModelObject())) {
				if (inviteeType.getObject() == InviteeType.user) {
					for (User u : recipients.getModelObject()) {
						Invitation i = create(u);
						try {
							getBean(InvitationManager.class).sendInvitionLink(i, MessageType.Create, subject.getObject(), message.getObject(), false);
						} catch (Exception e) {
							log.error("error while sending invitation by User ", e);
						}
					}
				} else {
					for (Organisation g : groups.getModelObject()) {
						for (Organisation_Users ou : getBean(OrganisationUserDao.class).get(g.getOrganisation_id(), 0, Integer.MAX_VALUE)) {
							Invitation i = create(ou.getUser());
							try {
								getBean(InvitationManager.class).sendInvitionLink(i, MessageType.Create, subject.getObject(), message.getObject(), false);
							} catch (Exception e) {
								log.error("error while sending invitation by Group ", e);
							}
						}
					}
				}
			} else {
				Invitation i = form.getModelObject();
				try {
					getBean(InvitationManager.class).sendInvitionLink(i, MessageType.Create, subject.getObject(), message.getObject(), false);
				} catch (Exception e) {
					log.error("error while sending invitation by URL ", e);
				}
			}
			super.onClick(target, button);
		}
	}
	
	private Invitation create(User u) {
		Invitation i = new Invitation(form.getModelObject());
		i.setId(null);
		i.setUpdated(null);
		i.setUsed(false);
		
		i.setPassword(ManageCryptStyle.getInstanceOfCrypt().createPassPhrase(i.getPassword())); //FIXME should be hidden
		//FIXME another HACK
		Calendar d = Calendar.getInstance();
		d.setTime(i.getValidFrom());
		d.add(Calendar.MINUTE, -5);
		i.setValidFrom(d.getTime());
		
		i.setInvitee(u);
		if (Type.contact == u.getType()) {
			//TODO not sure it is right
			u.setLanguage_id(lang);
		}
		return getBean(InvitationDao.class).update(i);
	}
	
	@Override
	protected void onSubmit(AjaxRequestTarget target) {
		//designed to be empty because of multiple submit buttons
	}
	
	private class InvitationForm extends Form<Invitation> {
		private static final long serialVersionUID = 1L;
		private final PasswordTextField passwd;
		private final DateTimePicker from;
		private final DateTimePicker to;
		private final DropDownChoice<String> timeZoneId;
		
		public InvitationForm(String id, IModel<Invitation> model) {
			super(id, model);
			RadioGroup<InviteeType> rdi = new RadioGroup<>("inviteeType", inviteeType);
			add(rdi.add(new AjaxFormChoiceComponentUpdatingBehavior() {
				private static final long serialVersionUID = 1L;

				@Override
				protected void onUpdate(AjaxRequestTarget target) {
					boolean groupsEnabled = InviteeType.group == inviteeType.getObject();
					updateButtons(target);
					target.add(groups.setEnabled(groupsEnabled), recipients.setEnabled(!groupsEnabled));
				}
			}));
			//TODO list should be updated on open
			rdi.add(recipients.setLabel(Model.of(Application.getString(216))).setRequired(true).add(new AjaxFormComponentUpdatingBehavior("change") {
				private static final long serialVersionUID = 1L;
				
				@Override
				protected void onUpdate(AjaxRequestTarget target) {
					url.setModelObject(null);
					updateButtons(target);
				}
			}).setOutputMarkupId(true));
			rdi.add(groups.setLabel(Model.of(Application.getString(126))).setRequired(true).add(new AjaxFormComponentUpdatingBehavior("change") {
				private static final long serialVersionUID = 1L;
				
				@Override
				protected void onUpdate(AjaxRequestTarget target) {
					url.setModelObject(null);
					updateButtons(target);
				}
			}).setOutputMarkupId(true));
			rdi.add(new Radio<InviteeType>("user", Model.of(InviteeType.user)), new Radio<InviteeType>("group", Model.of(InviteeType.group)));

			rdi.add(new TextField<String>("subject", subject));
			rdi.add(new TextArea<String>("message", message));
			rdi.add(new AjaxCheckBox("passwordProtected") {
				private static final long serialVersionUID = 1L;

				@Override
				protected void onUpdate(AjaxRequestTarget target) {
					InvitationForm.this.getModelObject().setPasswordProtected(getConvertedInput());
					passwd.setEnabled(getConvertedInput());
					target.add(passwd);
				}
			});
			RadioGroup<Valid> valid = new RadioGroup<Valid>("valid");
			valid.add(new AjaxFormChoiceComponentUpdatingBehavior() {
				private static final long serialVersionUID = 1L;

				@Override
				protected void onUpdate(AjaxRequestTarget target) {
					boolean dateEnabled = InvitationForm.this.getModelObject().getValid() == Valid.Period;
					target.add(from.setEnabled(dateEnabled), to.setEnabled(dateEnabled), timeZoneId.setEnabled(dateEnabled));
				}
			});
			rdi.add(valid.add(new Radio<Valid>("one", Model.of(Valid.OneTime))
					, new Radio<Valid>("period", Model.of(Valid.Period))
					, new Radio<Valid>("endless", Model.of(Valid.Endless))));
			rdi.add(passwd = new PasswordTextField("password"));
			Invitation i = getModelObject();
			passwd.setLabel(Model.of(Application.getString(525))).setOutputMarkupId(true).setEnabled(i.isPasswordProtected());
			rdi.add(from = new AjaxDateTimePicker("validFrom", "yyyy/MM/dd", "HH:mm:ss")); //FIXME use user locale
			rdi.add(to = new AjaxDateTimePicker("validTo", "yyyy/MM/dd", "HH:mm:ss")); //FIXME use user locale
			rdi.add(timeZoneId = new DropDownChoice<String>("timeZoneId", tzId, AVAILABLE_TIMEZONES));
			from.setEnabled(i.getValid() == Valid.Period).setOutputMarkupId(true);
			to.setEnabled(i.getValid() == Valid.Period).setOutputMarkupId(true);
			timeZoneId.setEnabled(i.getValid() == Valid.Period).setOutputMarkupId(true)
				.add(new AjaxFormComponentUpdatingBehavior("change") {
					private static final long serialVersionUID = 1L;
	
					@Override
					protected void onUpdate(AjaxRequestTarget target) {
						//no-op added to preserve selection
					}
				});
			rdi.add(new LanguageDropDown("language", new PropertyModel<Long>(InvitationDialog.this, "lang")));
			rdi.add(url.setOutputMarkupId(true));
			add(feedback);
		}
		
		private void updateButtons(AjaxRequestTarget target) {
			if (inviteeType.getObject() == InviteeType.user) {
				Collection<User> to = recipients.getModelObject();
				send.setEnabled(to.size() > 0, target);
				generate.setEnabled(to.size() == 1, target);
			} else {
				Collection<Organisation> to = groups.getModelObject();
				send.setEnabled(to.size() > 0, target);
				generate.setEnabled(false, target);
			}
		}
		
		@Override
		protected void onValidate() {
			if (from.getConvertedInput() != null && to.getConvertedInput() != null && from.getConvertedInput().after(to.getConvertedInput())) {
				error(Application.getString(1592));
			}
		}
	}
	
	@Override
	protected void onDetach() {
		subject.detach();
		message.detach();
		tzId.detach();
		inviteeType.detach();
		super.onDetach();
	}
}
