/**
 * Copyright IBM Corp. 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import "../../globals/settings.js";
import { forEach, indexOf } from "../../globals/internal/collection-helpers.js";
import { carbonElement } from "../../globals/decorators/carbon-element.js";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.js";
import { CONTENT_SWITCHER_SIZE, NAVIGATION_DIRECTION } from "./defs.js";
import content_switcher_default$1 from "./content-switcher.scss.js";
import { LitElement, html } from "lit";
import { property } from "lit/decorators.js";
//#region src/components/content-switcher/content-switcher.ts
/**
* Copyright IBM Corp. 2019, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @param index The index
* @param length The length of the array.
* @returns The new index, adjusting overflow/underflow.
*/
const capIndex = (index, length) => {
	if (index < 0) return length - 1;
	if (index >= length) return 0;
	return index;
};
/**
* Content switcher.
*
* @element cds-custom-content-switcher
* @fires cds-custom-content-switcher-beingselected
*   The custom event fired before a content switcher item is selected upon a user gesture.
*   Cancellation of this event stops changing the user-initiated selection.
* @fires cds-custom-content-switcher-selected - The custom event fired after a a content switcher item is selected upon a user gesture.
*/
let CDSContentSwitcher = class CDSContentSwitcher extends LitElement {
	constructor(..._args) {
		super(..._args);
		this.value = "";
		this.selectedIndex = 0;
		this.selectionMode = "automatic";
		this.size = "";
		this.iconOnly = false;
		this.lowContrast = false;
	}
	/**
	* Handles `mouseover`/`mouseout` events on `<slot>`.
	*
	* @param event The event.
	* @param event.target The event target.
	* @param event.type The event type.
	*/
	_handleHover({ target, type }) {
		const { selectorItem } = this.constructor;
		const items = this.querySelectorAll(selectorItem);
		const index = type !== "mouseover" ? -1 : indexOf(items, target.closest(selectorItem));
		if (target.closest(selectorItem)?.hasAttribute("disabled")) return;
		const nextIndex = index < 0 ? index : index + 1;
		forEach(this.querySelectorAll(selectorItem), (elem, i) => {
			elem.hideDivider = i === nextIndex;
		});
		const { selectorItemSelected } = this.constructor;
		const selectedItem = this.querySelector(selectorItemSelected);
		const nextItem = this._getNextItem(selectedItem, 1);
		nextItem.hideDivider = true;
	}
	/**
	* @param target The current event target.
	* @returns The item to be selected.
	*/
	_getCurrentItem(target) {
		const items = this.querySelectorAll(this.constructor.selectorItemEnabled);
		const { selectorItem } = this.constructor;
		return items[indexOf(items, target.closest(selectorItem))] ?? null;
	}
	/**
	* @param currentItem The currently selected item.
	* @param direction The navigation direction.
	* @returns The item to be selected.
	*/
	_getNextItem(currentItem, direction) {
		const items = this.querySelectorAll(this.constructor.selectorItemEnabled);
		const currentIndex = indexOf(items, currentItem);
		const nextIndex = capIndex(currentIndex + direction, items.length);
		return nextIndex === currentIndex ? null : items[nextIndex];
	}
	/**
	* Handles `click` event on content switcher item.
	*
	* @param event The event.
	* @param event.target The event target.
	*/
	_handleClick({ target }) {
		const currentItem = this._getCurrentItem(target);
		this._handleUserInitiatedSelectItem(currentItem, "mouse");
	}
	/**
	* Handles `keydown` event on the top-level element in the shadow DOM.
	*
	* @param event The event.
	* @param event.key The event key.
	*/
	_handleKeydown({ key }) {
		if (key in NAVIGATION_DIRECTION) this._navigate(NAVIGATION_DIRECTION[key]);
	}
	/**
	* Handles user-initiated selection of a content switcher item.
	*
	* @param [item] The content switcher item user wants to select.
	*/
	_handleUserInitiatedSelectItem(item, interactionType) {
		if (item && !item.disabled && item.value !== this.value || this.selectionMode === "manual" && interactionType === "keyboard" && !item.disabled) if (this.selectionMode !== "manual" || interactionType !== "keyboard") {
			const init = {
				bubbles: true,
				composed: true,
				detail: { item }
			};
			const constructor = this.constructor;
			const beforeSelectEvent = new CustomEvent(constructor.eventBeforeSelect, {
				...init,
				cancelable: true
			});
			if (this.dispatchEvent(beforeSelectEvent)) {
				this._selectionDidChange(item, interactionType);
				const items = this.querySelectorAll(constructor.selectorItem);
				const index = Array.from(items).indexOf(item);
				const name = item.getAttribute("name") ?? void 0;
				const text = item.textContent?.trim() || item.getAttribute("aria-label")?.trim() || void 0;
				const afterSelectEvent = new CustomEvent(constructor.eventSelect, {
					bubbles: true,
					composed: true,
					detail: {
						item,
						index,
						name,
						text
					}
				});
				this.dispatchEvent(afterSelectEvent);
			}
		} else this._selectionDidChange(item, interactionType);
	}
	/**
	* Navigates through content switcher items.
	*
	* @param direction `-1` to navigate backward, `1` to navigate forward.
	*/
	_navigate(direction) {
		const { selectorItemFocused } = this.constructor;
		const nextItem = this._getNextItem(this.querySelector(selectorItemFocused), direction);
		if (nextItem) {
			this._handleUserInitiatedSelectItem(nextItem, "keyboard");
			this.requestUpdate();
		}
	}
	/**
	* A callback that runs after change in content switcher selection upon user interaction is confirmed.
	*
	* @param itemToSelect A content switcher item.
	*/
	_selectionDidChange(itemToSelect, interactionType) {
		if (this.selectionMode === "manual" && interactionType === "keyboard") {
			Promise.resolve().then(() => {
				itemToSelect.focus();
			});
			return;
		}
		this.value = itemToSelect.value;
		forEach(this.querySelectorAll(this.constructor.selectorItemSelected), (item) => {
			item.selected = false;
		});
		itemToSelect.selected = true;
		Promise.resolve().then(() => {
			itemToSelect.focus();
			const { selectorItem } = this.constructor;
			const index = indexOf(this.querySelectorAll(selectorItem), itemToSelect.closest(selectorItem));
			const nextIndex = index < 0 ? index : index + 1;
			forEach(this.querySelectorAll(selectorItem), (elem, i) => {
				elem.hideDivider = i === nextIndex;
			});
		});
	}
	firstUpdated() {
		this._updateSelectedItemFromIndex();
	}
	_updateSelectedItemFromIndex() {
		const { selectorItemEnabled } = this.constructor;
		const items = this.querySelectorAll(selectorItemEnabled);
		if (items.length > 0 && this.selectedIndex >= 0 && this.selectedIndex < items.length) {
			const itemToSelect = items[this.selectedIndex];
			this._selectionDidChange(itemToSelect, this.selectionMode === "manual" ? "activation" : "mouse");
		}
	}
	_updateSelectedItemFromValue(changedProps) {
		if (changedProps.has("value")) {
			const { selectorItem } = this.constructor;
			forEach(this.querySelectorAll(selectorItem), (elem) => {
				elem.selected = elem.value === this.value;
			});
		}
	}
	shouldUpdate(changedProps) {
		if (changedProps.has("iconOnly") || changedProps.has("selectedIndex")) {
			const items = this.querySelectorAll(`cds-custom-content-switcher-item`);
			const allIcon = Array.from(items).every((item) => item.hasAttribute("icon"));
			this.iconOnly = allIcon;
		}
		return true;
	}
	updated(changedProperties) {
		if (changedProperties.has("selectedIndex")) this._updateSelectedItemFromIndex();
		this._updateSelectedItemFromValue(changedProperties);
		if (changedProperties.has("size")) this.querySelectorAll(`cds-custom-content-switcher-item`).forEach((item) => {
			const size = this.size || "md";
			item.setAttribute("size", size);
		});
	}
	_handleSlotchange() {
		const { selectorItemSelected } = this.constructor;
		const selectedItem = this.querySelector(selectorItemSelected);
		const nextItem = this._getNextItem(selectedItem, 1);
		if (nextItem) nextItem.hideDivider = true;
	}
	/**
	* A selector that will return content switcher items.
	*/
	static get selectorItem() {
		return `cds-custom-content-switcher-item`;
	}
	/**
	* A selector that will return content switcher icon items.
	*/
	static get selectorIconItem() {
		return `cds-custom-content-switcher-item[icon]`;
	}
	/**
	* A selector that will return enabled content switcher items.
	*/
	static get selectorItemEnabled() {
		return `cds-custom-content-switcher-item:not([disabled])`;
	}
	/**
	* A selector that will return selected items.
	*/
	static get selectorItemSelected() {
		return `cds-custom-content-switcher-item[selected]`;
	}
	/**
	* A selector that will return focused items.
	*/
	static get selectorItemFocused() {
		return `cds-custom-content-switcher-item:focus`;
	}
	/**
	* The name of the custom event fired before a content switcher item is selected upon a user gesture.
	* Cancellation of this event stops changing the user-initiated selection.
	*/
	static get eventBeforeSelect() {
		return `cds-custom-content-switcher-beingselected`;
	}
	/**
	* The name of the custom event fired after a a content switcher item is selected upon a user gesture.
	*/
	static get eventSelect() {
		return `cds-custom-content-switcher-selected`;
	}
	render() {
		const { _handleHover: handleHover, _handleKeydown: handleKeydown, _handleSlotchange: handleSlotchange } = this;
		return html`
      <slot
        @click="${this._handleClick}"
        @keydown="${handleKeydown}"
        @mouseover="${handleHover}"
        @mouseout="${handleHover}"
        @slotchange=${handleSlotchange}></slot>
    `;
	}
	static {
		this.styles = content_switcher_default$1;
	}
};
__decorate([property({ reflect: true })], CDSContentSwitcher.prototype, "value", void 0);
__decorate([property({
	type: Number,
	attribute: "selected-index"
})], CDSContentSwitcher.prototype, "selectedIndex", void 0);
__decorate([property({ attribute: "selection-mode" })], CDSContentSwitcher.prototype, "selectionMode", void 0);
__decorate([property({ reflect: true })], CDSContentSwitcher.prototype, "size", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "icon"
})], CDSContentSwitcher.prototype, "iconOnly", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "low-contrast"
})], CDSContentSwitcher.prototype, "lowContrast", void 0);
CDSContentSwitcher = __decorate([carbonElement(`cds-custom-content-switcher`)], CDSContentSwitcher);
var content_switcher_default = CDSContentSwitcher;
//#endregion
export { CONTENT_SWITCHER_SIZE, NAVIGATION_DIRECTION, content_switcher_default as default };

//# sourceMappingURL=content-switcher.js.map