import * as i0 from '@angular/core';
import { Directive, Input } from '@angular/core';
import { DropdownBaseComponent, DROPDOWN_OPTIONS_WITHOUT_SCROLL } from '@ironsource/fusion-ui/components/dropdown/common/base';
import { Observable } from 'rxjs';
import { takeUntil, startWith, map } from 'rxjs/operators';
import { isNullOrUndefined } from '@ironsource/fusion-ui/utils';

class MultiDropdownBaseComponent extends DropdownBaseComponent {
    constructor() {
        super(...arguments);
        /** @ignore */
        this.confirm = true;
        /** @ignore */
        this.optionsWithoutScroll = DROPDOWN_OPTIONS_WITHOUT_SCROLL;
        /** @ignore */
        this.hasSearchValue$ = new Observable();
        /** @ignore */
        this.showSelectedFirst = false;
    }
    get isMulti() {
        return true;
    }
    ngOnInit() {
        this.id = `is-multi-dropdown-${this.uniqueIdService.getUniqueId()}`;
        this.tempSelected = this.selected || [];
        this.tempOptions = this.cloneArray(this.options);
        // if has "select all"
        this.optionsWithoutScroll = this.selectAllLabel ? this.optionsWithoutScroll - 1 : this.optionsWithoutScroll;
        // if has "search"
        this.optionsWithoutScroll = this.search || this.autoComplete ? this.optionsWithoutScroll - 1 : this.optionsWithoutScroll;
        super.ngOnInit();
        this.hasSearchValue$ = this.searchValue.valueChanges.pipe(takeUntil(this.onDestroy$), startWith(false), map(searchValue => !!searchValue));
        this.resetState$
            .asObservable()
            .pipe(takeUntil(this.onDestroy$))
            .subscribe(_ => {
            this.applySelect(true);
        });
    }
    /**
     * Relevant only for auto complete mode.
     * If options changed outside compoenent we need to update tempOptions to
     * be the new options
     */
    ngOnChanges(changes) {
        if (changes.options && changes.options.currentValue !== changes.options.previousValue) {
            this.tempOptions = changes.options.currentValue;
            if (!changes.options.firstChange) {
                this.tempSelected = this.cloneArray(this.selected);
                this.isInSelectAllAction();
                super.setLabel();
            }
        }
        this.dropdownSelectConfigurations$.next(this.getDropdownSelectConfigurations());
    }
    /** @ignore */
    getHolderCSSClasses() {
        return [...super.getHolderCSSClasses(), ...[this.confirm && 'is-with-confirm']].filter(Boolean);
    }
    /** @ignore */
    getOptionClasses(option, index) {
        const isGroup = this.isGroupOption(option);
        const hideGroup = this.showSelectedFirst && isGroup ? this.hideGroup(index) : false;
        return {
            [option.class]: option.class,
            'fu-group': isGroup,
            'fu-group-first': isGroup && index === 0,
            'fu-group-hide': hideGroup
        };
    }
    /**
     * Open dropdown windows
     * @internal
     */
    openDropdown(event) {
        this.tempSelected = this.cloneArray(this.selected);
        super.openDropdown(event);
        this.isInSelectAllAction();
    }
    /**
     * Set to clear / select all by the given default action button
     * @internal
     */
    selectAll(checked) {
        if (checked) {
            this.tempOptions.forEach(option => {
                if (option.childOptions || option.isGroup) {
                    option.childOptions?.forEach(child => {
                        child.checked = true;
                    });
                }
                else {
                    option.checked = true;
                }
            });
            this.tempSelected = this.cloneArray(this.tempOptions.reduce((acc, option) => {
                if (option.childOptions || option.isGroup) {
                    option.childOptions?.forEach(option => {
                        if (option.checked) {
                            acc.push(option);
                        }
                    });
                }
                else {
                    if (option.checked) {
                        acc.push(option);
                    }
                }
                return acc;
            }, []));
        }
        else {
            this.tempSelected = [];
            this.tempOptions.forEach(option => {
                if (option.childOptions || option.isGroup) {
                    option.childOptions?.forEach(child => {
                        child.checked = false;
                    });
                }
                else {
                    option.checked = false;
                }
            });
        }
        this.isInSelectAllAction();
        if (!this.confirm) {
            this.applySelect();
        }
    }
    clearAll() {
        this.selectAll(false);
    }
    /**
     * Saving selected options
     * @internal
     */
    applySelect(close = false) {
        this.selected = this.tempSelected;
        if (this.showSelectedFirst && this.selected.length && this.isIndeterminate) {
            this.options = this.getSelectedOptionsFirst();
        }
        else {
            this.options = this.tempOptions;
        }
        this.setLabel();
        this.selectedChange.emit(this.selected.map(item => {
            item.isSelected = true;
            return item;
        }));
        this.propagateChange(this.selected);
        if (close) {
            this.closeDropdown();
        }
    }
    /**
     * select / remove option from selected list
     * @internal
     */
    changeSelected(option) {
        const objSelectedIndex = this.getSelectedIndex(option);
        if (objSelectedIndex > -1) {
            this.tempSelected.splice(objSelectedIndex, 1);
        }
        else {
            this.tempSelected.push(option);
        }
        this.isInSelectAllAction();
        if (!this.confirm) {
            this.applySelect();
        }
    }
    /** @ignore */
    isSelected(option) {
        return this.tempSelected && this.tempSelected.findIndex(item => item.id === option.id) !== -1;
    }
    /**
     * Check if dropdown is in default button mode.
     * If all options selected Or if none of the options selected.
     * @internal
     */
    isInSelectAllAction() {
        const tempOptionsList = this.tempOptions.reduce((acc, option) => {
            if (option.childOptions || option.isGroup) {
                option.childOptions?.forEach(option => {
                    acc.push(option);
                });
            }
            else {
                acc.push(option);
            }
            return acc;
        }, []);
        this.isAllSelected = tempOptionsList.length === this.tempSelected.length;
        this.isIndeterminate = this.tempSelected.length !== 0 && this.tempSelected.length !== tempOptionsList.length;
    }
    /**
     * @returns number - index of selected in options array or -1 if not selected
     * @internal
     */
    getSelectedIndex(option) {
        let optionSelectedIndex = -1;
        let selectedList = this.confirm ? this.tempSelected : this.selected;
        selectedList = selectedList || []; // when page did not loaded yet selectedList is undefined
        selectedList.forEach((selectedOption, index) => {
            if (selectedOption[this.mappingOptions.id] === option[this.mappingOptions.id]) {
                optionSelectedIndex = index;
            }
        });
        return optionSelectedIndex;
    }
    /** @ignore */
    optionParentClicked($event) {
        const targetEl = $event.currentTarget;
        const targetClassList = targetEl.classList;
        if (targetClassList.contains('is-has-children')) {
            if (targetClassList.contains('is-open')) {
                this.renderer.removeClass(targetEl, 'is-open');
            }
            else {
                this.renderer.addClass(targetEl, 'is-open');
            }
        }
    }
    /**
     * copy arrays without reference
     */
    cloneArray(array) {
        return [...array];
    }
    isGroupOption(option) {
        return option.isGroup && !option.childOptions;
    }
    hideGroup(index) {
        const nextOption = this.displayedOptions$.getValue()[index + 1];
        return (!isNullOrUndefined(nextOption) && this.isGroupOption(nextOption)) || isNullOrUndefined(nextOption);
    }
    getSelectedOptionsFirst() {
        return [...this.tempOptions].sort((a, b) => {
            const isASelected = this.selected.includes(a);
            const isBSelected = this.selected.includes(b);
            return isASelected === isBSelected ? 0 : isASelected ? -1 : 1;
        });
    }
    /** @ignore */
    writeValue(value) {
        super.writeValue(value);
        this.tempSelected = this.selected;
        this.isInSelectAllAction();
        super.setLabel();
    }
    static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMultiDropdownBaseComponent_BaseFactory; return function MultiDropdownBaseComponent_Factory(t) { return (ɵMultiDropdownBaseComponent_BaseFactory || (ɵMultiDropdownBaseComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MultiDropdownBaseComponent)))(t || MultiDropdownBaseComponent); }; })(); }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: MultiDropdownBaseComponent, inputs: { confirm: "confirm", selectAllLabel: "selectAllLabel", templateRef: "templateRef", testId: "testId" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MultiDropdownBaseComponent, [{
        type: Directive
    }], null, { confirm: [{
            type: Input
        }], selectAllLabel: [{
            type: Input
        }], templateRef: [{
            type: Input
        }], testId: [{
            type: Input
        }] }); })();

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

export { MultiDropdownBaseComponent };
//# sourceMappingURL=ironsource-fusion-ui-components-multi-dropdown-common-base.mjs.map
