import { __metadata, __decorate } from 'tslib';
import * as i0 from '@angular/core';
import { EventEmitter, Directive, Input, Output, ViewChild, HostBinding, HostListener } from '@angular/core';
import { isNullOrUndefined } from '@ironsource/fusion-ui/utils';
import { FormControl } from '@angular/forms';
import { Subject, BehaviorSubject } from 'rxjs';
import * as i2 from '@ironsource/fusion-ui/services/unique-id';
import * as i4 from '@ironsource/fusion-ui/pipes/clone';
import { takeUntil, debounceTime, distinctUntilChanged, map, take, switchMapTo } from 'rxjs/operators';
import * as i3 from '@ironsource/fusion-ui/pipes/collection';
import { detectChangesDecorator } from '@ironsource/fusion-ui/decorators';
import * as i5 from '@ironsource/fusion-ui/services/events-handler';
import * as i1 from '@ironsource/fusion-ui/components/dropdown/service';
import '@ironsource/fusion-ui/components/dropdown-search';
import '@ironsource/fusion-ui/components/dropdown-select';
import { ApiBase } from '@ironsource/fusion-ui/components/api-base';
import { DropdownTestIdModifiers } from '@ironsource/fusion-ui/entities';
import { TestIdsService } from '@ironsource/fusion-ui/services/test-ids';

const DROPDOWN_DEBOUNCE_TIME = 500;
const DROPDOWN_OPTIONS_WITHOUT_SCROLL = 8; // if options less then - no use scroll

const _c0 = ["optionsHolder"];
const _c1 = ["searchComponent"];
const _c2 = ["selectComponent"];
const _c3 = ["chipContent"];
const _c4 = ["trigger"];
class DropdownBaseComponent extends ApiBase {
    set options(value) {
        this.optionsState = this.cloneOptions(value);
        this.displayedOptions$.next(this.parseOptions(this.optionsState));
    }
    /** @ignore */
    set optionsGroups(value) {
        if (value) {
            this.options = this.dropdownService.mapGroupedOptions(value);
        }
    }
    /** @internal */
    set placeholderLocation(location) {
        if (location) {
            this._isLocatedLeft = 'left' === location;
            this._isLocatedRight = 'right' === location;
        }
    }
    /** @internal */
    set loading(value) {
        this.isLoadingManuallyChanged = true;
        this.loadingState = value;
    }
    /** @internal */
    set error(error) {
        this._error = error;
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
    }
    get error() {
        return this._error;
    }
    /** @ignore */
    set optionsTitle(value) {
        this._optionsTitle = value;
    }
    /** @ignore */
    get optionsTitle() {
        return this._optionsTitle;
    }
    /** @ignore */
    set backendPagination(value) {
        this.onBackendPaginationChanged(value);
        this.backendPaginationState = value;
    }
    /** @internal */
    set placeholder(value) {
        if (typeof value === 'string') {
            this.placeholderText = value ?? 'Please Select';
        }
        else {
            this.placeholderText = value?.placeholderText || 'Please Select';
            this.placeholderIcon = value?.icon;
            this.forcePlaceholderOnSelection = value?.isForcedPlaceholder ? value?.isForcedPlaceholder : this.forcePlaceholderOnSelection;
        }
    }
    get testAttribute() {
        return this.testId;
    }
    get filteredOptions() {
        return this.filteredOptionsState;
    }
    get hasScroll() {
        if (this.options) {
            const hasSubOptions = this.options.some(option => Array.isArray(option.childOptions));
            return hasSubOptions || this.displayedOptions$.getValue().length > DROPDOWN_OPTIONS_WITHOUT_SCROLL;
        }
    }
    get isLocatedLeft() {
        return this._isLocatedLeft;
    }
    get isLocatedRight() {
        return this._isLocatedRight;
    }
    // eslint-disable-next-line
    get loading() {
        return this.loadingState;
    }
    // eslint-disable-next-line
    get options() {
        return this.optionsState || [];
    }
    get isMulti() {
        return false;
    }
    constructor(
    /** @ignore */
    dropdownService, uniqueIdService, element, renderer, filterByFieldPipe, 
    /** @ignore */
    cdr, clonePipe, sharedEventsService, injector) {
        super();
        this.dropdownService = dropdownService;
        this.uniqueIdService = uniqueIdService;
        this.element = element;
        this.renderer = renderer;
        this.filterByFieldPipe = filterByFieldPipe;
        this.cdr = cdr;
        this.clonePipe = clonePipe;
        this.sharedEventsService = sharedEventsService;
        this.injector = injector;
        /** @ignore */
        this.optionsChange = new EventEmitter();
        /** @ignore */
        this.selected = [];
        /** @ignore */
        this.selectedChange = new EventEmitter();
        /** @internal */
        this.searchPlaceholder = 'Search';
        /** @internal */
        this.placeholderWidth = '';
        /** @internal */
        this.isIconRightPosition = false;
        /** @internal */
        this.limitOptions = 10;
        /** @ignore */
        this.isTabMode = false;
        /** @ignore */
        this.isMultiRawDisplay = false;
        /** @ignore */
        this.optionsRenderByHover = true;
        /** @internal */
        this.searchByProperties = [];
        /** @internal */
        this.searchChange = new EventEmitter();
        /** @internal */
        this.searchClear = new EventEmitter();
        /** @internal */
        this.optionCloseIconClicked = new EventEmitter();
        /** @internal */
        this.closed = new EventEmitter();
        /** @ignore */
        this.onDestroy$ = new Subject();
        /** @ignore */
        this.forcePlaceholderOnSelection = false;
        /** @ignore */
        this.placeholderText = 'Please Select';
        /** @ignore */
        this.isOpen$ = new BehaviorSubject(false);
        /** @ignore */
        this.id = this.uniqueIdService.getUniqueId().toString();
        /** @ignore */
        this.searchValue = new FormControl();
        /** @ignore */
        this.subject = new Subject();
        /** @ignore */
        this.isPredefinedTags = false; // from tag-input
        /** @ignore */
        this.isNotFoundPredefined = false; // from tag-input
        /** @ignore */
        this.isLoadingManuallyChanged = false;
        /** @ignore */
        this.pagination = {
            latestScrollHeight: null,
            counter: 1,
            lastCounter: 0,
            percentScrollDown: 0.2,
            oneTimeFlagScroll: false
        };
        /** @ignore */
        this.placeholder$ = new BehaviorSubject('');
        /** @ignore */
        this.searchPlaceholder$ = new BehaviorSubject(this.searchPlaceholder);
        /** @ignore */
        this.backendPaginationChanged$ = new Subject();
        /** @ignore */
        this.displayedOptions$ = new BehaviorSubject([]);
        /** @ignore */
        this.dropdownArrowIconName = {
            iconName: 'arrow-dropdown',
            iconVersion: 'v1'
        };
        /** @ignore */
        this.isIndeterminate = false;
        /** @ignore */
        this.optionSelected$ = new BehaviorSubject('');
        this._isLocatedRight = false;
        this._isLocatedLeft = false;
        this.focusedLI = -1;
        this.backendPaginationPageNumber = 1;
        this.filteredOptionsState = [];
        this.optionsState = [];
        /** @ignore */
        this.dropdownSelectConfigurations$ = new BehaviorSubject(this.getDropdownSelectConfigurations());
        this.testIdDropdownModifiers = DropdownTestIdModifiers;
        this.testIdsService = this.injector.get(TestIdsService);
        // Implement ControlValueAccessor methods
        /**
         * Method to call when the component value has changes.
         * @ignore
         */
        this.propagateChange = (_) => { };
    }
    ngOnInit() {
        if (this.templateRef) {
            this.optionsRenderByHover = false;
        }
        this.contentTemplate = this.chipContent;
        this.displayedOptionsObservable$ = this.getDisplayedOptionsObservable();
        this.arrowNavigation = this.arrowNavigation || false;
        this.icon = this.icon || '';
        this.placeholder$.next(this.placeholderText);
        this.initPlaceholder = this.placeholderText;
        this.initIcon = typeof this.icon === 'string' ? this.icon : { ...this.icon };
        this.search = this.search || false;
        this.strictSearch = this.strictSearch || false;
        this.selected = this.selected || [];
        this.mappingOptions = {
            id: 'id',
            title: 'title',
            displayText: 'displayText',
            ...this.mappingOptions
        };
        if (!this.autoComplete && (!this.options || !this.options.length)) {
            this.options = this.options || [];
        }
        this.setLabel();
        // debounceTime - Wait 1 second before creating another http call
        // distinctUntilChanged - Block new request if with the same request:
        // Example for distinctUntilChanged: entered '123' - generate a call,
        // clear '3' and then type again '3'. instead of '3' requests will be only 1.
        this.subject.pipe(takeUntil(this.onDestroy$), debounceTime(DROPDOWN_DEBOUNCE_TIME), distinctUntilChanged()).subscribe(() => {
            if (this.searchValue.value && this.searchValue.value.trim().length !== 0) {
                this.searchChange.emit(this.searchValue.value);
            }
            else {
                if (this.autoComplete) {
                    this.options = [];
                }
                this.searchClear.emit();
            }
            this.displayedOptions$.next(this.parseOptions(this.options));
        });
        this.initListeners();
    }
    /** @ignore */
    getDropdownSelectConfigurations() {
        return {
            selectedOption: this.selected,
            dynamicContent: this.dynamicPlaceholder,
            placeholder: {
                prefix: this.placeholderPrefix,
                search: this.searchPlaceholder$.getValue(),
                value: this.placeholder$.getValue(),
                width: this.placeholderWidth,
                forcePlaceholderOnSelection: this.forcePlaceholderOnSelection,
                overlayLocation: this.placeholderLocation
            },
            disabled: this.isDisabled || this.isDisabledForm,
            readonly: this.readonly,
            isTabMode: this.isTabMode,
            isSearch: this.autoComplete || this.search,
            isOpen: this.isOpen$.getValue(),
            error: this.error,
            icon: this.icon || this.placeholderIcon,
            labelFlag: this.labelFlag,
            labelImage: this.labelImageSrc,
            dropdownArrowIconName: this.dropdownArrowIconName,
            isMultipleSelection: this.isMulti,
            filterIconName: this.filterIconName
        };
    }
    ngOnDestroy() {
        this.onDestroy$.next();
        this.onDestroy$.complete();
        this.resetState$.complete();
        this.backendPaginationChanged$.next();
        this.backendPaginationChanged$.complete();
    }
    ngOnChanges(changes) {
        if (changes.placeholder) {
            this.placeholder$.next(this.placeholderText);
        }
        if (changes.options && !this.isLoadingManuallyChanged) {
            this.loadingState = !this.options || this.options?.length === 0;
        }
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
    }
    /** @ignore */
    initListeners() {
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
        this.searchValue.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
            this.onSearchChange();
        });
        this.dropdownService.closeAll$.pipe(takeUntil(this.onDestroy$)).subscribe(event => {
            if (!!event.target.closest('div.dropdown-arrow-container')) {
                return;
            }
            this.closeDropdown();
        });
        this.apiBaseListeners();
    }
    /**
     * Subscribe for that search text as been changed
     * @ignore
     */
    onSearchChange() {
        this.focusedLI = -1;
        if (!isNullOrUndefined(this.searchValue.value) && !this.searchValue.value.trim().length && this.autoComplete) {
            this.clearOptions();
        }
        this.subject.next(this.searchValue.value);
    }
    /**
     * Open dropdown windows
     * @ignore
     */
    openDropdown(event) {
        const forceOpen = !!event.target.closest('div.dropdown-arrow-container');
        if (!(this.isDisabled || this.isDisabledForm) && !this.readonly) {
            if (!this.isTabMode || forceOpen) {
                if (this.isOpen$.getValue()) {
                    this.closeDropdown();
                }
                else {
                    this.isOpen$.next(true);
                    setTimeout(this._onDropdownOpened.bind(this), 0);
                }
            }
            if (forceOpen && this.isTabMode) {
                event.stopPropagation();
                this.dropdownService.emitCloseAllEvent(event);
            }
        }
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
    }
    _onDropdownOpened() {
        this.calcOptionHolderPosition();
        this.optionsHolderElRef.nativeElement.scrollTop = 0;
        if ((this.search || this.autoComplete) && this.searchComponent && this.searchComponent.inputComponent) {
            this.searchComponent.inputComponent.setFocus();
        }
    }
    /**
     * Close dropdwn windows
     * @ignore
     */
    closeDropdown({ clickOutside = false } = { clickOutside: false }) {
        this.isOpen$.next(false);
        this.searchValue.reset('');
        if (!!this.selectComponent?.resetSearch) {
            this.selectComponent.resetSearch();
        }
        this.focusedLI = -1;
        // clear options if in autoComplete mode
        if (this.autoComplete) {
            this.clearOptions();
        }
        this.pagination = { ...this.pagination, counter: 1, lastCounter: 0 };
        this.displayedOptions$.next(this.parseOptions(this.optionsState));
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
        this.resetOptionsStyle();
        this.closed.emit({ clickOutside });
    }
    /**
     * Set a label to dropdown main button
     * @ignore
     */
    setLabel() {
        this.labelImageSrc = undefined;
        let placeholder = this.initPlaceholder;
        let placeholderForSearch = this.searchPlaceholder;
        this.icon = this.initIcon;
        this.labelFlag = '';
        if (this.selected && this.selected.length > 0 && !this.forcePlaceholderOnSelection) {
            if (this.selected.length === 1) {
                placeholder = this.getFirstSelectedLabel();
                placeholderForSearch = this.selected[0].titleText
                    ? this.selected[0].titleText
                    : this.dropdownService.optionToString(this.selected[0], this.mappingOptions, {}, true);
                if (!!this.selected[0].icon) {
                    this.icon = this.selected[0].icon;
                }
                if (!!this.selected[0].image) {
                    this.labelImageSrc = this.selected[0].image;
                }
                if (this.selected[0].flag) {
                    this.labelFlag = this.selected[0].flag;
                }
                else {
                    this.labelFlag = '';
                }
            }
            else {
                const placeholderPrefix = this.isAllSelected ? 'All' : `${this.selected.length}`;
                if (this.placeholderChipV4Mode) {
                    placeholderForSearch = placeholder =
                        placeholderPrefix === 'All' ? `${placeholderPrefix}` : this.getFirstSelectedLabel(2);
                }
                else {
                    placeholderForSearch = placeholder = this.placeholderPrefix
                        ? `${placeholderPrefix} ${this.placeholderPrefix} ${placeholderPrefix !== 'All' ? 'selected' : ''}`
                        : `${this.selected.length} selected`;
                }
            }
        }
        this.placeholder$.next(placeholder);
        this.searchPlaceholder$.next(placeholderForSearch);
        this.optionSelected$.next(placeholder !== this.initPlaceholder
            ? this.selectedTypeObject && Array.isArray(this.selected) && this.selected.length
                ? this.selected[0]
                : placeholder
            : null);
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
    }
    /** @ignore */
    getHolderCSSClasses() {
        return [
            this.isIconRightPosition && 'is-icon-right-position',
            this.isOpen$.getValue() && 'dd-opened',
            !!this.selected && this.selected.length && 'ss-selected',
            (this.isDisabled || this.isDisabledForm) && 'dd-disabled',
            this.readonly && 'dd-readonly',
            this.isTabMode && 'is-tab-mode'
        ].filter(Boolean);
    }
    /** @ignore */
    parseOptions(options) {
        if (options) {
            let filteredOptions = [...options];
            if ((!this.autoComplete && !this.backendPaginationState && this.searchValue && this.searchValue.value) ||
                this.isPredefinedTags) {
                let filterByArray = [];
                if (this.searchByProperties?.length) {
                    filterByArray = this.searchByProperties;
                }
                else if (this.mappingOptions) {
                    filterByArray = Object.values(this.mappingOptions);
                }
                // use filter !(item.checked && this.isPredefinedTags) because in tags-input component item.checked
                // must bot showed and in drop-down can
                filteredOptions = this.filterByFieldPipe.transform(filteredOptions.filter(item => !(item.checked && this.isPredefinedTags)), filterByArray, this.searchValue ? this.searchValue.value : null, {
                    caseSensitive: this.strictSearch,
                    ignoreKey: this.isMulti ? 'isGroup' : null
                });
                if (this.isMulti) {
                    filteredOptions = this.dropdownService.filterEmptyGroupTitle(filteredOptions);
                }
                this.isNotFoundPredefined = !filteredOptions.length;
            }
            if (this.limitOptions && this.limitOptions > 0 && this.pagination.counter * this.limitOptions < this.options.length) {
                filteredOptions = filteredOptions.slice(0, this.limitOptions * this.pagination.counter);
            }
            this.filteredOptionsState = filteredOptions;
            return filteredOptions || [];
        }
        else {
            return [];
        }
    }
    /** @ignore */
    isSelected(option) {
        return (this.selected &&
            this.selected.length > 0 &&
            this.selected.some(item => {
                if (!isNullOrUndefined(option.id) && !isNullOrUndefined(item.id)) {
                    return item.id === option.id; // in case not same instance
                }
                else {
                    return item === option;
                }
            }));
    }
    /**
     * Add arrows key navigation for the drop-down
     * @ignore
     */
    keyEvent(event) {
        if (!this.arrowNavigation) {
            return;
        }
        event.stopPropagation();
        const keyCodes = ['ArrowDown', 'ArrowUp', 'Enter', 'Escape'];
        const elements = this.element.nativeElement.querySelectorAll('li.option:not(.is-hidden)');
        if (elements && elements.length !== 0 && keyCodes.indexOf(event.code) !== -1) {
            const elementLastIndex = elements.length - 1;
            switch (event.code) {
                case 'ArrowDown':
                    if (this.focusedLI < elementLastIndex) {
                        this.focusedLI++;
                    }
                    this.setLIFocused(elements[this.focusedLI]);
                    break;
                case 'ArrowUp':
                    if (this.focusedLI > 0) {
                        this.focusedLI--;
                    }
                    this.setLIFocused(elements[this.focusedLI]);
                    break;
                case 'Enter':
                    if (this.focusedLI >= 0) {
                        if (elements[this.focusedLI]) {
                            elements[this.focusedLI].click();
                        }
                        if (elements[this.focusedLI + 1]) {
                            this.setLIFocused(elements[this.focusedLI + 1]);
                        }
                        else if (elements[this.focusedLI - 1]) {
                            this.setLIFocused(elements[this.focusedLI - 1]);
                            this.focusedLI--;
                        }
                        else {
                            this.focusedLI = 0;
                        }
                    }
                    break;
                case 'Escape':
                    this.closeDropdown();
                    break;
            }
        }
    }
    /** @ignore */
    onScroll($event) {
        if (this.options) {
            const target = $event.target;
            if (this.pagination.counter * this.limitOptions > this.options.length) {
                if (this.isScrollReachEnd(target)) {
                    this.onScrollReachEnd();
                }
                return;
            }
            if (this.pagination.lastCounter === this.pagination.counter || this.loading) {
                // ignore scroll when data not rendered yet or data loading
                return;
            }
            if (target.scrollHeight - (target.offsetHeight + target.scrollTop) + 2 <
                target.scrollHeight * this.pagination.percentScrollDown) {
                this.pagination.lastCounter = this.pagination.counter;
                this.pagination.counter++;
                this.pagination.oneTimeFlagScroll = true;
                this.displayedOptions$.next(this.parseOptions(this.options));
            }
        }
    }
    /**
     * select / remove option from selected list
     * @ignore
     */
    changeSelected({ option, $event }) {
        // ignore click on selected
        if (this.selected && this.selected[0] && option && this.selected[0].id === option.id) {
            return;
        }
        if ($event) {
            const subOptionId = $event.target.closest('li').dataset.id;
            if (Array.isArray(option.childOptions) && subOptionId) {
                option = option.childOptions.find(item => item.id.toString() === subOptionId);
                $event.stopPropagation();
            }
        }
        if (!isNullOrUndefined(this.changeConfirmation) && !this.selected.some(item => item.id === option.id)) {
            this.changeConfirmation().then(isReset => {
                if (isReset) {
                    this.doChanges(option);
                }
                else {
                    this.closeDropdown();
                }
            });
        }
        else {
            this.doChanges(option);
        }
    }
    /** @ignore */
    changeConfig(val) {
        this.element.nativeElement.style.setProperty('--fu-chip-max-width', val);
    }
    /** @ignore */
    valueSelected() {
        return this.optionSelected$.asObservable().pipe(map(value => ({ value, isSelected: !!value })));
    }
    /** @ignore */
    open() {
        this.trigger.nativeElement.click();
    }
    /** @ignore */
    onCloseIconClicked(option) {
        this.optionCloseIconClicked.emit(option);
    }
    doChanges(option) {
        if (!Array.isArray(option.childOptions)) {
            this.selected = !option ? [] : [option];
            this.propagateChange(this.selected);
            this.selectedChange.emit(this.selected);
            this.closeDropdown();
            this.setOptionsAndLabel();
        }
        else {
            this.options = this.optionsState.map((optionItem) => optionItem.id === option.id
                ? {
                    ...option,
                    isOpen: !option?.isOpen
                }
                : optionItem);
        }
    }
    /**
     * clear all options and notify.
     * @ignore
     */
    clearOptions() {
        this.options = [];
        this.optionsChange.emit(this.options);
        this.searchClear.emit();
    }
    /**
     * event from directive on outside component click
     * @ignore
     */
    onOutsideClick(target) {
        this.closeDropdown({ clickOutside: true });
    }
    getFirstSelectedLabel(amount = 1) {
        const labelString = this.selected
            .slice(0, amount)
            .map(item => item.titleText
            ? item.titleText
            : this.placeholderChipV4Mode && item.flag
                ? item.flag.toUpperCase()
                : this.dropdownService.optionToString(item, this.mappingOptions))
            .join(', ');
        const andPlus = this.selected.length > amount ? `, +${this.selected.length - amount}` : '';
        return labelString + andPlus;
    }
    cloneOptions(options) {
        if (isNullOrUndefined(options)) {
            return [];
        }
        return this.optionsState && this.optionsState.length ? [...options] : this.clonePipe.transform(options);
    }
    setLIFocused(element) {
        const focusedElement = this.element.nativeElement.querySelector('li.is-focused');
        if (focusedElement) {
            this.renderer.removeClass(focusedElement, 'is-focused');
        }
        if (!!element) {
            this.renderer.addClass(element, 'is-focused');
            element.scrollIntoView(false);
        }
    }
    setOptionsAndLabel() {
        if (this.selected && this.selected.length !== 0) {
            const optionsSettings = this.dropdownService.setOptionsState(this.options, this.selected);
            this.options = optionsSettings.options;
            this.setLabel();
        }
        else {
            this.setLabel();
        }
    }
    onBackendPaginationChanged(backendPagination) {
        this.backendPaginationChanged$.next();
        this.backendPaginationTotalResult = null;
        this.backendPaginationPageNumber = 1;
        this.options = null;
        this.loading = true;
        if (backendPagination) {
            backendPagination
                .backendGetFunction(backendPagination.getOptions)
                .pipe(takeUntil(this.backendPaginationChanged$))
                .subscribe(val => {
                const value = val ? [...val[backendPagination.responseDataPropertyName]] : null;
                this.options = this.sortOptions({
                    backendPagination,
                    dropdownOptions: value
                        ? backendPagination.mappingFunction
                            ? value.map(backendPagination.mappingFunction)
                            : value
                        : null
                });
                this.backendPaginationTotalResult = val ? val[backendPagination.responseTotalCountPropertyName] : null;
                this.loading = false;
                this.cdr.markForCheck();
            });
        }
    }
    onScrollReachEnd() {
        if (!this.loading) {
            if (this.backendPaginationState) {
                if (this.backendPaginationTotalResult && this.backendPaginationTotalResult > this.options.length) {
                    this.loading = true;
                    this.backendPaginationState
                        .backendGetFunction({
                        ...this.backendPaginationState.getOptions,
                        pageNumber: this.backendPaginationPageNumber + 1
                    })
                        .pipe(take(1))
                        .subscribe(val => {
                        const responseValue = val && Array.isArray(val[this.backendPaginationState.responseDataPropertyName])
                            ? val[this.backendPaginationState.responseDataPropertyName]
                            : [];
                        const value = this.backendPaginationState.mappingFunction
                            ? responseValue.map(this.backendPaginationState.mappingFunction)
                            : responseValue;
                        const dropdownOptions = this.sortOptions({
                            backendPagination: this.backendPaginationState,
                            dropdownOptions: [...value]
                        });
                        this.options = [...this.options, ...dropdownOptions];
                        this.loading = false;
                        this.backendPaginationPageNumber++;
                        this.cdr.markForCheck();
                    });
                }
            }
        }
    }
    sortOptions({ backendPagination, dropdownOptions }) {
        if (backendPagination.sortingFunction) {
            return dropdownOptions.sort(backendPagination.sortingFunction);
        }
        return dropdownOptions;
    }
    isScrollReachEnd(target) {
        return target.scrollHeight - target.scrollTop <= target.clientHeight + 10;
    }
    /**
     * Calculate if need  options open above
     */
    calcOptionHolderPosition() {
        const hostEl = this.element.nativeElement;
        const optionsHolder = hostEl.querySelector('.options-dropdown');
        if (optionsHolder) {
            if (this.parentWithOverflow === undefined || !document.contains(this.parentWithOverflow)) {
                this.parentWithOverflow = this.getParentWithOverflow(hostEl);
            }
            if (this.parentWithOverflow !== null) {
                const parentOverflowRect = this.parentWithOverflow.getBoundingClientRect();
                const optionsHolderRect = optionsHolder.getBoundingClientRect();
                const hostHolderRect = hostEl.getBoundingClientRect();
                const hasSpaceOnUp = hostHolderRect.top - parentOverflowRect.top > optionsHolderRect.height;
                if (hasSpaceOnUp && parentOverflowRect.bottom - optionsHolderRect.bottom <= 0) {
                    this.renderer.addClass(hostEl, 'fu-options-position-up');
                }
            }
            this.renderer.setStyle(optionsHolder, 'visibility', 'visible');
        }
    }
    /**
     * Find first parent element with style overflow in 'auto', 'hidden', 'scroll'
     * - childEl
     */
    getParentWithOverflow(childEl) {
        const parent = childEl.parentElement;
        let retVal = null;
        if (parent) {
            const parentOverflow = window.getComputedStyle(parent).overflow;
            retVal = ['auto', 'hidden', 'scroll'].includes(parentOverflow) ? parent : this.getParentWithOverflow(parent);
        }
        return retVal;
    }
    resetOptionsStyle() {
        const hostEl = this.element.nativeElement;
        this.renderer.removeClass(hostEl, 'fu-options-position-up');
        const optionsHolderEl = hostEl.querySelector('.options-dropdown');
        if (optionsHolderEl) {
            this.renderer.setStyle(optionsHolderEl, 'visibility', 'hidden');
        }
    }
    /**
     * update value from model to the component
     * @ignore
     */
    writeValue(value) {
        if (isNullOrUndefined(value) || (Array.isArray(value) && value.length === 0)) {
            this.selected = [];
        }
        else {
            this.selected = Array.isArray(value) ? [...value] : [value];
        }
        this.setOptionsAndLabel();
    }
    /** @ignore */
    registerOnChange(fn) {
        this.propagateChange = fn;
    }
    /** @ignore */
    registerOnTouched() { }
    /** @ignore */
    setDisabledState(isDisabled) {
        if (isNullOrUndefined(this.isDisabled)) {
            this.isDisabledForm = isDisabled;
            this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
            this.cdr.markForCheck();
        }
    }
    getDisplayedOptionsObservable() {
        if (this.optionsRenderByHover) {
            return this.sharedEventsService
                .getMouseoverObservable({
                element: this.element.nativeElement,
                padding: 100
            })
                .pipe(take(1), switchMapTo(this.displayedOptions$.asObservable()));
        }
        else {
            return this.displayedOptions$.asObservable();
        }
    }
    apiBaseListeners() {
        this.placeholder$
            .asObservable()
            .pipe(takeUntil(this.onDestroy$))
            .subscribe(placeholder => (this.chipDefaultContent = this.placeholderPrefix ? this.placeholderPrefix + ': ' + placeholder : placeholder));
        this.resetState$
            .asObservable()
            .pipe(takeUntil(this.onDestroy$))
            .subscribe(_ => {
            this.writeValue(null);
            this.propagateChange(null);
        });
    }
    static { this.ɵfac = function DropdownBaseComponent_Factory(t) { return new (t || DropdownBaseComponent)(i0.ɵɵdirectiveInject(i1.DropdownService), i0.ɵɵdirectiveInject(i2.UniqueIdService), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i3.FilterByFieldPipe), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i4.ClonePipe), i0.ɵɵdirectiveInject(i5.SharedEventsService), i0.ɵɵdirectiveInject(i0.Injector)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: DropdownBaseComponent, viewQuery: function DropdownBaseComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(_c0, 5);
            i0.ɵɵviewQuery(_c1, 5);
            i0.ɵɵviewQuery(_c2, 5);
            i0.ɵɵviewQuery(_c3, 7);
            i0.ɵɵviewQuery(_c4, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.optionsHolderElRef = _t.first);
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchComponent = _t.first);
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.selectComponent = _t.first);
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.chipContent = _t.first);
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.trigger = _t.first);
        } }, hostVars: 1, hostBindings: function DropdownBaseComponent_HostBindings(rf, ctx) { if (rf & 1) {
            i0.ɵɵlistener("keyup", function DropdownBaseComponent_keyup_HostBindingHandler($event) { return ctx.keyEvent($event); });
        } if (rf & 2) {
            i0.ɵɵattribute("data-testid", ctx.testAttribute);
        } }, inputs: { testId: "testId", options: "options", optionsGroups: "optionsGroups", selected: "selected", placeholderPrefix: "placeholderPrefix", searchPlaceholder: "searchPlaceholder", placeholderWidth: "placeholderWidth", dynamicPlaceholder: "dynamicPlaceholder", icon: "icon", filterIconName: "filterIconName", isIconRightPosition: "isIconRightPosition", isDisabled: "isDisabled", readonly: "readonly", search: "search", autoComplete: "autoComplete", mappingOptions: "mappingOptions", limitOptions: "limitOptions", placeholderLocation: "placeholderLocation", loading: "loading", strictSearch: "strictSearch", arrowNavigation: "arrowNavigation", error: "error", optionsTitle: "optionsTitle", optionRightHoverText: "optionRightHoverText", changeConfirmation: "changeConfirmation", optionCloseIcon: "optionCloseIcon", helper: "helper", backendPagination: "backendPagination", isTabMode: "isTabMode", isMultiRawDisplay: "isMultiRawDisplay", placeholder: "placeholder", optionsRenderByHover: "optionsRenderByHover", searchByProperties: "searchByProperties" }, outputs: { optionsChange: "optionsChange", selectedChange: "selectedChange", searchChange: "searchChange", searchClear: "searchClear", optionCloseIconClicked: "optionCloseIconClicked", closed: "closed" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature] }); }
}
__decorate([
    detectChangesDecorator,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], DropdownBaseComponent.prototype, "closeDropdown", null);
__decorate([
    detectChangesDecorator,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], DropdownBaseComponent.prototype, "changeSelected", null);
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DropdownBaseComponent, [{
        type: Directive
    }], () => [{ type: i1.DropdownService }, { type: i2.UniqueIdService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i3.FilterByFieldPipe }, { type: i0.ChangeDetectorRef }, { type: i4.ClonePipe }, { type: i5.SharedEventsService }, { type: i0.Injector }], { testId: [{
            type: Input
        }], options: [{
            type: Input
        }], optionsGroups: [{
            type: Input
        }], optionsChange: [{
            type: Output
        }], selected: [{
            type: Input
        }], selectedChange: [{
            type: Output
        }], placeholderPrefix: [{
            type: Input
        }], searchPlaceholder: [{
            type: Input
        }], placeholderWidth: [{
            type: Input
        }], dynamicPlaceholder: [{
            type: Input
        }], icon: [{
            type: Input
        }], filterIconName: [{
            type: Input
        }], isIconRightPosition: [{
            type: Input
        }], isDisabled: [{
            type: Input
        }], readonly: [{
            type: Input
        }], search: [{
            type: Input
        }], autoComplete: [{
            type: Input
        }], mappingOptions: [{
            type: Input
        }], limitOptions: [{
            type: Input
        }], placeholderLocation: [{
            type: Input
        }], loading: [{
            type: Input
        }], strictSearch: [{
            type: Input
        }], arrowNavigation: [{
            type: Input
        }], error: [{
            type: Input
        }], optionsTitle: [{
            type: Input
        }], optionRightHoverText: [{
            type: Input
        }], changeConfirmation: [{
            type: Input
        }], optionCloseIcon: [{
            type: Input
        }], helper: [{
            type: Input
        }], backendPagination: [{
            type: Input
        }], isTabMode: [{
            type: Input
        }], isMultiRawDisplay: [{
            type: Input
        }], placeholder: [{
            type: Input
        }], optionsRenderByHover: [{
            type: Input
        }], searchByProperties: [{
            type: Input
        }], searchChange: [{
            type: Output
        }], searchClear: [{
            type: Output
        }], optionCloseIconClicked: [{
            type: Output
        }], closed: [{
            type: Output
        }], optionsHolderElRef: [{
            type: ViewChild,
            args: ['optionsHolder']
        }], searchComponent: [{
            type: ViewChild,
            args: ['searchComponent']
        }], selectComponent: [{
            type: ViewChild,
            args: ['selectComponent']
        }], chipContent: [{
            type: ViewChild,
            args: ['chipContent', { static: true }]
        }], trigger: [{
            type: ViewChild,
            args: ['trigger']
        }], testAttribute: [{
            type: HostBinding,
            args: ['attr.data-testid']
        }], closeDropdown: [], keyEvent: [{
            type: HostListener,
            args: ['keyup', ['$event']]
        }], changeSelected: [] }); })();

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

export { DROPDOWN_DEBOUNCE_TIME, DROPDOWN_OPTIONS_WITHOUT_SCROLL, DropdownBaseComponent };
//# sourceMappingURL=ironsource-fusion-ui-components-dropdown-common-base.mjs.map
