/*
 * 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.user.profile;

import static org.apache.openmeetings.db.entity.user.PrivateMessage.INBOX_FOLDER_ID;
import static org.apache.openmeetings.db.entity.user.PrivateMessage.SENT_FOLDER_ID;
import static org.apache.openmeetings.web.app.Application.getBean;
import static org.apache.openmeetings.web.app.WebSession.getUserId;
import static org.apache.openmeetings.web.util.CalendarWebHelper.getZoneId;
import static org.apache.openmeetings.web.util.RoomTypeDropDown.getRoomTypes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
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.AppointmentDao;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.user.PrivateMessagesDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.MeetingMember;
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.PrivateMessage;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Type;
import org.apache.openmeetings.mail.MailHandler;
import org.apache.openmeetings.util.CalendarHelper;
import org.apache.openmeetings.util.LinkHelper;
import org.apache.openmeetings.web.app.Application;
import org.apache.openmeetings.web.common.OmDateTimePicker;
import org.apache.openmeetings.web.util.CalendarWebHelper;
import org.apache.openmeetings.web.util.ContactsHelper;
import org.apache.openmeetings.web.util.RoomTypeDropDown;
import org.apache.openmeetings.web.util.UserMultiChoice;
import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
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.util.CollectionModel;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZonedDateTime;
import org.threeten.bp.temporal.ChronoUnit;

import com.googlecode.wicket.jquery.core.Options;
import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.WysiwygEditor;
import com.googlecode.wicket.jquery.ui.plugins.wysiwyg.toolbar.DefaultWysiwygToolbar;
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.local.DateTimePicker;
import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;

public class MessageDialog extends AbstractFormDialog<PrivateMessage> {
	private static final long serialVersionUID = 1L;
	private final Form<PrivateMessage> form;
	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
	DialogButton send = new DialogButton("send", Application.getString(218));
	private DialogButton cancel = new DialogButton("cancel", Application.getString(219));
	private final WebMarkupContainer roomParamsBlock = new WebMarkupContainer("roomParamsBlock");
	private final WebMarkupContainer roomParams = new WebMarkupContainer("roomParams");
	private final DateTimePicker start = new OmDateTimePicker("start", Model.of(LocalDateTime.now()));
	private final DateTimePicker end = new OmDateTimePicker("end", Model.of(LocalDateTime.now()));
	private boolean isPrivate = false; 
	private final IModel<Collection<User>> modelTo = new CollectionModel<User>(new ArrayList<User>());

	@Override
	public int getWidth() {
		return 650;
	}
	
	public void open(IPartialPageRequestHandler target, long userId) {
		getModelObject().setTo(getBean(UserDao.class).get(userId));
		open(target);
	}
	
	public MessageDialog reset(boolean isPrivate) {
		//TODO should be 'in sync' with appointment
		LocalDateTime now = ZonedDateTime.now(getZoneId()).toLocalDateTime();
		start.setModelObject(now);
		end.setModelObject(now.plus(1, ChronoUnit.HOURS));
		modelTo.setObject(new ArrayList<User>());
		PrivateMessage p = new PrivateMessage();
		p.setFrom(getBean(UserDao.class).get(getUserId()));
		p.setOwner(p.getFrom());
		p.setIsRead(false);
		p.setFolderId(INBOX_FOLDER_ID);
		Room r = new Room();
		r.setAppointment(true);
		r.setRoomtype(getRoomTypes().get(0));
		p.setRoom(r);
		setModelObject(p);
		roomParams.setVisible(getModelObject().isBookedRoom());
		form.setModelObject(p);
		this.isPrivate = isPrivate;
		return this;
	}
	
	@Override
	protected void onOpen(IPartialPageRequestHandler target) {
		if (getModel().getObject().getTo() != null) {
			modelTo.getObject().add(getModel().getObject().getTo());
		}
		target.add(form);
		super.onOpen(target);
	}
	
	public MessageDialog(String id, CompoundPropertyModel<PrivateMessage> model) {
		super(id, Application.getString(1209), model);
		form = new Form<PrivateMessage>("form", getModel());
		
		form.add(feedback.setOutputMarkupId(true));
		form.add(new UserMultiChoice("to", modelTo).setRequired(true));
		form.add(new TextField<String>("subject"));
		DefaultWysiwygToolbar toolbar = new DefaultWysiwygToolbar("toolbarContainer");
		form.add(toolbar);
		form.add(new WysiwygEditor("message", toolbar));
		form.add(roomParamsBlock.setOutputMarkupId(true));
		final CheckBox bookedRoom = new CheckBox("bookedRoom");
		form.add(bookedRoom.setOutputMarkupId(true).add(new AjaxEventBehavior("click") {
			private static final long serialVersionUID = 1L;
			
			@Override
			protected void onEvent(AjaxRequestTarget target) {
				PrivateMessage p = MessageDialog.this.getModelObject();
				p.setBookedRoom(!p.isBookedRoom());
				roomParams.setVisible(p.isBookedRoom());
				target.add(bookedRoom, roomParamsBlock);
			}
		}));
		roomParamsBlock.add(roomParams);
		roomParams.add(new RoomTypeDropDown("room.roomtype"));
		roomParams.add(start);
		roomParams.add(end);
		add(form.setOutputMarkupId(true));
	}

	@Override
	protected List<DialogButton> getButtons() {
		return Arrays.asList(send, cancel);
	}
	
	@Override
	protected DialogButton getSubmitButton() {
		return send;
	}

	@Override
	public Form<PrivateMessage> getForm() {
		return form;
	}

	@Override
	protected void onError(AjaxRequestTarget target) {
		target.add(feedback);
	}

	@Override
	protected void onSubmit(AjaxRequestTarget target) {
		PrivateMessage p = getModelObject();
		p.setInserted(new Date());
		UserDao userDao = getBean(UserDao.class); 
		User owner = userDao.get(getUserId());
		if (p.isBookedRoom()) {
			Room r = p.getRoom();
			r.setName(p.getSubject());
			r.setComment("");
			r.setNumberOfPartizipants(100L);
			r.setAppointment(true);
			r.setAllowUserQuestions(true);
			r.setAllowFontStyles(true);
			r = getBean(RoomDao.class).update(r, getUserId());
			Appointment a = new Appointment();
			a.setTitle(p.getSubject());
			a.setDescription(p.getMessage());
			a.setRoom(r);
			a.setStart(CalendarWebHelper.getDate(start.getModelObject()));
			a.setEnd(CalendarWebHelper.getDate(end.getModelObject()));
			List<MeetingMember> attendees = new ArrayList<>();
			for (User to : modelTo.getObject()) {
        		MeetingMember mm = new MeetingMember();
        		mm.setUser(to);
        		mm.setDeleted(false);
        		mm.setInserted(a.getInserted());
        		mm.setUpdated(a.getUpdated());
        		mm.setAppointment(a);
        		attendees.add(mm);
			}
			a.setOwner(owner);
			a.setMeetingMembers(attendees);
	        getBean(AppointmentDao.class).update(a, getUserId(), false);
			p.setRoom(r);
		} else {
			p.setRoom(null);
		}
		PrivateMessagesDao msgDao = getBean(PrivateMessagesDao.class);
		for (User to : modelTo.getObject()) {
			if (to.getUser_id() == null) {
				userDao.update(to, getUserId());
			}
			//to send
			p = new PrivateMessage(p);
			p.setTo(to);
			p.setFolderId(SENT_FOLDER_ID);
			msgDao.update(p, getUserId());
			//to inbox
			p = new PrivateMessage(p);
			p.setOwner(to);
			p.setFolderId(INBOX_FOLDER_ID);
			msgDao.update(p, getUserId());
			if (to.getAdresses() != null) {
				String aLinkHTML = 	(isPrivate && to.getType() == Type.user) ? "<br/><br/>" + "<a href='" + ContactsHelper.getLink() + "'>"
							+ Application.getString(1302, to.getLanguage_id()) + "</a><br/>" : "";
				String invitation_link = "";
				if (p.isBookedRoom()) {
					Invitation i = getBean(InvitationManager.class).getInvitation(to, p.getRoom(),
							false, null, Valid.Period, owner, to.getLanguage_id()
							, CalendarHelper.getDate(start.getModelObject(), to.getTimeZoneId())
							, CalendarHelper.getDate(end.getModelObject(), to.getTimeZoneId()), null);
					
					invitation_link = LinkHelper.getInvitationLink(getBean(ConfigurationDao.class).getBaseUrl(), i);

					if (invitation_link == null) {
						invitation_link = "";
					} else {
						invitation_link = "<br/>" //
								+ Application.getString(503, to.getLanguage_id())
								+ "<br/><a href='" + invitation_link
								+ "'>"
								+ Application.getString(504, to.getLanguage_id()) + "</a><br/>";
					}
				}
				
				getBean(MailHandler.class).send(to.getAdresses().getEmail(),
						Application.getString(1301, to.getLanguage_id()) + p.getSubject(),
						(p.getMessage() == null ? "" : p.getMessage().replaceAll("\\<.*?>", "")) + aLinkHTML + invitation_link);
			}
		}
	}
	
	@Override
	protected void onDetach() {
		modelTo.detach();
		super.onDetach();
	}
}
