/*
This file is part of »dali«.

Copyright 2025 'kcf' <fenris@folksprak.org>

»dali« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»dali« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »dali«. If not, see <http://www.gnu.org/licenses/>.
 */


namespace _dali.widgets
{
	
	/**
	 */
	export type type_value = {
		calendar_id : (null | _dali.type_calendar_id);
		event_name : string;
		event_begin : lib_plankton.pit.type_datetime;
		event_end : (null | lib_plankton.pit.type_datetime);
		event_location : (null | string);
		event_link : (null | string);
		event_description : (null | string);
	};
	
	
	/**
	 */
	export type type_representation = {
		calendar_id : string;
		event_name : string;
		event_begin : lib_plankton.pit.type_datetime;
		event_end : (null | lib_plankton.pit.type_datetime);
		event_location : (null | string);
		event_link : (null | string);
		event_description : (null | string);
	};
	
	
	/**
	 */
	export class class_widget_event_edit
		implements lib_plankton.zoo_widget.interface_widget
	{
		
		/**
		 * [data]
		 */
		private available_calendars : Array<
			{
				id : int;
				name : string;
				hue : float;
				access_level : _dali.enum_access_level;
			}
		>;
		
		
		/**
		 * [data]
		 */
		private read_only : boolean;
		
		
		/**
		 * [data]
		 */
		private initial_value : type_value;
		
		
		/**
		 * [hook]
		 */
		private action_cancel ?: (null | (() => void));
		
		
		/**
		 * [hook]
		 */
		private action_add ?: (null | ((value : type_value) => void));
		
		
		/**
		 * [hook]
		 */
		private action_change ?: (null | ((value : type_value) => void));
		
		
		/**
		 * [hook]
		 */
		private action_remove ?: (null | ((value : type_value) => void));
		
		
		/**
		 */
		public constructor(
			available_calendars : Array<
				{
					id : int;
					name : string;
					hue : float;
					access_level : _dali.enum_access_level;
				}
			>,
			initial_value : type_value,
			{
				"read_only": read_only = false,
				"action_cancel": action_cancel = null,
				"action_add": action_add = null,
				"action_change": action_change = null,
				"action_remove": action_remove = null,
			}
			:
			{
				read_only ?: boolean;
				action_cancel ?: (null | (() => void));
				action_add ?: (null | ((value : type_value) => void));
				action_change ?: (null | ((value : type_value) => void));
				action_remove ?: (null | ((value : type_value) => void));
			}
			=
			{
			}
		)
		{
			// data
			this.read_only = read_only;
			this.available_calendars = available_calendars;
			this.initial_value = initial_value;
			
			// hooks
			this.action_cancel = action_cancel;
			this.action_add = action_add;
			this.action_change = action_change;
			this.action_remove = action_remove;
		}
		
		
		/**
		 * [implementation]
		 */
		public async load(
			target_element : HTMLElement
		) : Promise<void>
		{
			const dom_root = await _dali.helpers.element_from_template(
				"widget-event_edit",
				"main",
				{
				}
			);
			
			const form : lib_plankton.zoo_form.class_form<
				type_value,
				type_representation
			> = new lib_plankton.zoo_form.class_form<
				type_value,
				type_representation
			>(
				(value) => ({
					"calendar_id": (value.calendar_id ?? this.available_calendars[0].id).toFixed(0),
					"event_name": value.event_name,
					"event_begin": value.event_begin,
					"event_end": value.event_end,
					"event_location": value.event_location,
					"event_link": value.event_link,
					"event_description": value.event_description,
				}),
				(representation) => ({
					"calendar_id": parseInt(representation.calendar_id),
					"event_name": representation.event_name,
					"event_begin": representation.event_begin,
					"event_end": representation.event_end,
					"event_location": representation.event_location,
					"event_link": representation.event_link,
					"event_description": representation.event_description,
				}),
				new lib_plankton.zoo_input.class_input_group<any>(
					[
						{
							"name": "calendar_id",
							"input": new lib_plankton.zoo_input.class_input_selection(
								(
									this.available_calendars
									.map(
										(entry) => ({
											"value": entry.id.toFixed(0),
											"label": entry.name,
										})
									)
								)
							),
							"label": lib_plankton.translate.get("calendar.calendar")
						},
						{
							"name": "event_name",
							"input": new lib_plankton.zoo_input.class_input_text(
							),
							"label": lib_plankton.translate.get("event.name")
						},
						{
							"name": "event_begin",
							"input": _dali.helpers.datetime_input(
								(await _dali.model.settings()).use_fallback_for_date_and_time_inputs
							),
							"label": lib_plankton.translate.get("event.begin")
						},
						{
							"name": "event_end",
							"input": new lib_plankton.zoo_input.class_input_soft<lib_plankton.pit.type_datetime>(
								_dali.helpers.datetime_input(
									(await _dali.model.settings()).use_fallback_for_date_and_time_inputs
								)
							),
							"label": lib_plankton.translate.get("event.end")
						},
						{
							"name": "event_location",
							"input": new lib_plankton.zoo_input.class_input_soft<string>(
								new lib_plankton.zoo_input.class_input_text(
								)
							),
							"label": lib_plankton.translate.get("event.location")
						},
						{
							"name": "event_link",
							"input": new lib_plankton.zoo_input.class_input_soft<string>(
								new lib_plankton.zoo_input.class_input_text(
								)
							),
							"label": lib_plankton.translate.get("event.link")
						},
						{
							"name": "event_description",
							"input": new lib_plankton.zoo_input.class_input_soft<string>(
								new lib_plankton.zoo_input.class_input_textarea(
								)
							),
							"label": lib_plankton.translate.get("event.description")
						},
					]
				),
				(
					[]
					// add
					.concat(
						((! this.read_only) && (! (this.action_add === null)))
						?
						[
							{
								"label": lib_plankton.translate.get("widget.event_edit.actions.add"),
								"procedure": async (get_value, get_representation) => {
									const value : type_value = await get_value();
									this.action_add(value);
								}
							},
						]
						:
						[]
					)
					// change
					.concat(
						((! this.read_only) && (! (this.action_change === null)))
						?
						[
							{
								"label": lib_plankton.translate.get("widget.event_edit.actions.change"),
								"procedure": async (get_value, get_representation) => {
									const value : type_value = await get_value();
									this.action_change(value);
								}
							},
						]
						:
						[]
					)
					// remove
					.concat(
						((! this.read_only) && (! (this.action_remove === null)))
						?
						[
							{
								"label": lib_plankton.translate.get("widget.event_edit.actions.remove"),
								"procedure": async (get_value, get_representation) => {
									if (! window.confirm(lib_plankton.translate.get("common.confirm_deletion")))
									{
										// do nothing
									}
									else
									{
										const value : type_value = await get_value();
										this.action_remove(value);
									}
								}
							},
						]
						:
						[]
					)
					// cancel
					.concat(
						(! (this.action_cancel === null))
						?
						[
							{
								"label": lib_plankton.translate.get("common.cancel"),
								"procedure": async () => {
									this.action_cancel();
								}
							},
						]
						:
						[]
					)
				)
			);
			await form.setup(dom_root);
			await form.input_lock(this.read_only);
			await form.input_write(this.initial_value);
			
			target_element.appendChild(dom_root);
			form.input_focus();
		}
		
	}
	
}
