/*
 * SPDX-FileCopyrightText: 2012-2026 Univention GmbH
 * SPDX-License-Identifier: AGPL-3.0-only
 */

/*global define*/

define([
	"dojo/_base/declare",
	"dojo/_base/lang",
	"dojo/_base/array",
	"dojo/when",
	"dojo/promise/all",
	"dojox/html/entities",
	"umc/dialog",
	"umc/app",
	"umc/tools",
	"umc/widgets/Wizard",
	"umc/widgets/ComboBox",
	"umc/i18n!umc/modules/schoolwizards"
], function(declare, lang, array, when, all, entities, dialog, app, tools, Wizard, ComboBox, _) {

	return declare("umc.modules.schoolwizards.Wizard", [Wizard], {

		umcpCommand: null,
		store: null,

		udmLinkEnabled: null, // flag for showing a link to the fully flegded UDM module
		editMode: null,  // flag for edit mode
		$dn$: null,  // the object we edit
		school: null,  // the school of that object
		objectType: null, // the UDM type of that object
		loadedValues: null, // the values of the object as seen from server

		editModeDescriptionWithoutSchool: _('Edit {itemType} {itemName}'),
		createModeDescriptionWithoutSchool: _('Create a new {itemType}'),
		editModeDescription: _('{itemSchool}: edit {itemType} {itemName}'),
		createModeDescription: _('{itemSchool}: create a new {itemType}'),
		_skippedGeneralPage: false,

		postMixInProperties: function() {
			this.inherited(arguments);
			this.pages = [];
			var generalPage = this.getGeneralPage();
			if (generalPage) {
				this.pages.push(generalPage);
			}
			var itemPage = this.getItemPage();
			this.pages.push(itemPage);
		},

		getHeaderButtons: function(pageName) {
			var buttons =[];

			buttons.push({
				name: 'close',
				label: _('Cancel'),
				iconClass: 'arrow-left',
				callback: lang.hitch(this, 'onCancel')
			});

			if (this.udmLinkEnabled && this.editMode && this.objectType && app.getModule('udm', 'navigation')) {
				buttons.push({
					name: 'udm_link',
					label: _('Advanced settings'),
					callback: lang.hitch(this, function() {
						app.openModule('udm', 'navigation', {openObject: {objectType: this.objectType, objectDN: this.$dn$}});
						this.onFinished();  // close this wizard
					})
				});
			}

			return buttons;
		},

		getFooterButtons: function(pageName) {
			var buttons = [{
				name: 'previous',
				label: _('Back'),
				align: 'right',
				callback: lang.hitch(this, '_previous', pageName)
			}, {
				name: 'next',
				defaultButton: true,
				label: _('Next'),
				callback: lang.hitch(this, '_next', pageName)
			}, {
				name: 'finish',
				defaultButton: true,
				label: _('Finish'),
				callback: lang.hitch(this, '_finish', pageName)
			}];

			if (this._getPageIndex(pageName) === (this.pages.length - 1)) {
				array.forEach(buttons, lang.hitch(this, function(button) {
					if (button.name === 'next') {
						button.label = _('Save');
					}
				}));
			}

			return buttons;
		},

		loadVariables: function() {
			return null;
		},

		startup: function() {
			this.inherited(arguments);
			var loading = [this.loadValues(), this.loadVariables()];
			tools.forIn(this._pages, function(name, page) {
				if (page._form) {
					loading.push(page._form.ready());
				}
			});
			loading = all(loading);
			this.standbyDuring(loading);
			when(loading).always(lang.hitch(this, function(values) {
				var name = values && values[0] && values[0].name;
				var _setHandlerAndValue = lang.hitch(this, function(widget, value) {
					if (widget) {
						if (!value && widget.getAllItems) {
							var firstItem = widget.getAllItems()[0];
							value = firstItem && firstItem.id;
						}
						if (value) {
							widget.set('value', value);
							this.setHeader(widget, null, null, value);
						}
						widget.watch('value', lang.hitch(this, 'setHeader', widget));
					}
				});
				var typeWidget = this.getWidget('general', 'type');
				var schoolWidget = this.getWidget('general', 'school');
				var nameWidget = this.getWidget('item', 'name');
				_setHandlerAndValue(typeWidget, this.type);
				_setHandlerAndValue(schoolWidget, this.selectedSchool);
				_setHandlerAndValue(nameWidget, name);
				this.setHeader();
				if (this.selectedSchool && (!typeWidget || this.type)) {
					// hack to go to the next page (itemPage)
					this._skippedGeneralPage = true;
					this._next(this.next(null));
				}
			}));
		},

		hasPrevious: function() {
			if (this.editMode) {
				// make it impossible to show the general page
				return false;
			}
			if (this._skippedGeneralPage) {
				// general page was unnecessary: do not go back!
				return false;
			}
			return this.inherited(arguments);
		},

		setHeader: function(widget, attr, oldVal, newVal) {
			if (widget) {
				if (widget.getAllItems) {
					var allItems = widget.getAllItems();
					array.some(allItems, function(item) {
						if (item.id === newVal) {
							newVal = item.label;
							return true;
						}
					});
				}
				this.set('item' + tools.capitalize(widget.name), newVal);
			}
			var header = null;
			if (this.editMode) {
				if (this.itemSchool) {
					header = lang.replace(this.editModeDescription, {itemSchool: this.itemSchool, itemName: this.itemName, itemType: this.itemType});
				} else {
					header = lang.replace(this.editModeDescriptionWithoutSchool, {itemName: this.itemName, itemType: this.itemType});
				}
			} else {
				if (this.itemSchool) {
					header = lang.replace(this.createModeDescription, {itemSchool: this.itemSchool, itemName: this.itemName, itemType: this.itemType});
				} else {
					header = lang.replace(this.createModeDescriptionWithoutSchool, {itemName: this.itemName, itemType: this.itemType});
				}
			}
			tools.forIn(this._pages, function(name, page) {
				// general page has 'school' and 'type' widget.
				// seems not appropriate to set header to:
				// School: Create new Teacher although you can still
				// change it
				if (page.name !== 'general') {
					page.set('headerText', header);
				}
			});
		},

		getGeneralPage: function() {
			return {
				name: 'general',
				headerText: this.description,
				widgets: [{
					name: 'school',
					label: _('School'),
					type: ComboBox,
					staticValues: this.schools,
					value: this.selectedSchool,
					autoHide: true
				}],
				layout: ['school']
			};
		},

		loadValues: function() {
			if (!this.$dn$) {
				return null;
			}
			var load = this.store.get({
				object: {
					$dn$: this.$dn$,
					school: this.school
				}
			});
			load.then(lang.hitch(this, function(result) {
				this.loadedValues = result;
				tools.forIn(result, lang.hitch(this, function(key, value) {
					var widget = this.getWidget(key);
					if (widget) {
						widget.set('value', value);
					}
				}));
			}));
			return load;
		},

		hasNext: function() {
			return true;
		},

		next: function(/*String*/ currentPage) {
			var nextPage = this.inherited(arguments);
			this.updateWidgets(currentPage);
			if (this._getPageIndex(currentPage) === (this.pages.length - 1 )) {
				if (this._validateForm()) {
					if (this.editMode) {
						return this.finishEditMode(currentPage);
					} else {
						return this.finishAddMode(currentPage);
					}
				} else {
					return currentPage;
				}
			}
			return nextPage;
		},

		finishAddMode: function(currentPage) {
			return this._createObject().then(lang.hitch(this, function(result) {
				if (result) {
					this.addNote();
					this.restart();
					this.focusFirstWidget(currentPage);
				}
				return currentPage;
			}));
		},

		finishEditMode: function(currentPage) {
			var values = this.getValues();
			values.$dn$ = this.$dn$;
			values.school = this.school;
			return this.standbyDuring(this.store.put(values)).then(lang.hitch(this, function(response) {
				if (response.result) {
					dialog.alert(entities.encode(response.result.message));
				} else {
					this.onFinished();  // close this wizard
				}
				return currentPage;
			}));
		},

		_validateForm: function() {
			var form = this.selectedChildWidget.get('_form');
			if (!form.validate()) {
				var widgets = form.getInvalidWidgets();
				form.getWidget(widgets[0]).focus();
				return false;
			}
			return true;
		},

		_createObject: function() {
			var values = this.getValues();
			return this.standbyDuring(this.store.add(values)).then(
				function(response) {
					if (response.result) {
						dialog.alert(entities.encode(response.result.message));
						return false;
					}
					return true;
				},
				function() {
					return false;
				}
			);
		},

		restart: function() {
		},

		updateWidgets: function(/*String*/ currentPage) {
		},

		focusFirstWidget: function(pageName) {
			// Determine the name of the first widget
			var layout = this.getPage(pageName)._form.get('layout');
			while (layout instanceof Array) {
				layout = layout[0];
			}
			this.getWidget(pageName, layout).focus();
		}
	});
});
