package org.openlca.app.navigation.actions;

import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.openlca.app.M;
import org.openlca.app.db.Cache;
import org.openlca.app.db.Database;
import org.openlca.app.editors.parameters.RenameParameterDialog;
import org.openlca.app.navigation.Navigator;
import org.openlca.app.navigation.elements.CategoryElement;
import org.openlca.app.navigation.elements.INavigationElement;
import org.openlca.app.navigation.elements.ModelElement;
import org.openlca.app.rcp.images.Icon;
import org.openlca.app.util.ErrorReporter;
import org.openlca.app.util.MsgBox;
import org.openlca.app.util.UI;
import org.openlca.core.database.CategoryDao;
import org.openlca.core.database.Daos;
import org.openlca.core.database.ParameterDao;
import org.openlca.core.database.RootEntityDao;
import org.openlca.core.model.Category;
import org.openlca.core.model.ModelType;
import org.openlca.core.model.RootEntity;
import org.openlca.core.model.descriptors.Descriptor;
import org.openlca.core.model.descriptors.RootDescriptor;

class RenameAction extends Action implements INavigationAction {

	private INavigationElement<?> element;

	public RenameAction() {
		setText(M.Rename);
		setImageDescriptor(Icon.CHANGE.descriptor());
	}

	@Override
	public boolean accept(List<INavigationElement<?>> selection) {
		if (selection.size() != 1)
			return false;
		var first = selection.get(0);
		if (!(first instanceof ModelElement
				|| first instanceof CategoryElement))
			return false;
		if (first.getLibrary().isPresent())
			return false;
		this.element = first;
		return true;
	}

	@Override
	public void run() {

		// for parameters, open another dialog
		if (element instanceof ModelElement) {
			var d = ((ModelElement) element).getContent();
			if (d.type == ModelType.PARAMETER) {
				var param = new ParameterDao(Database.get())
						.getForId(d.id);
				RenameParameterDialog.open(param);
				return;
			}
		}

		var name = element instanceof CategoryElement
				? ((CategoryElement) element).getContent().name
				: ((ModelElement) element).getContent().name;

		var dialog = new InputDialog(UI.shell(), M.Rename,
				M.PleaseEnterANewName, name, null);
		if (dialog.open() != Window.OK)
			return;
		var newName = dialog.getValue();
		if (newName == null || newName.trim().isEmpty()) {
			MsgBox.error(M.NameCannotBeEmpty);
			return;
		}
		if (element instanceof CategoryElement) {
			doUpdate(((CategoryElement) element).getContent(), newName);
		} else {
			doUpdate(((ModelElement) element).getContent(), newName);
		}
	}

	private void doUpdate(Category category, String newName) {
		try {
			category.name = newName.trim();
			category = new CategoryDao(Database.get()).update(category);
			Cache.evict(Descriptor.of(category));
			Navigator.refresh(element);
		} catch (final Exception e) {
			ErrorReporter.on("Failed to update category", e);
		}
	}

	@SuppressWarnings("unchecked")
	private <T extends RootEntity> void doUpdate(
			RootDescriptor d, String newName) {
		var dao = (RootEntityDao<T, ?>) Daos.root(
				Database.get(), d.type);
		T entity = dao.getForId(d.id);
		entity.name = newName.trim();
		dao.update(entity);
		Navigator.refresh(element.getParent());
	}

}

@@ -1539,17 +1539,16 @@
 ment%0A%09%09%09
-%09
 %7C%7C first
@@ -1579,58 +1579,220 @@
 ent)
-)%0A%09%09%09return false;%0A%09%09if (first.getLibrary().isPres
+%0A%09%09%09%7C%7C first.getLibrary().isPresent())%0A%09%09%09return false;%0A%09%09if (first instanceof ModelElement e) %7B%0A%09%09%09if (e.isFromLibrary())%0A%09%09%09%09return false;%0A%09%09%7D%0A%09%09if (first instanceof CategoryElement e) %7B%0A%09%09%09if (e.hasLibraryCont
 ent(
@@ -1789,32 +1789,33 @@
 ryContent())%0A%09%09%09
+%09
 return false;%0A%09%09
@@ -1812,16 +1812,20 @@
  false;%0A
+%09%09%7D%0A
 %09%09this.e
@@ -2118,17 +2118,16 @@
 ))%0A%09%09%09%09%09
-%09
 .getForI
@@ -2247,17 +2247,16 @@
 ment%0A%09%09%09
-%09
 ? ((Cate
@@ -2295,17 +2295,16 @@
 ().name%0A
-%09
 %09%09%09: ((M
@@ -2401,17 +2401,16 @@
 ame,%0A%09%09%09
-%09
 M.Please
@@ -3224,17 +3224,16 @@
 date(%0A%09%09
-%09
 RootDesc
@@ -3305,17 +3305,16 @@
 s.root(%0A
-%09
 %09%09%09Datab

test the new library predicate in the RenameAction