/*
Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend
Copyright (C) 2024 Christian Fraß

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

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see 
<https://www.gnu.org/licenses/>. 
 */

lib_plankton.zoo_page.register(
	"invite_create",
	async (parameters, target_element) => {
		target_element.appendChild(template_request("invite_create"));
		
		target_element.querySelector(".invite_create-title").textContent = lib_plankton.translate.get("page.invite_create.title");
		
		const indent = str => (/*"... " + */str);
				
		/**
		 * @todo outsource
		 */
		const null_when_empty = (str) => (((str === null) || (str === "")) ? null : str);

		/**
		 * @todo cache
		 */
		const groups_as_array : Array<{id : int; name : string;}> = await _espe.backend.group_list();
		const groups_as_map : Map<int, {name : string;}> = new Map<int, {name : string;}>();
		for (const group_thingy of groups_as_array)
		{
			groups_as_map.set(group_thingy.id, {"name": group_thingy.name});
		}
		
		const form = new lib_plankton.zoo_form.class_form<
			{
				data : {
					name_changeable : boolean;
					name_value : (null | string);
					email_address_changeable : boolean;
					email_address_value : (null | string);
					groups_changeable : boolean;
					groups_value : Array<int>;
					expiry : (null | int);
				};
				send_immediatly : boolean;
			},
			{
				name : {
					changeable : boolean;
					value : string;
				};
				email_address : {
					changeable : boolean;
					value : string;
				};
				groups : {
					changeable : boolean;
					value : Array<int>;
				};
				expiry : (null | lib_plankton.pit.type_datetime);
				send_immediatly : boolean;
			}
		>(
			value => ({
				"name": {
					"changeable": value.data.name_changeable,
					"value": value.data.name_value,
				},
				"email_address": {
					"changeable": value.data.email_address_changeable,
					"value": (value.data.email_address_value ?? ""),
				},
				"groups": {
					"changeable": value.data.groups_changeable,
					"value": value.data.groups_value,
				},
				"expiry": (
					(value.data.expiry === null)
					?
					null
					:
					lib_plankton.pit.to_datetime(lib_plankton.pit.from_unix_timestamp(value.data.expiry))
				),
				"send_immediatly": value.send_immediatly,
			}),
			representation => ({
				"data": {
					"name_changeable": representation.name.changeable,
					"name_value": null_when_empty(representation.name.value),
					"email_address_changeable": representation.email_address.changeable,
					"email_address_value": null_when_empty(representation.email_address.value),
					"groups_changeable": representation.groups.changeable,
					"groups_value": representation.groups.value,
					"expiry": (
						(representation.expiry === null)
						?
						null
						:
						lib_plankton.pit.to_unix_timestamp(lib_plankton.pit.from_datetime(representation.expiry))
					),
				},
				"send_immediatly": representation.send_immediatly,
			}),
			new lib_plankton.zoo_input.class_input_group(
				[
					{
						"name": "name",
						"input": new lib_plankton.zoo_input.class_input_group(
							[
								{
									"name": "value",
									"input": new lib_plankton.zoo_input.class_input_text(),
									"label": indent(lib_plankton.translate.get("common.initial_value")),
								},
								{
									"name": "changeable",
									"input": new lib_plankton.zoo_input.class_input_checkbox(),
									"label": indent(lib_plankton.translate.get("common.changeable")),
								},
							]
						),
						"label": lib_plankton.translate.get("domain.member.name.label"),
					},
					{
						"name": "email_address",
						"input": new lib_plankton.zoo_input.class_input_group(
							[
								{
									"name": "value",
									"input": new lib_plankton.zoo_input.class_input_text(),
									"label": indent(lib_plankton.translate.get("common.initial_value")),
								},
								{
									"name": "changeable",
									"input": new lib_plankton.zoo_input.class_input_checkbox(),
									"label": indent(lib_plankton.translate.get("common.changeable")),
								},
							]
						),
						"label": lib_plankton.translate.get("domain.member.email_address.label"),
					},
					{
						"name": "groups",
						"input": new lib_plankton.zoo_input.class_input_group(
							[
								{
									"name": "value",
									/*
									"input": new lib_plankton.zoo_input.class_input_list(
										() => new lib_plankton.zoo_input.class_input_text()
									),
									 */
									"input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
										new _espe.class_input_set(
											groups_as_array.map(
												group_thingy => group_thingy.id.toFixed(0)
											),
											group_id_encoded => groups_as_map.get(parseInt(group_id_encoded)).name
										),
										(value_inner) => {
											const array : Array<int> = [];
											for (const group_id_encoded of value_inner)
											{
												array.push(parseInt(group_id_encoded));
											}
											return array;
										},
										(value_outer) => new Set<string>(value_outer.map(group_id => group_id.toFixed(0)))
									),
									"label": indent(lib_plankton.translate.get("common.initial_value")),
								},
								{
									"name": "changeable",
									"input": new lib_plankton.zoo_input.class_input_checkbox(),
									"label": indent(lib_plankton.translate.get("common.changeable")),
								},
							]
						),
						"label": lib_plankton.translate.get("domain.member.groups.label"),
					},
					{
						"name": "expiry",
						"input": new lib_plankton.zoo_input.class_input_soft(
							new lib_plankton.zoo_input.class_input_datetime_central_europe(
								{
									// "label_timezone_shift": indent(lib_plankton.translate.get("common.timezone_shift")),
									"label_date": indent(lib_plankton.translate.get("common.date")),
									"label_time": indent(lib_plankton.translate.get("common.time")),
								}
							)
						),
						"label": lib_plankton.translate.get("domain.invite.expiry.label"),
					},
					{
						"name": "send_immediatly",
						"input": new lib_plankton.zoo_input.class_input_checkbox(),
						"label": indent(lib_plankton.translate.get("page.invite_create.form.field.send_immediatly.label")),
					},
				]
			),
			[
				{
					"label": lib_plankton.translate.get("page.invite_create.form.action.submit"),
					"procedure": async (get_value, get_representation) => {
						const value = await get_value();
						const result : {id : int; key : string;} = await _espe.backend.invite_create(
							value.data,
							value.send_immediatly,
							lib_plankton.zoo_page.encode(
								{
									"name": "invite_handle",
									"parameters": {
										"key": "{{key}}",
									}
								}
							)
						);
						lib_plankton.zoo_page.set(
							false
							?
							{
								"name": "invite_view",
								"parameters": {"id": result.id.toFixed(0)}
							}
							:
							{
								"name": "invite_list",
								"parameters": {}
							}
						);
					},
				}
			]
		);
		await form.setup(target_element.querySelector(".invite_create-form") as HTMLElement);
		form.input_write(
			{
				"data": {
					"name_changeable": false,
					"name_value": "",
					"email_address_changeable": true,
					"email_address_value": null,
					"groups_changeable": false,
					"groups_value": [],
					/**
					 * @todo conf
					 */
					"expiry": lib_plankton.pit.shift_week(lib_plankton.pit.now(), 2),
				},
				"send_immediatly": true,
			}
		);
	}
);
