/*
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
{
	
	/**
	 */
	type type_entry_data = {
		label : string;
		groups : Array<string>;
		action : (() => void);
	}
	
	
	/**
	 */
	export class class_widget_menu implements lib_plankton.zoo_widget.interface_widget
	{
		
		/**
		 */
		private entries : Array<type_entry_data>;
		
		
		/**
		 */
		private initial_groups : Array<string>;
		
		
		/**
		 */
		private label : (null | string);
		
		
		/**
		 */
		private container : (null | HTMLElement);
		
		
		/**
		 */
		public constructor(
			entries : Array<type_entry_data>,
			{
				"initial_groups": initial_groups = [],
				"initial_label": initial_label = "",
			}
			:
			{
				initial_groups ?: Array<string>;
				initial_label ?: string;
			}
			=
			{
			}
		)
		{
			this.entries = entries;
			this.initial_groups = initial_groups;
			this.label = initial_label;
			this.container = null;
		}
		
		
		/**
		 */
		public set_groups(
			groups : Array<string>
		)
		: void
		{
			this.entries.forEach(
				(entry, index) => {
					const active : boolean = groups.some(group => entry.groups.includes(group));
					const rel : string = index.toFixed(0);
					const dom_entry = this.container.querySelector(".widget-menu-entry[rel=\"" + rel + "\"]");
					dom_entry.classList.toggle("widget-menu-entry-hidden", (! active));
				}
			);
		}
		
		
		/**
		 */
		public set_label(
			label : (null | string)
		)
		: void
		{
			this.label = label;
			this.container.querySelector(".widget-menu-button").innerHTML = (
				(this.label === null)
				?
				("[" + "=" + "]")
				:
				("[" + this.label + "]")
			);
		}
		
		
		/**
		 */
		private toggle_collapsed(
			{
				"mode": mode = null,
			}
			:
			{
				mode ?: (null | boolean);
			}
			=
			{
			}
		)
		: void
		{
			this.container.classList.toggle("widget-menu-collapsed", mode ?? undefined);
		}
		
		
		/**
		 * [implementation]
		 */
		public async load(
			target_element : Element
		)
		: Promise<void>
		{
			// structure
			this.container = await _dali.helpers.element_from_template(
				"widget-menu",
				"main",
				{
					"entries": (
						(
							await lib_plankton.call.promise_condense(
								this.entries.map(
									(entry, index) => () => _dali.helpers.template_coin(
										"widget-menu",
										"entry",
										{
											"label": entry.label,
											"rel": index.toFixed(0),
										}
									)
								)
							)
						)
						.join("")
					),
				}
			);
			
			// logic
			{
				// collapser
				{
					this.container.querySelector(".widget-menu-button").addEventListener(
						"click",
						() => {
							this.toggle_collapsed();
						}
					);
				}
				// entries
				{
					this.container.querySelectorAll(".widget-menu-entry").forEach(
						dom_entry => {
							dom_entry.addEventListener(
								"click",
								() => {
									const index : int = parseInt(dom_entry.getAttribute("rel"));
									const entry : type_entry_data = this.entries[index];
									this.toggle_collapsed({"mode": true});
									entry.action();
								}
							);
						}
					);
				}
			}
			
			// init
			{
				this.toggle_collapsed({"mode": true});
				this.set_groups(this.initial_groups);
				this.set_label(null);
			}
			
			// finish
			target_element.appendChild(this.container);
		}
		
	}
	
}
