package ui

type SelectOption struct {
	Value    string
	Label    string
	Disabled bool
}

type SelectProps struct {
	ID          string
	Name        string
	Placeholder string
	Value       string
	Values      []string
	Multiple    bool
	Options     []SelectOption
	Attrs       templ.Attributes
}

templ Select(props SelectProps) {
	<div
		class="ui-select"
		data-ui-select-root
		data-ui-select-multiple={ selectBoolData(props.Multiple) }
		data-placeholder={ selectPlaceholder(props) }
		data-selected-label={ selectSelectedLabel(props) }
	>
		<select
			id={ selectNativeID(props.ID, props.Name) }
			name={ props.Name }
			class="ui-select-native"
			data-ui-select-native
			if props.Multiple {
				multiple
			}
			{ props.Attrs... }
		>
			if !props.Multiple && selectPlaceholder(props) != "" {
				<option value="">{ selectPlaceholder(props) }</option>
			}
			for _, option := range props.Options {
				<option
					value={ option.Value }
					if option.Disabled {
						disabled
					}
					if selectOptionSelected(props, option.Value) {
						selected
					}
				>{ option.Label }</option>
			}
		</select>
		<button
			id={ inputID(props.ID, props.Name) }
			type="button"
			class="ui-select-control"
			data-ui-select-trigger
			aria-haspopup="listbox"
			aria-expanded="false"
			aria-controls={ selectMenuID(props.ID, props.Name) }
			if selectIsDisabled(props.Attrs) {
				disabled
			}
		>
			<span class="ui-select-value-wrapper" data-ui-select-label>
				if props.Multiple {
					if len(selectSelectedLabels(props)) == 0 {
						<span class="ui-select-placeholder">{ selectPlaceholder(props) }</span>
					} else {
						for _, label := range selectSelectedLabels(props) {
							<span class="ui-select-chip">{ label }</span>
						}
					}
				} else if selectSelectedLabel(props) != "" {
					{ selectSelectedLabel(props) }
				} else {
					<span class="ui-select-placeholder">{ selectPlaceholder(props) }</span>
				}
			</span>
			<span class="ui-select-arrow-zone">
				<svg class="ui-select-arrow-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
					<path d="m6 9 6 6 6-6"></path>
				</svg>
			</span>
		</button>
		<div
			id={ selectMenuID(props.ID, props.Name) }
			class="ui-select-menu"
			data-ui-select-menu
			role="listbox"
			if props.Multiple {
				aria-multiselectable="true"
			}
			hidden
		>
			for _, option := range props.Options {
				<button
					type="button"
					class={ selectMenuOptionClass(selectOptionSelected(props, option.Value), option.Disabled) }
					data-ui-select-option
					data-value={ option.Value }
					data-label={ option.Label }
					role="option"
					aria-selected={ selectBoolData(selectOptionSelected(props, option.Value)) }
					if option.Disabled {
						disabled
					}
				>
					<span class="ui-select-option-text">{ option.Label }</span>
					<span class="ui-select-option-check" aria-hidden="true">✓</span>
				</button>
			}
		</div>
		<script>
			(function () {
				if (!window.__uiSelectInitAll) {
					window.__uiSelectSetOpen = function (root, open) {
						var trigger = root.querySelector("[data-ui-select-trigger]");
						var menu = root.querySelector("[data-ui-select-menu]");
						if (!trigger || !menu) {
							return;
						}
						root.classList.toggle("is-open", open);
						trigger.setAttribute("aria-expanded", open ? "true" : "false");
						menu.hidden = !open;
					};

					window.__uiSelectCloseAll = function (exceptRoot) {
						document.querySelectorAll("[data-ui-select-root].is-open").forEach(function (root) {
							if (root !== exceptRoot) {
								window.__uiSelectSetOpen(root, false);
							}
						});
					};

					window.__uiSelectSync = function (root) {
						var nativeSelect = root.querySelector("[data-ui-select-native]");
						var outlet = root.querySelector("[data-ui-select-label]");
						var placeholder = root.getAttribute("data-placeholder") || "";
						var multiple = root.getAttribute("data-ui-select-multiple") === "true";
						if (!nativeSelect || !outlet) {
							return;
						}

						var labels = Array.from(nativeSelect.options).filter(function (option) {
							return option.selected && option.value !== "";
						}).map(function (option) {
							return option.textContent;
						});

						root.setAttribute("data-selected-label", labels.join(", "));
						outlet.innerHTML = "";

						if (labels.length === 0) {
							var placeholderNode = document.createElement("span");
							placeholderNode.className = "ui-select-placeholder";
							placeholderNode.textContent = placeholder;
							outlet.appendChild(placeholderNode);
						} else if (multiple) {
							labels.forEach(function (label) {
								var chip = document.createElement("span");
								chip.className = "ui-select-chip";
								chip.textContent = label;
								outlet.appendChild(chip);
							});
						} else {
							outlet.textContent = labels[0];
						}

						root.querySelectorAll("[data-ui-select-option]").forEach(function (optionButton) {
							var selected = Array.from(nativeSelect.options).some(function (option) {
								return option.value === optionButton.getAttribute("data-value") && option.selected;
							});
							optionButton.classList.toggle("is-selected", selected);
							optionButton.setAttribute("aria-selected", selected ? "true" : "false");
						});
					};

					window.__uiSelectToggleValue = function (root, optionButton) {
						var nativeSelect = root.querySelector("[data-ui-select-native]");
						var multiple = root.getAttribute("data-ui-select-multiple") === "true";
						var value = optionButton.getAttribute("data-value");
						if (!nativeSelect || value === null) {
							return;
						}

						Array.from(nativeSelect.options).forEach(function (option) {
							if (option.value !== value && !multiple) {
								option.selected = false;
							}
							if (option.value === value) {
								option.selected = multiple ? !option.selected : true;
							}
						});

						window.__uiSelectSync(root);
						nativeSelect.dispatchEvent(new Event("change", { bubbles: true }));

						if (!multiple) {
							window.__uiSelectSetOpen(root, false);
						}
					};

					window.__uiSelectInitAll = function (scope) {
						(scope || document).querySelectorAll("[data-ui-select-root]").forEach(function (root) {
							window.__uiSelectSync(root);
						});
					};

					document.addEventListener("click", function (event) {
						var optionButton = event.target.closest("[data-ui-select-option]");
						if (optionButton) {
							var optionRoot = optionButton.closest("[data-ui-select-root]");
							if (optionRoot) {
								window.__uiSelectToggleValue(optionRoot, optionButton);
							}
							return;
						}

						var trigger = event.target.closest("[data-ui-select-trigger]");
						if (trigger) {
							var root = trigger.closest("[data-ui-select-root]");
							var shouldOpen = root && !root.classList.contains("is-open");
							window.__uiSelectCloseAll(root);
							if (root) {
								window.__uiSelectSetOpen(root, shouldOpen);
							}
							return;
						}

						if (!event.target.closest("[data-ui-select-root]")) {
							window.__uiSelectCloseAll(null);
						}
					});

					document.addEventListener("keydown", function (event) {
						if (event.key === "Escape") {
							window.__uiSelectCloseAll(null);
						}
					});

					document.addEventListener("htmx:afterSwap", function (event) {
						window.__uiSelectInitAll(event.target);
					});
				}

				window.__uiSelectInitAll(document);
			})();
		</script>
	</div>
}
