package org.openlca.app.tools.openepd;

import java.util.Optional;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.openlca.app.rcp.images.Icon;
import org.openlca.app.tools.openepd.model.Credentials;
import org.openlca.app.tools.openepd.model.Ec3Client;
import org.openlca.app.util.Controls;
import org.openlca.app.util.ErrorReporter;
import org.openlca.app.util.MsgBox;
import org.openlca.app.util.UI;
import org.openlca.util.Strings;

public class LoginPanel {

	private final Credentials credentials;
	private Ec3Client client;
	private Button button;

	private LoginPanel() {
		credentials = Credentials.getDefault();
	}

	public static LoginPanel create(Composite body, FormToolkit tk) {
		var section = new LoginPanel();
		section.render(body, tk);
		return section;
	}

	public Credentials credentials() {
		return credentials;
	}

	private void render(Composite body, FormToolkit tk) {
		var section = UI.section(body, tk, "EC3 Login");
		var comp = UI.sectionClient(section, tk, 2);

		// url
		var filled = 0;
		var urlText = UI.formText(comp, tk, "URL");
		if (Strings.notEmpty(credentials.url())) {
			urlText.setText(credentials.url());
			filled++;
		}
		urlText.addModifyListener(
			$ -> credentials.url(urlText.getText()));

		// user
		var userText = UI.formText(comp, tk, "User");
		if (Strings.notEmpty(credentials.user())) {
			userText.setText(credentials.user());
			filled++;
		}
		userText.addModifyListener(
			$ -> credentials.user(userText.getText()));

		// password
		var pwText = UI.formText(comp, tk, "Password", SWT.PASSWORD);
		if (Strings.notEmpty(credentials.password())) {
			pwText.setText(credentials.password());
			filled++;
		}
		pwText.addModifyListener(
			$ -> credentials.password(pwText.getText()));

		// login button
		UI.filler(comp, tk);
		button = tk.createButton(comp, "Login", SWT.NONE);
		button.setImage(Icon.CONNECT.get());
		Controls.onSelect(button, $ -> {
			if (client == null) {
				login();
			} else {
				logout();
			}
		});
		button.addDisposeListener($ -> {
			if (client != null) {
				client.logout();
			}
		});

		section.setExpanded(filled < 3);
	}

	public Optional<Ec3Client> login() {
		if (client != null)
			return Optional.of(client);
		if (button.isDisposed())
			return Optional.empty();
		try {
			var o = credentials.login();
			if (o.isEmpty()) {
				MsgBox.error("Login failed",
					"Failed to login into the EC3 API with" +
						" the given user name and password.");
				updateButton("Login");
				client = null;
				return Optional.empty();
			}
			client = o.get();
			updateButton("Logout");
			return o;
		} catch (Exception e) {
			ErrorReporter.on("EC3 login failed", e);
			client = null;
			updateButton("Login");
			return Optional.empty();
		}
	}

	public void logout() {
		if (button.isDisposed())
			return;
		if (client != null) {
			try {
				client.logout();
			} catch (Exception e) {
				ErrorReporter.on("EC3 logout failed", e);
			} finally {
				client = null;
			}
		}
		updateButton("Login");
	}

	private void updateButton(String text) {
		if (button.isDisposed())
			return;
		button.setText(text);
		button.getParent().layout();
		button.getParent().redraw();
	}

}

@@ -619,16 +619,53 @@
 ntials;%0A
+%09private boolean credentialsChanged;%0A
 %09private
@@ -683,16 +683,16 @@
 client;%0A
-
 %09private
@@ -1343,33 +1343,64 @@
 ifyListener(
-%0A%09%09%09
 $ -%3E 
+%7B%0A%09%09%09credentialsChanged = true;%0A%09%09%09
 credentials.
@@ -1413,32 +1413,37 @@
 lText.getText())
+;%0A%09%09%7D
 );%0A%0A%09%09// user%0A%09%09
@@ -1617,33 +1617,64 @@
 ifyListener(
-%0A%09%09%09
 $ -%3E 
+%7B%0A%09%09%09credentialsChanged = true;%0A%09%09%09
 credentials.
@@ -1689,32 +1689,37 @@
 rText.getText())
+;%0A%09%09%7D
 );%0A%0A%09%09// passwor
@@ -1925,17 +1925,48 @@
 ner(
-%0A%09%09%09
 $ -%3E 
+%7B%0A%09%09%09credentialsChanged = true;%0A%09%09%09
 cred
@@ -1999,16 +1999,21 @@
 tText())
+;%0A%09%09%7D
 );%0A%0A%09%09//
@@ -2493,32 +2493,32 @@
 n.isDisposed())%0A
-
 %09%09%09return Option
@@ -2529,16 +2529,102 @@
 mpty();%0A
+%09%09if (credentialsChanged) %7B%0A%09%09%09credentials.save();%0A%09%09%09credentialsChanged = false;%0A%09%09%7D%0A
 %09%09try %7B%0A

save changed credentials on login