import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
import * as i0 from '@angular/core';
import { InjectionToken, inject, ElementRef, input, booleanAttribute, HostListener, HostBinding, Directive, contentChildren, output, INJECTOR, ChangeDetectorRef, DestroyRef, effect, signal, NgModule } from '@angular/core';

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
const AUTOCOMPLETE_LISTBOX = new InjectionToken('si-autocomplete-listbox');

class SiAutocompleteOptionDirective {
    static idCounter = 0;
    element = inject(ElementRef);
    parent = inject(AUTOCOMPLETE_LISTBOX);
    /**
     * @defaultValue
     * ```
     * `__si-autocomplete-option-${SiAutocompleteOptionDirective.idCounter++}`
     * ```
     */
    id = input(`__si-autocomplete-option-${SiAutocompleteOptionDirective.idCounter++}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
    /** @defaultValue false */
    // eslint-disable-next-line @angular-eslint/no-input-rename
    disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : {}), alias: 'disabled', transform: booleanAttribute });
    get disabled() {
        return this.disabledInput();
    }
    /** @defaultValue undefined */
    value = input(undefined, { ...(ngDevMode ? { debugName: "value" } : {}), alias: 'siAutocompleteOption' });
    active;
    click() {
        this.parent.siAutocompleteOptionSubmitted.emit(this.value());
    }
    /** @internal */
    setActiveStyles() {
        this.active = true;
        this.element.nativeElement.scrollIntoView({ block: 'nearest' });
    }
    /** @internal */
    setInactiveStyles() {
        this.active = false;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteOptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiAutocompleteOptionDirective, isStandalone: true, selector: "[siAutocompleteOption]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "siAutocompleteOption", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, listeners: { "click": "click()" }, properties: { "id": "id()", "attr.aria-disabled": "disabledInput()", "class.active": "this.active" } }, exportAs: ["siAutocompleteOption"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteOptionDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[siAutocompleteOption]',
                    host: {
                        role: 'option',
                        '[id]': 'id()',
                        '[attr.aria-disabled]': 'disabledInput()'
                    },
                    exportAs: 'siAutocompleteOption'
                }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "siAutocompleteOption", required: false }] }], active: [{
                type: HostBinding,
                args: ['class.active']
            }], click: [{
                type: HostListener,
                args: ['click']
            }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
class SiAutocompleteListboxDirective {
    static idCounter = 0;
    options = contentChildren(SiAutocompleteOptionDirective, { ...(ngDevMode ? { debugName: "options" } : {}), descendants: true });
    /**
     * @defaultValue
     * ```
     * `__si-autocomplete-listbox-${SiAutocompleteListboxDirective.idCounter++}`
     * ```
     */
    id = input(`__si-autocomplete-listbox-${SiAutocompleteListboxDirective.idCounter++}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
    autocomplete = input.required({ ...(ngDevMode ? { debugName: "autocomplete" } : {}), alias: 'siAutocompleteListboxFor' });
    /** @defaultValue 0 */
    siAutocompleteDefaultIndex = input(0, ...(ngDevMode ? [{ debugName: "siAutocompleteDefaultIndex" }] : []));
    siAutocompleteOptionSubmitted = output();
    injector = inject(INJECTOR);
    keyManager = new ActiveDescendantKeyManager(this.options, this.injector)
        .withWrap(true)
        .withVerticalOrientation(true);
    changeDetectorRef = inject(ChangeDetectorRef);
    destroyRef = inject(DestroyRef);
    constructor() {
        effect(() => {
            if (this.siAutocompleteDefaultIndex() >= 0 && !this.keyManager.activeItem) {
                this.setActiveItem();
            }
        });
        effect(() => {
            if (this.options()) {
                this.setActiveItem();
            }
        });
    }
    ngOnInit() {
        // For some reason, this is needed sometimes. Otherwise, one may get ExpressionChangedAfterItHasBeenCheckedError.
        queueMicrotask(() => {
            this.changeDetectorRef.markForCheck();
            this.autocomplete().listbox.set(this);
        });
        this.destroyRef.onDestroy(() => {
            this.autocomplete().listbox.set(undefined);
        });
    }
    setActiveItem() {
        queueMicrotask(() => {
            this.keyManager.setActiveItem(this.siAutocompleteDefaultIndex());
            this.changeDetectorRef.markForCheck();
        });
    }
    /** @internal */
    onKeydown(event) {
        if (event.ctrlKey && event.key === 'Enter') {
            // [ctrl + enter] should submit and not select an option.
            // Mainly needed for filtered-search.
            return;
        }
        this.keyManager.onKeydown(event);
        if (event.key === 'Enter' && this.keyManager.activeItem) {
            this.siAutocompleteOptionSubmitted.emit(this.keyManager.activeItem.value());
            // Something was selected. This should prevent everything else from happening, especially submitting the form.
            event.stopImmediatePropagation();
        }
        this.changeDetectorRef.markForCheck();
    }
    get active() {
        // NOTE: We must not return `this.keyManager.activeItem` here, because its not updating
        // activeItem reference when options change.
        if (this.keyManager.activeItemIndex === null) {
            return null;
        }
        return this.options().at(this.keyManager.activeItemIndex) ?? null;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteListboxDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.0.8", type: SiAutocompleteListboxDirective, isStandalone: true, selector: "[siAutocompleteListboxFor]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "siAutocompleteListboxFor", isSignal: true, isRequired: true, transformFunction: null }, siAutocompleteDefaultIndex: { classPropertyName: "siAutocompleteDefaultIndex", publicName: "siAutocompleteDefaultIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { siAutocompleteOptionSubmitted: "siAutocompleteOptionSubmitted" }, host: { attributes: { "role": "listbox" }, properties: { "id": "id()" } }, providers: [{ provide: AUTOCOMPLETE_LISTBOX, useExisting: SiAutocompleteListboxDirective }], queries: [{ propertyName: "options", predicate: SiAutocompleteOptionDirective, descendants: true, isSignal: true }], exportAs: ["siAutocompleteListbox"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteListboxDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[siAutocompleteListboxFor]',
                    providers: [{ provide: AUTOCOMPLETE_LISTBOX, useExisting: SiAutocompleteListboxDirective }],
                    host: {
                        role: 'listbox',
                        '[id]': 'id()'
                    },
                    exportAs: 'siAutocompleteListbox'
                }]
        }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SiAutocompleteOptionDirective), { ...{ descendants: true }, isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "siAutocompleteListboxFor", required: true }] }], siAutocompleteDefaultIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "siAutocompleteDefaultIndex", required: false }] }], siAutocompleteOptionSubmitted: [{ type: i0.Output, args: ["siAutocompleteOptionSubmitted"] }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
class SiAutocompleteDirective {
    /** @internal */
    listbox = signal(undefined, ...(ngDevMode ? [{ debugName: "listbox" }] : []));
    get activeDescendant() {
        return this.listbox()?.active?.id() ?? '';
    }
    keydown(event) {
        this.listbox()?.onKeydown(event);
    }
    get active() {
        return this.listbox()?.active;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.8", type: SiAutocompleteDirective, isStandalone: true, selector: "input[siAutocomplete]", host: { attributes: { "role": "combobox", "aria-autocomplete": "list" }, listeners: { "keydown": "keydown($event)" }, properties: { "attr.aria-activedescendant": "activeDescendant", "attr.aria-controls": "listbox()?.id()", "attr.aria-expanded": "!!listbox()" } }, exportAs: ["siAutocomplete"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[siAutocomplete]',
                    host: {
                        role: 'combobox',
                        'aria-autocomplete': 'list',
                        '[attr.aria-activedescendant]': 'activeDescendant',
                        '[attr.aria-controls]': 'listbox()?.id()',
                        '[attr.aria-expanded]': '!!listbox()'
                    },
                    exportAs: 'siAutocomplete'
                }]
        }], propDecorators: { keydown: [{
                type: HostListener,
                args: ['keydown', ['$event']]
            }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
class SiAutocompleteModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteModule, imports: [SiAutocompleteDirective, SiAutocompleteListboxDirective, SiAutocompleteOptionDirective], exports: [SiAutocompleteDirective, SiAutocompleteListboxDirective, SiAutocompleteOptionDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAutocompleteModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SiAutocompleteDirective, SiAutocompleteListboxDirective, SiAutocompleteOptionDirective],
                    declarations: [],
                    exports: [SiAutocompleteDirective, SiAutocompleteListboxDirective, SiAutocompleteOptionDirective]
                }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */

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

export { SiAutocompleteDirective, SiAutocompleteListboxDirective, SiAutocompleteModule, SiAutocompleteOptionDirective };
//# sourceMappingURL=siemens-element-ng-autocomplete.mjs.map
