import { ENTER, SPACE } from '@angular/cdk/keycodes';
import * as i0 from '@angular/core';
import { signal, inject, Renderer2, effect, forwardRef, booleanAttribute, HostListener, ContentChildren, Input, Host, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import * as i1 from '@fundamental-ngx/cdk/utils';
import { RtlService, destroyObservable, KeyUtil, FocusableItemDirective, FocusableListDirective } from '@fundamental-ngx/cdk/utils';
import { FD_BUTTON_COMPONENT } from '@fundamental-ngx/core/button';
import { FD_LANGUAGE, TranslationResolver } from '@fundamental-ngx/i18n';
import { Subject, merge, EMPTY, asyncScheduler, fromEvent } from 'rxjs';
import { startWith, observeOn, filter, tap, takeUntil } from 'rxjs/operators';

/**
 * Container for grouped buttons.
 *
 * ```html
 * <fd-segmented-button [(ngModel)]="value">
 *     <button fd-button value="first">Button</button>
 *     <button fd-button value="second">Button</button>
 *     <button fd-button value="third">Button</button>
 * </fd-segmented-button>
 * ```
 */
class SegmentedButtonComponent {
    /** @hidden */
    constructor(_changeDetRef, _elementRef, _destroyRef, _ngZone, _focusableList) {
        this._changeDetRef = _changeDetRef;
        this._elementRef = _elementRef;
        this._destroyRef = _destroyRef;
        this._ngZone = _ngZone;
        this._focusableList = _focusableList;
        /** Whether segmented button is on toggle mode, which allows to toggle more than 1 button */
        this.toggle = false;
        /**
         * Whether segmented button is on vertical mode,
         * which allows to display buttons vertically
         **/
        this.vertical = false;
        /** @hidden */
        this._focusedItemId = signal(null, ...(ngDevMode ? [{ debugName: "_focusedItemId" }] : []));
        /** @hidden */
        this._isDisabled = false;
        /** An RxJS Subject that will kill the data stream upon queryList changes (for unsubscribing)  */
        this._onRefresh$ = new Subject();
        /** @hidden */
        this._lang$ = inject(FD_LANGUAGE);
        /** @hidden */
        this._translationResolver = inject(TranslationResolver);
        /** @hidden */
        this.renderer = inject(Renderer2);
        /** @hidden */
        this._rtlService = inject(RtlService, { optional: true });
        /** @hidden */
        this.onChange = () => { };
        /** @hidden */
        this.onTouched = () => { };
        this._focusableList.navigationDirection.set(this.vertical ? 'vertical' : 'horizontal');
        effect(() => {
            this._focusableList.contentDirection.set(this._rtlService?.rtl() ? 'rtl' : 'ltr');
        });
        const itemFocusedSubscription = this._focusableList.itemFocused.subscribe((item) => {
            this._focusedItemId.set(item.id);
        });
        this._destroyRef.onDestroy(() => itemFocusedSubscription.unsubscribe());
    }
    /** @hidden */
    _click(event) {
        if (!this._elementRef.nativeElement.contains(event.relatedTarget)) {
            this.onTouched();
        }
    }
    /** @hidden */
    ngOnInit() {
        this._lang$.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((lang) => {
            this._groupRoleDescription = this._translationResolver.resolve(lang, 'segmentedButton.groupRoleDescription');
            this._buttonRoleDescription = this._translationResolver.resolve(lang, 'segmentedButton.buttonRoleDescription');
            this._updateButtonRoleDescriptions();
            this._changeDetRef.markForCheck();
        });
    }
    /** @hidden */
    ngAfterViewInit() {
        this._listenToButtonChanges();
    }
    /** @hidden */
    ngOnChanges(changes) {
        if (changes && changes.vertical) {
            this._focusableList.navigationDirection.set(this.vertical ? 'vertical' : 'horizontal');
        }
    }
    /** @hidden */
    ngOnDestroy() {
        this._onRefresh$.complete();
        this._buttons = null;
        this._focusableItems = null;
    }
    /** @hidden */
    writeValue(values) {
        this._currentValue = values;
        this._pickButtonsByValues(values);
    }
    /**
     * @hidden
     * @param fn User defined function that handles the *onChange* event of the SegmentedButtons.
     */
    registerOnChange(fn) {
        this.onChange = fn;
    }
    /**
     * @hidden
     * @param fn User defined function that handles the *onTouch* event of the SegmentedButtons.
     */
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    /**
     * @hidden
     * @param isDisabled Sets the value of the *disabled* property of the SegmentedButtons.
     */
    setDisabledState(isDisabled) {
        this._isDisabled = isDisabled;
        this._toggleDisableButtons(isDisabled);
        this._onRefresh$.next();
        if (!isDisabled) {
            this._ngZone.run(() => {
                if (this._buttons) {
                    this._listenToButtonChanges();
                    this._pickButtonsByValues(this._currentValue);
                }
            });
        }
        this._changeDetRef.detectChanges();
    }
    /** @hidden */
    _listenToButtonChanges() {
        if (!this._buttons || !this._focusableItems) {
            return;
        }
        this._onRefresh$.next();
        merge(this._buttons.changes ?? EMPTY, this._focusableItems.changes ?? EMPTY)
            .pipe(startWith(1), observeOn(asyncScheduler), takeUntilDestroyed(this._destroyRef))
            .subscribe(() => {
            if (!this._buttons || !this._focusableItems) {
                return;
            }
            this._toggleDisableButtons(this._isDisabled);
            this._pickButtonsByValues(this._currentValue);
            this._buttons.forEach((button, index) => {
                this._setButtonAttributes(button, index);
                this._listenToTriggerEvents(button);
            });
        });
    }
    /** @hidden */
    _listenToTriggerEvents(buttonComponent) {
        const htmlElement = buttonComponent.elementRef.nativeElement;
        const refresh$ = merge(destroyObservable(this._destroyRef), this._onRefresh$);
        const triggerEvents$ = merge(fromEvent(htmlElement, 'click'), fromEvent(htmlElement, 'keydown').pipe(filter((event) => KeyUtil.isKeyCode(event, [ENTER, SPACE])), tap((event) => {
            event.preventDefault();
            this.onTouched();
        })));
        triggerEvents$.pipe(takeUntil(refresh$)).subscribe(() => this._handleTriggerOnButton(buttonComponent));
    }
    /** @hidden */
    _setButtonAttributes(buttonComponent, index) {
        const el = buttonComponent.elementRef.nativeElement;
        this.renderer.setAttribute(el, 'role', 'option');
        this.renderer.setAttribute(el, 'aria-roledescription', this._buttonRoleDescription);
        this.renderer.setAttribute(el, 'aria-posinset', String(index + 1));
        this.renderer.setAttribute(el, 'aria-setsize', String(this._buttons.length));
    }
    _updateButtonRoleDescriptions() {
        if (!this._buttons) {
            return;
        }
        this._buttons.forEach((button) => {
            this.renderer.setAttribute(button.elementRef.nativeElement, 'aria-roledescription', this._buttonRoleDescription);
        });
    }
    /** @hidden */
    _handleTriggerOnButton(buttonComponent) {
        if (!this._isButtonDisabled(buttonComponent)) {
            if (!this.toggle) {
                this._buttons.forEach((button) => this._deselectButton(button));
                this._selectButton(buttonComponent);
                this._propagateChange();
                this._changeDetRef.markForCheck();
            }
            else {
                this._toggleButton(buttonComponent);
                this._propagateChange();
                this._changeDetRef.markForCheck();
            }
        }
    }
    /** @hidden */
    _propagateChange() {
        const selectedValue = this._getValuesBySelected();
        this.onChange(selectedValue);
        this._currentValue = selectedValue;
    }
    /** @hidden */
    _toggleButton(buttonComponent) {
        if (this._isButtonSelected(buttonComponent)) {
            this._deselectButton(buttonComponent);
        }
        else {
            this._selectButton(buttonComponent);
        }
    }
    /** @hidden */
    _pickButtonsByValues(values) {
        if (!this._buttons) {
            return;
        }
        this._buttons.forEach((button) => this._deselectButton(button));
        this._getButtonsByValues(values).forEach((button) => this._selectButton(button));
        this._changeDetRef.detectChanges();
    }
    /** @hidden */
    _getButtonsByValues(values) {
        if (!values) {
            return [];
        }
        if (Array.isArray(values)) {
            return this._buttons.filter((button) => !!values.find((value) => this._getButtonValue(button) === value));
        }
        else {
            return this._buttons.filter((button) => this._getButtonValue(button) === values);
        }
    }
    /** @hidden */
    _selectButton(buttonComponent) {
        buttonComponent.setSelected(true);
    }
    /** @hidden */
    _deselectButton(buttonComponent) {
        buttonComponent.setSelected(false);
    }
    /** @hidden */
    _isButtonSelected(buttonComponent) {
        return !!buttonComponent.isSelected();
    }
    /** @hidden */
    _isButtonDisabled(buttonComponent) {
        return buttonComponent.isDisabled() || buttonComponent.ariaDisabled();
    }
    /** @hidden */
    _toggleDisableButtons(disable) {
        if (!this._buttons || !this._focusableItems) {
            return;
        }
        this._buttons.forEach((button) => button.setDisabled(disable));
        this._focusableItems.forEach((focusableItemDirective) => {
            focusableItemDirective.setTabbable(!disable);
            focusableItemDirective.setFocusable(!disable);
        });
        if (disable) {
            this._buttons.forEach((button) => {
                button.elementRef.nativeElement.role = 'option';
                this._listenToTriggerEvents(button);
            });
        }
        this._changeDetRef.markForCheck();
    }
    /** @hidden */
    _getButtonValue(buttonComponent) {
        const element = buttonComponent.elementRef.nativeElement;
        if (element instanceof HTMLButtonElement) {
            return element.value;
        }
        return element.getAttribute('value');
    }
    /** @hidden
     * Returns values depending on selected state of buttons
     */
    _getValuesBySelected() {
        if (!this._buttons) {
            return [];
        }
        const resButtons = this._buttons
            .filter((button) => !!this._isButtonSelected(button))
            .map((button) => this._getButtonValue(button));
        if (!this.toggle) {
            return resButtons.length === 1 ? resButtons[0] : null;
        }
        else {
            return resButtons;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SegmentedButtonComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.DestroyRef }, { token: i0.NgZone }, { token: i1.FocusableListDirective, host: true }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.1.0", type: SegmentedButtonComponent, isStandalone: true, selector: "fd-segmented-button", inputs: { toggle: ["toggle", "toggle", booleanAttribute], vertical: ["vertical", "vertical", booleanAttribute] }, host: { attributes: { "role": "listbox" }, listeners: { "click": "_click($event)" }, properties: { "class.fd-segmented-button": "true", "class.fd-segmented-button--vertical": "vertical", "attr.aria-multiselectable": "toggle", "attr.aria-orientation": "vertical ? \"vertical\" : \"horizontal\"", "attr.aria-roledescription": "_groupRoleDescription", "attr.aria-activedescendant": "_focusedItemId()" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => SegmentedButtonComponent),
                multi: true
            }
        ], queries: [{ propertyName: "_buttons", predicate: FD_BUTTON_COMPONENT }, { propertyName: "_focusableItems", predicate: FocusableItemDirective }], usesOnChanges: true, hostDirectives: [{ directive: i1.FocusableListDirective }], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [".fd-segmented-button{border:0;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--sapTextColor);display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-family:var(--sapFontFamily);font-size:var(--sapFontSize);font-weight:400;forced-color-adjust:none;line-height:normal;margin-block:0;margin-inline:0;padding-block:0;padding-inline:0;position:relative;vertical-align:middle;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.fd-segmented-button:after,.fd-segmented-button:before{-webkit-box-sizing:inherit;box-sizing:inherit;font-size:inherit}.fd-segmented-button:before{background:var(--sapButton_Background);border-radius:var(--sapButton_BorderCornerRadius);-webkit-box-shadow:inset 0 0 0 var(--sapButton_BorderWidth) var(--fdButtonPrioritizedBorderColor,var(--sapButton_BorderColor));box-shadow:inset 0 0 0 var(--sapButton_BorderWidth) var(--fdButtonPrioritizedBorderColor,var(--sapButton_BorderColor));content:\"\";height:100%;left:0;position:absolute;top:0;width:100%}.fd-segmented-button button{margin-block:0;margin-inline:0;--fdButtonPrioritizedBorderColor:var(--fdButton_Split_Border_Color);--fdButtonPrioritizedBackgroundColor:var(--fdButton_Split_Background_Color)}.fd-segmented-button button.is-hover,.fd-segmented-button button:hover{z-index:1}.fd-segmented-button button:first-child{border-radius:var(--fdButton_Border_Radius_Left)}.fd-segmented-button button:not(:first-child,:last-child){border-radius:var(--sapButton_Segment_BorderCornerRadius)}.fd-segmented-button button:last-child{border-radius:var(--fdButton_Border_Radius_Right)}.fd-segmented-button button:not(:last-child){-webkit-margin-end:var(--fdButton_Segmented_Border_Offset);margin-inline-end:var(--fdButton_Segmented_Border_Offset)}.fd-segmented-button:not(.fd-segmented-button--vertical) button[dir=rtl]:first-child,[dir=rtl] .fd-segmented-button:not(.fd-segmented-button--vertical) button:first-child{border-radius:var(--fdButton_Border_Radius_Left_RTL)}.fd-segmented-button:not(.fd-segmented-button--vertical) button[dir=rtl]:last-child,[dir=rtl] .fd-segmented-button:not(.fd-segmented-button--vertical) button:last-child{border-radius:var(--fdButton_Border_Radius_Right_RTL)}.fd-segmented-button--vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.fd-segmented-button--vertical button:first-child{border-radius:var(--fdButton_Vertical_Border_Radius_Left)}.fd-segmented-button--vertical button:last-child{border-radius:var(--fdButton_Vertical_Border_Radius_Right)}.fd-segmented-button--vertical button:not(:last-child){-webkit-margin-end:0;margin-inline-end:0;-webkit-margin-after:var(--fdButton_Segmented_Border_Offset);margin-block-end:var(--fdButton_Segmented_Border_Offset)}.fd-button.is-disabled.is-selected,.fd-button.is-disabled[aria-selected=true],.fd-button:disabled.is-selected,.fd-button:disabled[aria-selected=true],.fd-button[aria-disabled=true].is-selected,.fd-button[aria-disabled=true][aria-selected=true]{--fdButtonBorderColor: var(--sapButton_Selected_BorderColor);--fdButtonBackgroundColor: var(--sapButton_Selected_Background)}\n/*! Bundled license information:\n\nfundamental-styles/dist/segmented-button.css:\n  (*!\n   * Fundamental Library Styles v0.40.1\n   * Copyright (c) 2025 SAP SE or an SAP affiliate company.\n   * Licensed under Apache License 2.0 (https://github.com/SAP/fundamental-styles/blob/main/LICENSE)\n   *)\n*/\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SegmentedButtonComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fd-segmented-button', template: `<ng-content></ng-content>`, host: {
                        role: 'listbox',
                        '[class.fd-segmented-button]': 'true',
                        '[class.fd-segmented-button--vertical]': 'vertical',
                        '[attr.aria-multiselectable]': 'toggle',
                        '[attr.aria-orientation]': 'vertical ? "vertical" : "horizontal"',
                        '[attr.aria-roledescription]': '_groupRoleDescription',
                        '[attr.aria-activedescendant]': '_focusedItemId()'
                    }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => SegmentedButtonComponent),
                            multi: true
                        }
                    ], hostDirectives: [FocusableListDirective], styles: [".fd-segmented-button{border:0;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--sapTextColor);display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-family:var(--sapFontFamily);font-size:var(--sapFontSize);font-weight:400;forced-color-adjust:none;line-height:normal;margin-block:0;margin-inline:0;padding-block:0;padding-inline:0;position:relative;vertical-align:middle;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.fd-segmented-button:after,.fd-segmented-button:before{-webkit-box-sizing:inherit;box-sizing:inherit;font-size:inherit}.fd-segmented-button:before{background:var(--sapButton_Background);border-radius:var(--sapButton_BorderCornerRadius);-webkit-box-shadow:inset 0 0 0 var(--sapButton_BorderWidth) var(--fdButtonPrioritizedBorderColor,var(--sapButton_BorderColor));box-shadow:inset 0 0 0 var(--sapButton_BorderWidth) var(--fdButtonPrioritizedBorderColor,var(--sapButton_BorderColor));content:\"\";height:100%;left:0;position:absolute;top:0;width:100%}.fd-segmented-button button{margin-block:0;margin-inline:0;--fdButtonPrioritizedBorderColor:var(--fdButton_Split_Border_Color);--fdButtonPrioritizedBackgroundColor:var(--fdButton_Split_Background_Color)}.fd-segmented-button button.is-hover,.fd-segmented-button button:hover{z-index:1}.fd-segmented-button button:first-child{border-radius:var(--fdButton_Border_Radius_Left)}.fd-segmented-button button:not(:first-child,:last-child){border-radius:var(--sapButton_Segment_BorderCornerRadius)}.fd-segmented-button button:last-child{border-radius:var(--fdButton_Border_Radius_Right)}.fd-segmented-button button:not(:last-child){-webkit-margin-end:var(--fdButton_Segmented_Border_Offset);margin-inline-end:var(--fdButton_Segmented_Border_Offset)}.fd-segmented-button:not(.fd-segmented-button--vertical) button[dir=rtl]:first-child,[dir=rtl] .fd-segmented-button:not(.fd-segmented-button--vertical) button:first-child{border-radius:var(--fdButton_Border_Radius_Left_RTL)}.fd-segmented-button:not(.fd-segmented-button--vertical) button[dir=rtl]:last-child,[dir=rtl] .fd-segmented-button:not(.fd-segmented-button--vertical) button:last-child{border-radius:var(--fdButton_Border_Radius_Right_RTL)}.fd-segmented-button--vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.fd-segmented-button--vertical button:first-child{border-radius:var(--fdButton_Vertical_Border_Radius_Left)}.fd-segmented-button--vertical button:last-child{border-radius:var(--fdButton_Vertical_Border_Radius_Right)}.fd-segmented-button--vertical button:not(:last-child){-webkit-margin-end:0;margin-inline-end:0;-webkit-margin-after:var(--fdButton_Segmented_Border_Offset);margin-block-end:var(--fdButton_Segmented_Border_Offset)}.fd-button.is-disabled.is-selected,.fd-button.is-disabled[aria-selected=true],.fd-button:disabled.is-selected,.fd-button:disabled[aria-selected=true],.fd-button[aria-disabled=true].is-selected,.fd-button[aria-disabled=true][aria-selected=true]{--fdButtonBorderColor: var(--sapButton_Selected_BorderColor);--fdButtonBackgroundColor: var(--sapButton_Selected_Background)}\n/*! Bundled license information:\n\nfundamental-styles/dist/segmented-button.css:\n  (*!\n   * Fundamental Library Styles v0.40.1\n   * Copyright (c) 2025 SAP SE or an SAP affiliate company.\n   * Licensed under Apache License 2.0 (https://github.com/SAP/fundamental-styles/blob/main/LICENSE)\n   *)\n*/\n"] }]
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.DestroyRef }, { type: i0.NgZone }, { type: i1.FocusableListDirective, decorators: [{
                    type: Host
                }] }], propDecorators: { toggle: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], vertical: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], _buttons: [{
                type: ContentChildren,
                args: [FD_BUTTON_COMPONENT]
            }], _focusableItems: [{
                type: ContentChildren,
                args: [FocusableItemDirective]
            }], _click: [{
                type: HostListener,
                args: ['click', ['$event']]
            }] } });

/**
 * @deprecated
 * Use direct `SegmentedButtonComponent` import instead.
 */
class SegmentedButtonModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SegmentedButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: SegmentedButtonModule, imports: [SegmentedButtonComponent], exports: [SegmentedButtonComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SegmentedButtonModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SegmentedButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SegmentedButtonComponent],
                    exports: [SegmentedButtonComponent]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { SegmentedButtonComponent, SegmentedButtonModule };
//# sourceMappingURL=fundamental-ngx-core-segmented-button.mjs.map
