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

import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
import static org.apache.openmeetings.db.util.AuthLevelUtil.hasGroupAdminLevel;
import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_USER_ID;
import static org.apache.openmeetings.util.OpenmeetingsVariables.isMyRoomsEnabled;
import static org.apache.openmeetings.web.app.WebSession.getUserId;
import static org.apache.openmeetings.web.common.confirmation.ConfirmationHelper.newOkCancelConfirm;
import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getParam;
import static org.apache.openmeetings.web.util.OmUrlFragment.CHILD_ID;
import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.basic.IWsClient;
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.Right;
import org.apache.openmeetings.util.OpenmeetingsVariables;
import org.apache.openmeetings.web.app.Application;
import org.apache.openmeetings.web.app.ClientManager;
import org.apache.openmeetings.web.app.WebSession;
import org.apache.openmeetings.web.common.menu.MainMenuItem;
import org.apache.openmeetings.web.common.menu.MenuPanel;
import org.apache.openmeetings.web.common.menu.OmMenuItem;
import org.apache.openmeetings.web.pages.MainPage;
import org.apache.openmeetings.web.user.AboutDialog;
import org.apache.openmeetings.web.user.InviteUserToRoomDialog;
import org.apache.openmeetings.web.user.MessageDialog;
import org.apache.openmeetings.web.user.UserInfoDialog;
import org.apache.openmeetings.web.user.chat.ChatPanel;
import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
import org.apache.openmeetings.web.util.ContactsHelper;
import org.apache.openmeetings.web.util.ExtendedClientProperties;
import org.apache.openmeetings.web.util.OmUrlFragment;
import org.apache.openmeetings.web.util.OmUrlFragment.MenuActions;
import org.apache.openmeetings.web.util.ProfileImageResourceReference;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
import org.apache.wicket.devutils.debugbar.DebugBar;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.head.PriorityHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
import org.apache.wicket.protocol.ws.api.message.AbstractClientMessage;
import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.urlfragment.UrlFragment;

import com.github.openjson.JSONObject;

import de.agilecoders.wicket.core.markup.html.bootstrap.navbar.INavbarComponent;
import de.agilecoders.wicket.core.markup.html.references.BootstrapJavaScriptReference;

public class MainPanel extends Panel {
	private static final long serialVersionUID = 1L;
	private static final Logger log = LoggerFactory.getLogger(MainPanel.class);
	private final WebMarkupContainer empty = new WebMarkupContainer(CHILD_ID);
	private String uid = null;
	private MenuPanel menu;
	private final WebMarkupContainer topControls = new WebMarkupContainer("topControls");
	private final WebMarkupContainer topLinks = new WebMarkupContainer("topLinks");
	private final MarkupContainer contents = new WebMarkupContainer("contents");
	private ChatPanel chat;
	private MessageDialog newMessage;
	private UserInfoDialog userInfo;
	private BasePanel panel;
	private InviteUserToRoomDialog inviteUser;

	@SpringBean
	private ClientManager cm;
	@SpringBean
	private ConfigurationDao cfgDao;
	@SpringBean
	private UserDao userDao;
	@SpringBean
	private RoomDao roomDao;

	public MainPanel(String id) {
		this(id, null);
	}

	public MainPanel(String id, BasePanel panel) {
		super(id);
		this.panel = panel;
		setAuto(true);
		setOutputMarkupId(true);
		setOutputMarkupPlaceholderTag(true);
	}

	@Override
	protected void onInitialize() {
		super.onInitialize();
		add(new OmWebSocketPanel("ws-panel") {
			private static final long serialVersionUID = 1L;

			@Override
			public void renderHead(IHeaderResponse response) {
				super.renderHead(response);
				StringBuilder handlers = new StringBuilder()
						.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_FAILURE, hideBusyIndicator);")
						.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_BEFORE, showBusyIndicator);")
						.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_SUCCESS, hideBusyIndicator);")
						.append("Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_COMPLETE, hideBusyIndicator);")
						.append("Wicket.Event.subscribe(Wicket.Event.Topic.WebSocket.Opened, function() { Wicket.WebSocket.send('socketConnected'); });");
				response.render(OnDomReadyHeaderItem.forScript(handlers));
			}

			@Override
			protected void onConnect(ConnectedMessage msg) {
				ExtendedClientProperties cp = WebSession.get().getExtendedProperties();
				final User u = userDao.get(getUserId());
				final Client client = new Client(
						getSession().getId()
						, msg.getKey().hashCode()
						, u
						, ProfileImageResourceReference.getUrl(getRequestCycle(), u));
				uid = client.getUid();
				cm.add(cp.update(client));
				log.debug("WebSocketBehavior::onConnect [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
			}

			@Override
			protected void onConnect(WebSocketRequestHandler handler) {
				if (panel != null) {
					updateContents(panel, handler);
				}
			}

			@Override
			protected void onMessage(WebSocketRequestHandler handler, JSONObject m) throws IOException {
				BasePanel p = getCurrentPanel();
				if (p != null) {
					p.process(handler, m);
				}
			}

			@Override
			protected void closeHandler(AbstractClientMessage msg) {
				log.debug("WebSocketBehavior::closeHandler uid - {}", uid);
				super.closeHandler(msg);
				if (uid != null) {
					cm.exit(getClient());
					uid = null;
				}
			}

			@Override
			protected IWsClient getWsClient() {
				return getClient();
			}
		});
		menu = new MenuPanel("menu", getMainMenu());
		add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
		add(contents.add(getClient() == null || panel == null ? empty : panel).setOutputMarkupId(true).setMarkupId("contents"));
		topControls.add(menu.setVisible(false), topLinks.setVisible(false).setOutputMarkupPlaceholderTag(true).setMarkupId("topLinks"));
		final AboutDialog about = new AboutDialog("aboutDialog");
		topLinks.add(new AjaxLink<Void>("about") {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClick(AjaxRequestTarget target) {
				about.show(target);
			}
		});
		if (getApplication().getDebugSettings().isDevelopmentUtilitiesEnabled()) {
			add(new DebugBar("dev").setOutputMarkupId(true));
		} else {
			add(new EmptyPanel("dev").setVisible(false));
		}
		add(new OmAjaxClientInfoBehavior());
		add(about, chat = new ChatPanel("chatPanel"));
		add(newMessage = new MessageDialog("newMessageDialog", new CompoundPropertyModel<>(new PrivateMessage())) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSend(IPartialPageRequestHandler handler) {
				BasePanel bp = getCurrentPanel();
				if (bp != null) {
					bp.onNewMessageClose(handler);
				}
			}
		});
		add(userInfo = new UserInfoDialog("userInfoDialog", newMessage));
		add(new AbstractDefaultAjaxBehavior() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void respond(AjaxRequestTarget target) {
				userInfo.show(target, getParam(getComponent(), PARAM_USER_ID).toLong());
			}

			@Override
			public void renderHead(Component component, IHeaderResponse response) {
				super.renderHead(component, response);
				response.render(new PriorityHeaderItem(getNamedFunction("showUserInfo", this, explicit(PARAM_USER_ID))));
			}
		});
		add(new AbstractDefaultAjaxBehavior() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void respond(AjaxRequestTarget target) {
				ContactsHelper.addUserToContactList(getParam(getComponent(), PARAM_USER_ID).toLong());
			}

			@Override
			public void renderHead(Component component, IHeaderResponse response) {
				super.renderHead(component, response);
				response.render(new PriorityHeaderItem(getNamedFunction("addContact", this, explicit(PARAM_USER_ID))));
			}
		});
		add(new AbstractDefaultAjaxBehavior() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void respond(AjaxRequestTarget target) {
				newMessage.reset(true).show(target, getParam(getComponent(), PARAM_USER_ID).toOptionalLong());
			}

			@Override
			public void renderHead(Component component, IHeaderResponse response) {
				super.renderHead(component, response);
				response.render(new PriorityHeaderItem(getNamedFunction("privateMessage", this, explicit(PARAM_USER_ID))));
			}
		});
		add(inviteUser = new InviteUserToRoomDialog("invite-to-room"));
		add(new AbstractDefaultAjaxBehavior() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void respond(AjaxRequestTarget target) {
				inviteUser.show(target, getParam(getComponent(), PARAM_USER_ID).toLong());
			}

			@Override
			public void renderHead(Component component, IHeaderResponse response) {
				super.renderHead(component, response);
				response.render(new PriorityHeaderItem(getNamedFunction("inviteUser", this, explicit(PARAM_USER_ID))));
			}
		});
		AjaxLink<Void> logout = new AjaxLink<>("logout") {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClick(AjaxRequestTarget target) {
				getSession().invalidate();
				setResponsePage(Application.get().getSignInPageClass());
			}

		};
		logout.add(newOkCancelConfirm(this, getString("634")));
		topLinks.add(logout);
	}

	@Override
	public void renderHead(IHeaderResponse response) {
		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(BootstrapJavaScriptReference.instance()))); //this one should go before jquery-ui
		super.renderHead(response);
	}

	private OmMenuItem getSubItem(String lbl, String title, MenuActions action) {
		return new MainMenuItem(lbl, title, action) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClick(AjaxRequestTarget target) {
				onClick(MainPanel.this, target);
			}
		};
	}

	private List<INavbarComponent> getMainMenu() {
		List<INavbarComponent> mmenu = new ArrayList<>();
		createDashboardMenu(mmenu);
		createRoomsMenu(mmenu);
		if (OpenmeetingsVariables.isRecordingsEnabled()) {
			// Recording Menu Points
			mmenu.add(getSubItem("395", "1452", MenuActions.RECORD));
		}
		createSettingsMenu(mmenu);
		Set<Right> r = WebSession.getRights();
		if (r.stream().anyMatch(right -> right.name().contains("ADMIN"))) {
			boolean isAdmin = hasAdminLevel(r);
			boolean isGrpAdmin = hasGroupAdminLevel(r);
			// Administration Menu Points
			List<INavbarComponent> l = new ArrayList<>();
			if (isAdmin || isGrpAdmin) {
				l.add(getSubItem("125", "1454", MenuActions.ADMIN_USER));
			}
			if (isAdmin || r.contains(Right.ADMIN_CONNECTIONS)) {
				l.add(getSubItem("597", "1455", MenuActions.ADMIN_CONNECTION));
			}
			if (isAdmin || isGrpAdmin) {
				l.add(getSubItem("126", "1456", MenuActions.ADMIN_GROUP));
				l.add(getSubItem("186", "1457", MenuActions.ADMIN_ROOM));
			}
			if (isAdmin || r.contains(Right.ADMIN_CONFIG)) {
				l.add(getSubItem("263", "1458", MenuActions.ADMIN_CONFIG));
			}
			if (isAdmin || r.contains(Right.ADMIN_LABEL)) {
				l.add(getSubItem("348", "1459", MenuActions.ADMIN_LABEL));
			}
			if (isAdmin) {
				l.add(getSubItem("1103", "1454", MenuActions.ADMIN_LDAP));
				l.add(getSubItem("1571", "1572", MenuActions.ADMIN_OAUTH));
			}
			if (isAdmin || r.contains(Right.ADMIN_BACKUP)) {
				l.add(getSubItem("367", "1461", MenuActions.ADMIN_BACKUP));
			}
			if (isAdmin) {
				l.add(getSubItem("main.menu.admin.email", "main.menu.admin.email.desc", MenuActions.ADMIN_EMAIL));
			}
			if (isAdmin || isGrpAdmin) {
				l.add(getSubItem("main.menu.admin.extra", "main.menu.admin.extra.desc", MenuActions.ADMIN_EXTRA));
			}
			mmenu.add(new OmMenuItem(getString("6"), l));
		}
		return mmenu;
	}

	private void createDashboardMenu(List<INavbarComponent> mmenu) {
		List<INavbarComponent> l = new ArrayList<>();
		l.add(getSubItem("290", "1450", MenuActions.DASHBOARD_START));
		l.add(getSubItem("291", "1451", MenuActions.DASHBOARD_CALENDAR));
		mmenu.add(new OmMenuItem(getString("124"), l));
	}

	private void createRoomsMenu(List<INavbarComponent> mmenu) {
		List<INavbarComponent> l = new ArrayList<>();
		l.add(getSubItem("777", "1506", MenuActions.ROOMS_PUBLIC));
		l.add(getSubItem("779", "1507", MenuActions.ROOMS_GROUP));
		if (isMyRoomsEnabled()) {
			l.add(getSubItem("781", "1508", MenuActions.ROOMS_MY));
		}
		List<Room> recent = roomDao.getRecent(getUserId());
		if (!recent.isEmpty()) {
			l.add(new OmMenuItem(null, (String)null));
		}
		for (Room r : recent) {
			final Long roomId = r.getId();
			l.add(new OmMenuItem(r.getName(), r.getName()) {
				private static final long serialVersionUID = 1L;

				@Override
				protected void onClick(AjaxRequestTarget target) {
					RoomEnterBehavior.roomEnter((MainPage)getPage(), target, roomId);
				}
			});
		}
		mmenu.add(new OmMenuItem(getString("792"), l));
	}

	private void createSettingsMenu(List<INavbarComponent> mmenu) {
		List<INavbarComponent> l = new ArrayList<>();
		l.add(getSubItem("1188", "1188", MenuActions.PROFILE_MESSAGE));
		l.add(getSubItem("377", "377", MenuActions.PROFILE_EDIT));
		l.add(getSubItem("1172", "1172", MenuActions.PROFILE_SEARCH));
		l.add(getSubItem("profile.invitations", "profile.invitations", MenuActions.PROFILE_INVITATION));
		l.add(getSubItem("1548", "1548", MenuActions.PROFILE_WIDGET));
		mmenu.add(new OmMenuItem(getString("4"), l));
	}

	public void updateContents(OmUrlFragment f, IPartialPageRequestHandler handler) {
		updateContents(f, handler, true);
	}

	private BasePanel getCurrentPanel() {
		Component prev = contents.get(CHILD_ID);
		if (prev instanceof BasePanel) {
			return (BasePanel)prev;
		}
		return null;
	}

	public void updateContents(OmUrlFragment f, IPartialPageRequestHandler handler, boolean updateFragment) {
		BasePanel npanel = getPanel(f.getArea(), f.getType());
		log.debug("updateContents:: npanels IS null ? {}, client IS null ? {}", npanel == null, getClient() == null);
		if (npanel != null) {
			if (getClient() != null) {
				updateContents(npanel, handler);
			} else {
				this.panel = npanel;
			}
			if (updateFragment) {
				UrlFragment uf = new UrlFragment(handler);
				uf.set(f.getArea().name(), f.getType());
			}
		}
	}

	private void updateContents(BasePanel inPanel, IPartialPageRequestHandler handler) {
		if (inPanel != null) {
			BasePanel prev = getCurrentPanel();
			if (prev != null) {
				prev.cleanup(handler);
			}
			handler.add(contents.replace(inPanel));
			handler.appendJavaScript("$('#" + this.getMarkupId() + "').attr('class', 'main " + inPanel.getCssClass() + "');");
			inPanel.onMenuPanelLoad(handler);
		}
	}

	public MenuPanel getMenu() {
		return menu;
	}

	public WebMarkupContainer getTopLinks() {
		return topLinks;
	}

	public WebMarkupContainer getTopControls() {
		return topControls;
	}

	public ChatPanel getChat() {
		return chat;
	}

	public MessageDialog getMessageDialog() {
		return newMessage;
	}

	public String getUid() {
		return uid;
	}

	public Client getClient() {
		return cm.get(uid);
	}
}
