/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License 2.0        
 * which accompanies this distribution, and is available at                  
 * https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 * SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.authentication.ui.login;

import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.osbp.authentication.account.dtos.UserAccountDto;
import org.eclipse.osbp.authentication.providerimpl.UserProtocol;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

@SuppressWarnings({ "serial", "restriction" })
public class NewPasswordDialog extends Window {

	private IDSLMetadataService dslMetadataService;

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory.getLogger(NewPasswordDialog.class);

	private Panel newPasswordPanel;
	private VerticalLayout layout;

	public NewPasswordDialog() {
		super();
		setDraggable(false);
		setResizable(false);
		setClosable(false);
		setModal(true);
		layout = new VerticalLayout();
		layout.setMargin(true);
		setContent(layout);

		newPasswordPanel = new Panel();
		newPasswordPanel.setWidth("430px");
		newPasswordPanel.setId("newPasswordPanelArea");
		newPasswordPanel.addStyleName("newPasswordPanelArea os-login");
	}

	public NewPasswordDialog init(IEventBroker eventBroker, IDSLMetadataService dslMetadataService, UserAccountDto userAccountDto) {
		LOGGER.debug("NewPasswordDialog init");
		setLocale(UI.getCurrent().getLocale());
		this.dslMetadataService = dslMetadataService;

		layout.addComponent(newPasswordPanel);
		layout.setComponentAlignment(newPasswordPanel, Alignment.MIDDLE_CENTER);
		layout.setPrimaryStyleName("osbp");
		newPasswordPanel.setCaption(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password_caption"));
		newPasswordPanel.setDescription(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password_caption_tip"));

		// VerticalLayout NEWPASSWORDFORM
		VerticalLayout newPasswordForm = new VerticalLayout();
		newPasswordForm.setSizeFull();
		newPasswordForm.setMargin(true);
		newPasswordForm.setId("osbpnewPasswordForm");
		newPasswordForm.addStyleName("loginPanelArea");
		newPasswordPanel.setContent(newPasswordForm);

		// VerticalLayout FULLAREA
		VerticalLayout fullArea = new VerticalLayout();
		fullArea.setSizeFull();
		fullArea.setId("newPasswordFullArea");
		newPasswordForm.addComponent(fullArea);

		// HorizontalLayout USERAREA
		HorizontalLayout userArea = new HorizontalLayout();
		userArea.setId("newPasswordUserArea");
		userArea.setSizeFull();
		userArea.setMargin(true);
		fullArea.addComponent(userArea);

		// VerticalLayout TEXTAREA
		VerticalLayout textArea = new VerticalLayout();
		textArea.setSizeFull();
		userArea.addComponent(textArea);
		userArea.setExpandRatio(textArea, 0.85f);
		userArea.setId("newPasswordTextArea");

		// VerticalLayout BUTTONAREA
		VerticalLayout buttonArea = new VerticalLayout();
		buttonArea.setId("newPasswordButtonArea");
		buttonArea.setSizeFull();
		buttonArea.setMargin(true);
		fullArea.addComponent(buttonArea);

		// HorizontalLayout newPasswordAREA
		HorizontalLayout newPasswordArea = new HorizontalLayout();
		newPasswordArea.setId("newPasswordnewPasswordArea");
		newPasswordArea.setSizeFull();
		buttonArea.addComponent(newPasswordArea);

		// VerticalLayout COPYRIGHTAREA
		VerticalLayout copyrightArea = new VerticalLayout();
		copyrightArea.setId("loginCopyrightArea");
		copyrightArea.addStyleName("loginCopyrightArea");
		copyrightArea.setSizeFull();
		newPasswordForm.addComponent(copyrightArea);
		// Label COPYRIGHTFIELD
		Label copyrightField = new Label();
		copyrightField.setSizeFull();
		copyrightArea.addComponent(copyrightField);
		copyrightArea.setComponentAlignment(copyrightField, Alignment.MIDDLE_CENTER);
		copyrightField.setValue(dslMetadataService.translate(getLocale().toLanguageTag(), "copyright"));

		// Text field OLDPASSWORD
		PasswordField oldPasswordField = new PasswordField();
		oldPasswordField.setSizeFull();
		textArea.addComponent(oldPasswordField);
		oldPasswordField.setCaption(dslMetadataService.translate(getLocale().toLanguageTag(), "old_password"));
		oldPasswordField.setDescription(dslMetadataService.translate(getLocale().toLanguageTag(), "old_password_tip"));
		oldPasswordField.focus();

		// Password field PASSWORD
		PasswordField newPasswordField = new PasswordField();
		newPasswordField.setSizeFull();
		textArea.addComponent(newPasswordField);
		newPasswordField.setCaption(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password"));
		newPasswordField.setDescription(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password_tip"));

		// Password field PASSWORD_VERIFIED
		PasswordField newPasswordVerifyingField = new PasswordField();
		newPasswordVerifyingField.setSizeFull();
		textArea.addComponent(newPasswordVerifyingField);
		newPasswordVerifyingField.setCaption(dslMetadataService.translate(getLocale().toLanguageTag(), "password_verifying"));
		newPasswordVerifyingField.setDescription(dslMetadataService.translate(getLocale().toLanguageTag(), "password_verifying_tip"));

		// Button newPassword
		Button newPasswordSaveButton = new Button();
		newPasswordSaveButton.setSizeFull();
		newPasswordArea.addComponent(newPasswordSaveButton);
		newPasswordSaveButton.setCaption(dslMetadataService.translate(getLocale().toLanguageTag(), "save"));
		newPasswordSaveButton.setDescription(dslMetadataService.translate(getLocale().toLanguageTag(), "save_tip"));
		newPasswordSaveButton.addClickListener(new Button.ClickListener() {

			@Override
			public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
				if (updatePassword(userAccountDto, oldPasswordField, newPasswordField, newPasswordVerifyingField)) {
					closeThisWindow();
				}
			}

		});

		// Button CANCEL
		Button cancelButton = new Button();
		cancelButton.setSizeFull();
		newPasswordArea.addComponent(cancelButton);
		cancelButton.setCaption(dslMetadataService.translate(getLocale().toLanguageTag(), "cancel"));
		cancelButton.setDescription(dslMetadataService.translate(getLocale().toLanguageTag(), "cancel_newPassword_tip"));
		cancelButton.addClickListener(new Button.ClickListener() {

			@Override
			public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
				closeThisWindow();
			}

		});
		return this;
	}

	private boolean updatePassword(UserAccountDto userAccountDto, PasswordField oldPasswordField, PasswordField passwordField,
			PasswordField passwordVerifyingField) {
		if (oldPasswordField == null || oldPasswordField.isEmpty()) {
			Notification.show(dslMetadataService.translate(getLocale().toLanguageTag(), "old_password_is_empty_message"));
			oldPasswordField.focus();
			return false;
		} else if (oldPasswordField != null
				&& !AuthenticationUiUtil.checkPassword(AuthenticationUiUtil.PORTAL_ID, userAccountDto.getUserName(),
						oldPasswordField.getValue())) {
			Notification.show(dslMetadataService.translate(getLocale().toLanguageTag(), "old_password_is_wrong"));
			return false;
		} else if (passwordField == null || passwordField.isEmpty()) {
			Notification.show(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password_is_empty_message"));
			passwordField.focus();
			return false;
		} else if (passwordVerifyingField == null || passwordVerifyingField.isEmpty()) {
			Notification.show(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password_verifying_is_empty_message"));
			passwordVerifyingField.focus();
			return false;
		} else if (passwordField != null && passwordVerifyingField != null
				&& !passwordField.getValue().equals(passwordVerifyingField.getValue())) {
			Notification.show(dslMetadataService.translate(getLocale().toLanguageTag(), "passwords_not_equal_message"));
			passwordField.focus();
			passwordField.clear();
			passwordVerifyingField.clear();
			return false;
		} else {
			String encryptedPassword = InitializationListener.getUserAccessService().encryptPassword(passwordField.getValue());
			userAccountDto.setPassword(encryptedPassword);
			userAccountDto.setPasswordReset(false);
			userAccountDto.setLocked(false);
			userAccountDto.setFailedAttempt(0);
			UserProtocol.getDtoUserAccountDtoService().update(userAccountDto);
			Notification.show(dslMetadataService.translate(getLocale().toLanguageTag(), "new_password_success_message"));
			return true;
		}
	}

	private void closeThisWindow() {
		close();
	}
}
