import { LoaderComponent } from '@agorapulse/ui-animations';
import { AvatarComponent } from '@agorapulse/ui-components/avatar';
import { FormFieldComponent } from '@agorapulse/ui-components/form-field';
import { InputDirective } from '@agorapulse/ui-components/input';
import { InputGroupComponent } from '@agorapulse/ui-components/input-group';
import { SymbolRegistry, apSearch, SymbolComponent } from '@agorapulse/ui-symbol';
import * as i2 from '@angular/cdk/overlay';
import { OverlayModule } from '@angular/cdk/overlay';
import * as i0 from '@angular/core';
import { EventEmitter, signal, inject, NgZone, ElementRef, Output, ViewChild, Input, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { BehaviorSubject, skip, debounceTime, distinctUntilChanged, tap, filter, switchMap, fromEvent } from 'rxjs';
import { NgTemplateOutlet } from '@angular/common';

class AutocompleteComponent {
    placeholder = 'Search...';
    label = '';
    inputId = '';
    loadingText = 'Loading Items';
    notFoundText = 'No result found';
    searchFn;
    trackByFn = (_, item) => item;
    set disabled(value) {
        this.disabledSignal.set(value);
    }
    optionLabel;
    optionCaption;
    optionImageUrl;
    optionValue;
    optionTextTemplate;
    formField;
    selectOption = new EventEmitter();
    disabledSignal = signal(false, ...(ngDevMode ? [{ debugName: "disabledSignal" }] : /* istanbul ignore next */ []));
    symbolRegistry = inject(SymbolRegistry);
    searchTerm$ = new BehaviorSubject('');
    searchTermSignal = toSignal(this.searchTerm$);
    showResultsSignal = signal(false, ...(ngDevMode ? [{ debugName: "showResultsSignal" }] : /* istanbul ignore next */ []));
    resultsLoadingSignal = signal(false, ...(ngDevMode ? [{ debugName: "resultsLoadingSignal" }] : /* istanbul ignore next */ []));
    searchResultsSignal = toSignal(this.searchTerm$.pipe(skip(1), debounceTime(250), distinctUntilChanged(), tap(() => this.showResultsSignal.set(false)), filter(term => term.length > 0), tap(() => this.showResultsSignal.set(true)), tap(() => this.resultsLoadingSignal.set(true)), switchMap(term => {
        return this.searchFn(term);
    }), tap(() => this.resultsLoadingSignal.set(false))));
    ngZone = inject(NgZone);
    el = inject(ElementRef);
    inputWidthSignal = signal(0, ...(ngDevMode ? [{ debugName: "inputWidthSignal" }] : /* istanbul ignore next */ []));
    constructor() {
        this.symbolRegistry.registerSymbols([apSearch]);
        this.ngZone.runOutsideAngular(() => {
            fromEvent(document, 'click')
                .pipe(takeUntilDestroyed())
                .subscribe(e => {
                const clickedInside = this.el.nativeElement.contains(e.target);
                if (!clickedInside) {
                    this.ngZone.run(() => {
                        this.resetAutocomplete();
                    });
                }
            });
        });
    }
    ngAfterViewInit() {
        this.inputWidthSignal.set(this.formField.nativeElement.offsetWidth);
    }
    onSelectOption(option) {
        if (typeof option !== 'string' && this.optionValue && option[this.optionValue]) {
            this.selectOption.emit(option[this.optionValue]);
        }
        else {
            this.selectOption.emit(option);
        }
        this.resetAutocomplete();
    }
    resetAutocomplete() {
        this.searchTerm$.next('');
        this.showResultsSignal.set(false);
        this.resultsLoadingSignal.set(false);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: AutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: AutocompleteComponent, isStandalone: true, selector: "ap-autocomplete", inputs: { placeholder: "placeholder", label: "label", inputId: "inputId", loadingText: "loadingText", notFoundText: "notFoundText", searchFn: "searchFn", trackByFn: "trackByFn", disabled: "disabled", optionLabel: "optionLabel", optionCaption: "optionCaption", optionImageUrl: "optionImageUrl", optionValue: "optionValue", optionTextTemplate: "optionTextTemplate" }, outputs: { selectOption: "selectOption" }, viewQueries: [{ propertyName: "formField", first: true, predicate: ["formField"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"input-autocomplete-wrapper\">\n    <ap-form-field\n        #formField\n        #trigger=\"cdkOverlayOrigin\"\n        cdkOverlayOrigin>\n        <label [for]=\"inputId\">\n            {{ label }}\n        </label>\n        <ap-input-group>\n            <ap-symbol symbolId=\"search\" />\n            <input\n                apInput\n                [id]=\"inputId\"\n                [disabled]=\"disabledSignal()\"\n                [placeholder]=\"placeholder\"\n                [ngModel]=\"searchTermSignal()\"\n                (ngModelChange)=\"searchTerm$.next($event)\" />\n        </ap-input-group>\n    </ap-form-field>\n    <div class=\"search-results-wrapper\">\n        <ng-template\n            cdkConnectedOverlay\n            [cdkConnectedOverlayOrigin]=\"trigger\"\n            [cdkConnectedOverlayWidth]=\"inputWidthSignal()\"\n            [cdkConnectedOverlayOpen]=\"showResultsSignal()\">\n            <div class=\"ap-autocomplete-search-results\">\n                @if (resultsLoadingSignal()) {\n                    <div class=\"ap-autocomplete-search-results-loading\">\n                        <ap-loader [diameter]=\"30\" />\n                        <span class=\"search-results-loading-label\">{{ loadingText }}</span>\n                    </div>\n                } @else {\n                    @if (searchResultsSignal()?.length) {\n                        @for (option of searchResultsSignal(); track trackByFn($index, option)) {\n                            <div\n                                class=\"ap-autocomplete-search-results-item\"\n                                tabindex=\"0\"\n                                (keydown.enter)=\"onSelectOption(option)\"\n                                (click)=\"onSelectOption(option)\">\n                                @if (!optionTextTemplate) {\n                                    @if (!optionLabel || !option[optionLabel]) {\n                                        <div class=\"option\">\n                                            <span\n                                                class=\"option-item\"\n                                                [title]=\"option\">\n                                                {{ option }}\n                                            </span>\n                                        </div>\n                                    }\n                                    @if (optionLabel && option[optionLabel]) {\n                                        <div\n                                            class=\"option\"\n                                            [class.with-caption]=\"optionLabel && optionCaption && option[optionCaption]\">\n                                            @if (!optionLabel) {\n                                                <span class=\"item\">\n                                                    {{ option }}\n                                                </span>\n                                            }\n                                            @if (optionImageUrl) {\n                                                <ap-avatar\n                                                    [size]=\"24\"\n                                                    [showInitials]=\"true\"\n                                                    [username]=\"optionLabel ? option[optionLabel] : option\"\n                                                    [profilePicture]=\"option[optionImageUrl]\" />\n                                            }\n                                            @if (optionLabel && option[optionLabel]) {\n                                                <div class=\"texts\">\n                                                    <div class=\"first-line\">\n                                                        <span\n                                                            class=\"label\"\n                                                            [title]=\"option[optionLabel]\">\n                                                            {{ option[optionLabel] }}\n                                                        </span>\n                                                    </div>\n                                                    @if (optionCaption && option[optionCaption]) {\n                                                        <span\n                                                            class=\"caption\"\n                                                            [title]=\"option[optionCaption]\">\n                                                            {{ option[optionCaption] }}\n                                                        </span>\n                                                    }\n                                                </div>\n                                            }\n                                        </div>\n                                    }\n                                } @else {\n                                    <ng-container [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\" />\n                                }\n                            </div>\n                        }\n                    } @else {\n                        <div class=\"ap-autocomplete-search-results-not-found\">\n                            {{ notFoundText }}\n                        </div>\n                    }\n                }\n            </div>\n        </ng-template>\n    </div>\n</div>\n", styles: ["ap-autocomplete{display:block}ap-autocomplete .input-autocomplete-wrapper{display:flex;flex-direction:column}ap-autocomplete .search-results-wrapper{position:relative}.ap-autocomplete-search-results{width:100%;display:flex;flex-direction:column;border-radius:var(--ref-border-radius-sm);box-shadow:var(--comp-select-shadow);padding:var(--comp-select-padding-vertical) 0;background-color:var(--comp-select-background-color);margin-top:var(--ref-spacing-xxxs);max-height:250px;overflow:auto}.ap-autocomplete-search-results-loading{display:flex;padding:var(--ref-spacing-sm) 0;flex-direction:column;justify-content:center;align-items:center;gap:var(--ref-spacing-xs)}.ap-autocomplete-search-results-loading .search-results-loading-label{font-style:italic;font-size:var(--ref-font-size-sm);color:var(--ref-color-grey-80)}.ap-autocomplete-search-results-not-found{padding:var(--ref-spacing-xs) var(--ref-spacing-sm);font-style:italic;font-size:var(--ref-font-size-sm);color:var(--ref-color-grey-80);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ap-autocomplete-search-results-item{padding:var(--ref-spacing-xxs) var(--ref-spacing-sm)}.ap-autocomplete-search-results-item .option{display:flex;align-items:center;font-size:var(--comp-select-one-line-text-size);font-weight:var(--comp-select-one-line-text-font-weight);color:var(--comp-select-one-line-text-color);line-height:var(--comp-select-one-line-text-line-height);font-family:var(--comp-select-one-line-text-font-family);gap:var(--ref-spacing-xs);min-height:24px}.ap-autocomplete-search-results-item .option .option-item{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ap-autocomplete-search-results-item .option .texts{flex:1;overflow:auto}.ap-autocomplete-search-results-item .option .texts .first-line{display:flex}.ap-autocomplete-search-results-item .option .texts .label{display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%}.ap-autocomplete-search-results-item .option.with-caption .texts{display:flex;flex-direction:column}.ap-autocomplete-search-results-item .option.with-caption .texts .label{color:var(--comp-select-two-line-title-text-color);font-size:var(--comp-select-two-line-title-text-size);line-height:var(--comp-select-two-line-title-text-line-height);font-weight:var(--comp-select-two-line-title-text-font-weight)}.ap-autocomplete-search-results-item .option.with-caption .texts .caption{color:var(--comp-select-two-line-caption-text-color);font-size:var(--comp-select-two-line-caption-text-size);line-height:var(--comp-select-two-line-caption-text-line-height);font-weight:var(--comp-select-two-line-caption-text-font-weight);display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%}.ap-autocomplete-search-results-item:hover{cursor:pointer;background-color:var(--ref-color-electric-blue-10)}.ap-autocomplete-search-results-item:active{background-color:var(--ref-color-electric-blue-20)}.ap-autocomplete-search-results-item:focus{background-color:var(--ref-color-electric-blue-20)}\n"], dependencies: [{ kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "component", type: FormFieldComponent, selector: "ap-form-field" }, { kind: "component", type: InputGroupComponent, selector: "ap-input-group", inputs: ["symbolPosition"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LoaderComponent, selector: "ap-loader", inputs: ["color", "diameter"] }, { kind: "directive", type: InputDirective, selector: "[apInput]" }, { kind: "component", type: AvatarComponent, selector: "ap-avatar", inputs: ["profilePicture", "alt", "network", "size", "username", "showInitials", "bigNetwork", "anonymous", "online", "youtubeAvatarMode", "rounded"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: AutocompleteComponent, decorators: [{
            type: Component,
            args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ap-autocomplete', imports: [
                        SymbolComponent,
                        FormFieldComponent,
                        InputGroupComponent,
                        FormsModule,
                        LoaderComponent,
                        InputDirective,
                        AvatarComponent,
                        OverlayModule,
                        NgTemplateOutlet
                    ], encapsulation: ViewEncapsulation.None, template: "<div class=\"input-autocomplete-wrapper\">\n    <ap-form-field\n        #formField\n        #trigger=\"cdkOverlayOrigin\"\n        cdkOverlayOrigin>\n        <label [for]=\"inputId\">\n            {{ label }}\n        </label>\n        <ap-input-group>\n            <ap-symbol symbolId=\"search\" />\n            <input\n                apInput\n                [id]=\"inputId\"\n                [disabled]=\"disabledSignal()\"\n                [placeholder]=\"placeholder\"\n                [ngModel]=\"searchTermSignal()\"\n                (ngModelChange)=\"searchTerm$.next($event)\" />\n        </ap-input-group>\n    </ap-form-field>\n    <div class=\"search-results-wrapper\">\n        <ng-template\n            cdkConnectedOverlay\n            [cdkConnectedOverlayOrigin]=\"trigger\"\n            [cdkConnectedOverlayWidth]=\"inputWidthSignal()\"\n            [cdkConnectedOverlayOpen]=\"showResultsSignal()\">\n            <div class=\"ap-autocomplete-search-results\">\n                @if (resultsLoadingSignal()) {\n                    <div class=\"ap-autocomplete-search-results-loading\">\n                        <ap-loader [diameter]=\"30\" />\n                        <span class=\"search-results-loading-label\">{{ loadingText }}</span>\n                    </div>\n                } @else {\n                    @if (searchResultsSignal()?.length) {\n                        @for (option of searchResultsSignal(); track trackByFn($index, option)) {\n                            <div\n                                class=\"ap-autocomplete-search-results-item\"\n                                tabindex=\"0\"\n                                (keydown.enter)=\"onSelectOption(option)\"\n                                (click)=\"onSelectOption(option)\">\n                                @if (!optionTextTemplate) {\n                                    @if (!optionLabel || !option[optionLabel]) {\n                                        <div class=\"option\">\n                                            <span\n                                                class=\"option-item\"\n                                                [title]=\"option\">\n                                                {{ option }}\n                                            </span>\n                                        </div>\n                                    }\n                                    @if (optionLabel && option[optionLabel]) {\n                                        <div\n                                            class=\"option\"\n                                            [class.with-caption]=\"optionLabel && optionCaption && option[optionCaption]\">\n                                            @if (!optionLabel) {\n                                                <span class=\"item\">\n                                                    {{ option }}\n                                                </span>\n                                            }\n                                            @if (optionImageUrl) {\n                                                <ap-avatar\n                                                    [size]=\"24\"\n                                                    [showInitials]=\"true\"\n                                                    [username]=\"optionLabel ? option[optionLabel] : option\"\n                                                    [profilePicture]=\"option[optionImageUrl]\" />\n                                            }\n                                            @if (optionLabel && option[optionLabel]) {\n                                                <div class=\"texts\">\n                                                    <div class=\"first-line\">\n                                                        <span\n                                                            class=\"label\"\n                                                            [title]=\"option[optionLabel]\">\n                                                            {{ option[optionLabel] }}\n                                                        </span>\n                                                    </div>\n                                                    @if (optionCaption && option[optionCaption]) {\n                                                        <span\n                                                            class=\"caption\"\n                                                            [title]=\"option[optionCaption]\">\n                                                            {{ option[optionCaption] }}\n                                                        </span>\n                                                    }\n                                                </div>\n                                            }\n                                        </div>\n                                    }\n                                } @else {\n                                    <ng-container [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\" />\n                                }\n                            </div>\n                        }\n                    } @else {\n                        <div class=\"ap-autocomplete-search-results-not-found\">\n                            {{ notFoundText }}\n                        </div>\n                    }\n                }\n            </div>\n        </ng-template>\n    </div>\n</div>\n", styles: ["ap-autocomplete{display:block}ap-autocomplete .input-autocomplete-wrapper{display:flex;flex-direction:column}ap-autocomplete .search-results-wrapper{position:relative}.ap-autocomplete-search-results{width:100%;display:flex;flex-direction:column;border-radius:var(--ref-border-radius-sm);box-shadow:var(--comp-select-shadow);padding:var(--comp-select-padding-vertical) 0;background-color:var(--comp-select-background-color);margin-top:var(--ref-spacing-xxxs);max-height:250px;overflow:auto}.ap-autocomplete-search-results-loading{display:flex;padding:var(--ref-spacing-sm) 0;flex-direction:column;justify-content:center;align-items:center;gap:var(--ref-spacing-xs)}.ap-autocomplete-search-results-loading .search-results-loading-label{font-style:italic;font-size:var(--ref-font-size-sm);color:var(--ref-color-grey-80)}.ap-autocomplete-search-results-not-found{padding:var(--ref-spacing-xs) var(--ref-spacing-sm);font-style:italic;font-size:var(--ref-font-size-sm);color:var(--ref-color-grey-80);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ap-autocomplete-search-results-item{padding:var(--ref-spacing-xxs) var(--ref-spacing-sm)}.ap-autocomplete-search-results-item .option{display:flex;align-items:center;font-size:var(--comp-select-one-line-text-size);font-weight:var(--comp-select-one-line-text-font-weight);color:var(--comp-select-one-line-text-color);line-height:var(--comp-select-one-line-text-line-height);font-family:var(--comp-select-one-line-text-font-family);gap:var(--ref-spacing-xs);min-height:24px}.ap-autocomplete-search-results-item .option .option-item{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ap-autocomplete-search-results-item .option .texts{flex:1;overflow:auto}.ap-autocomplete-search-results-item .option .texts .first-line{display:flex}.ap-autocomplete-search-results-item .option .texts .label{display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%}.ap-autocomplete-search-results-item .option.with-caption .texts{display:flex;flex-direction:column}.ap-autocomplete-search-results-item .option.with-caption .texts .label{color:var(--comp-select-two-line-title-text-color);font-size:var(--comp-select-two-line-title-text-size);line-height:var(--comp-select-two-line-title-text-line-height);font-weight:var(--comp-select-two-line-title-text-font-weight)}.ap-autocomplete-search-results-item .option.with-caption .texts .caption{color:var(--comp-select-two-line-caption-text-color);font-size:var(--comp-select-two-line-caption-text-size);line-height:var(--comp-select-two-line-caption-text-line-height);font-weight:var(--comp-select-two-line-caption-text-font-weight);display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%}.ap-autocomplete-search-results-item:hover{cursor:pointer;background-color:var(--ref-color-electric-blue-10)}.ap-autocomplete-search-results-item:active{background-color:var(--ref-color-electric-blue-20)}.ap-autocomplete-search-results-item:focus{background-color:var(--ref-color-electric-blue-20)}\n"] }]
        }], ctorParameters: () => [], propDecorators: { placeholder: [{
                type: Input
            }], label: [{
                type: Input
            }], inputId: [{
                type: Input
            }], loadingText: [{
                type: Input
            }], notFoundText: [{
                type: Input
            }], searchFn: [{
                type: Input,
                args: [{ required: true }]
            }], trackByFn: [{
                type: Input
            }], disabled: [{
                type: Input
            }], optionLabel: [{
                type: Input
            }], optionCaption: [{
                type: Input
            }], optionImageUrl: [{
                type: Input
            }], optionValue: [{
                type: Input
            }], optionTextTemplate: [{
                type: Input
            }], formField: [{
                type: ViewChild,
                args: ['formField', { read: ElementRef }]
            }], selectOption: [{
                type: Output
            }] } });

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

export { AutocompleteComponent };
//# sourceMappingURL=agorapulse-ui-components-autocomplete.mjs.map
