import * as i0 from '@angular/core';
import { Component, Inject, Optional, ContentChildren, Directive, NgModule } from '@angular/core';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i3 from '@wm/components/base';
import { PROP_STRING, PROP_BOOLEAN, PROP_ANY, PROP_NUMBER, register, StylableComponent, APPLY_STYLES_TYPE, styler, RedrawableDirective, provideAsWidgetRef, createArrayFrom, WmComponentsModule } from '@wm/components/base';
import * as i1 from '@wm/core';
import { noop, removeAttr } from '@wm/core';
import { find, isArray, indexOf, get, forEach, isNumber } from 'lodash-es';

const registerProps$1 = () => {
    register('wm-accordion', new Map([
        ['class', PROP_STRING],
        ['closeothers', { value: true, ...PROP_BOOLEAN }],
        ['dataset', PROP_ANY],
        ['defaultpaneindex', { value: 0, ...PROP_NUMBER }],
        ['name', PROP_STRING],
        ['nodatamessage', { value: 'No Data Found', ...PROP_STRING }],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['statehandler', { value: 'none', ...PROP_STRING }],
        ['tabindex', { value: 0, ...PROP_NUMBER }],
        ['type', PROP_STRING]
    ]));
};

const registerProps = () => {
    register('wm-accordionpane', new Map([
        ['active', PROP_BOOLEAN], // internal property
        ['badgetype', { value: 'default', ...PROP_STRING }],
        ['badgevalue', PROP_STRING],
        ['class', PROP_STRING],
        ['content', PROP_STRING],
        ['dynamicPaneIndex', PROP_NUMBER], // internal property
        ['iconclass', PROP_STRING],
        ['isdefaultpane', PROP_BOOLEAN],
        ['isdynamic', PROP_STRING], // internal property
        ['name', PROP_STRING],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['smoothscroll', { value: false, ...PROP_BOOLEAN }],
        ['subheading', PROP_STRING],
        ['tabindex', { value: 0, ...PROP_NUMBER }],
        ['title', { value: 'Title', ...PROP_STRING }]
    ]));
};

const _c0 = ["wmAccordionPane", ""];
const _c1 = ["*"];
const _c2 = a0 => ({ active: a0 });
const DEFAULT_CLS$1 = 'app-accordion-panel panel';
const WIDGET_CONFIG$1 = { widgetType: 'wm-accordionpane', hostClass: DEFAULT_CLS$1 };
class AccordionPaneComponent extends StylableComponent {
    static { this.initializeProps = registerProps(); }
    constructor(inj, accordionRef, explicitContext) {
        super(inj, WIDGET_CONFIG$1, explicitContext);
        this.accordionRef = accordionRef;
        this.isActive = false;
        this.$lazyLoad = noop;
        styler(this.nativeElement, this, APPLY_STYLES_TYPE.SHELL);
        // title property here serves the purpose of heading.
        // remove title property as attribute
        removeAttr(this.nativeElement, 'title');
    }
    /**
     * handles the pane expand
     * invoke $lazyLoad method which takes care of loading the partial when the content property is provided - lazyLoading or partial
     * invoke redraw on the re-drawable children
     * invoke expand callback
     * notify parent about the change
     * @param {Event} evt
     */
    expand(evt) {
        if (this.isActive) {
            return;
        }
        this.isActive = true;
        this.$lazyLoad();
        this.redrawChildren();
        this.invokeEventCallback('expand', { $event: evt });
        this.notifyParent(true, evt);
    }
    /**
     * handles the pane collapse
     * invoke collapse callback
     * notify parent about the change
     * @param {Event} evt
     */
    collapse(evt) {
        if (!this.isActive) {
            return;
        }
        this.isActive = false;
        this.invokeEventCallback('collapse', { $event: evt });
        this.notifyParent(false, evt);
    }
    remove() {
        const paneIndex = this.accordionRef.getPaneIndexByRef(this);
        if (this.isActive && this.accordionRef.panes.length > 1) {
            this === this.accordionRef.panes.last ? this.accordionRef.panes.toArray()[paneIndex - 1].expand() : this.accordionRef.panes.toArray()[paneIndex + 1].expand();
        }
        const availablePanes = this.accordionRef.panes.toArray();
        availablePanes.splice(this.accordionRef.getPaneIndexByRef(this), 1);
        this.accordionRef.panes.reset([...availablePanes]);
        this.nativeElement.remove();
    }
    toggle(evt) {
        if (this.isActive) {
            this.collapse(evt);
        }
        else {
            this.expand(evt);
        }
    }
    // Todo - Vinay externalize
    redrawChildren() {
        setTimeout(() => {
            if (this.reDrawableComponents) {
                this.reDrawableComponents.forEach(c => c.redraw());
            }
        }, 100);
    }
    notifyParent(isExpand, evt) {
        this.accordionRef.notifyChange(this, isExpand, evt);
    }
    onPropertyChange(key, nv, ov) {
        if (key === 'content') {
            if (this.isActive) {
                setTimeout(() => this.$lazyLoad(), 100);
            }
        }
        else {
            super.onPropertyChange(key, nv, ov);
        }
    }
    ngAfterViewInit() {
        super.ngAfterViewInit();
        styler(this.nativeElement.querySelector('.panel-body'), this, APPLY_STYLES_TYPE.INNER_SHELL);
        if (this.isdynamic) {
            this.accordionRef.registerDynamicPane(this);
        }
    }
    static { this.ɵfac = function AccordionPaneComponent_Factory(t) { return new (t || AccordionPaneComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(AccordionDirective), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AccordionPaneComponent, selectors: [["div", "wmAccordionPane", ""]], contentQueries: function AccordionPaneComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
            i0.ɵɵcontentQuery(dirIndex, RedrawableDirective, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.reDrawableComponents = _t);
        } }, exportAs: ["wmAccordionPane"], features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(AccordionPaneComponent)
            ]), i0.ɵɵInheritDefinitionFeature], attrs: _c0, ngContentSelectors: _c1, decls: 16, vars: 22, consts: [[1, "panel-heading", "clearfix", 3, "click", "ngClass"], [1, "panel-title"], ["href", "javascript:void(0);", "role", "button", 1, "accordion-toggle"], [1, "pull-left"], [3, "hidden"], [1, "heading", 3, "innerHTML"], [1, "description", 3, "innerHTML"], [1, "panel-actions"], ["type", "button", "aria-label", "Collapse/Expand", 1, "app-icon", "panel-action", "wi", 3, "title"], [3, "ngClass"], [1, "panel-collapse", "collapse", 3, "ngClass"], ["partial-container-target", "", 1, "panel-body", 3, "wmSmoothscroll"]], template: function AccordionPaneComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵprojectionDef();
            i0.ɵɵelementStart(0, "div", 0);
            i0.ɵɵlistener("click", function AccordionPaneComponent_Template_div_click_0_listener($event) { return ctx.toggle($event); });
            i0.ɵɵelementStart(1, "h3", 1)(2, "a", 2)(3, "div", 3);
            i0.ɵɵelement(4, "i", 4);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(5, "div", 3);
            i0.ɵɵelement(6, "div", 5)(7, "div", 6);
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(8, "div", 7)(9, "span");
            i0.ɵɵtext(10);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(11, "button", 8);
            i0.ɵɵelement(12, "i", 9);
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(13, "div", 10)(14, "div", 11);
            i0.ɵɵprojection(15);
            i0.ɵɵelementEnd()();
        } if (rf & 2) {
            i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(20, _c2, ctx.isActive));
            i0.ɵɵadvance(2);
            i0.ɵɵattribute("aria-expanded", ctx.isActive)("aria-label", ctx.badgevalue ? ctx.title + " " + ctx.badgevalue : ctx.title);
            i0.ɵɵadvance(2);
            i0.ɵɵclassMapInterpolate1("app-icon panel-icon ", ctx.iconclass, "");
            i0.ɵɵproperty("hidden", !ctx.iconclass);
            i0.ɵɵadvance(2);
            i0.ɵɵproperty("innerHTML", ctx.title, i0.ɵɵsanitizeHtml);
            i0.ɵɵadvance();
            i0.ɵɵproperty("innerHTML", ctx.subheading, i0.ɵɵsanitizeHtml);
            i0.ɵɵadvance(2);
            i0.ɵɵclassMapInterpolate1("label label-", ctx.badgetype, "");
            i0.ɵɵadvance();
            i0.ɵɵtextInterpolate(ctx.badgevalue);
            i0.ɵɵadvance();
            i0.ɵɵpropertyInterpolate2("title", "", ctx.appLocale.LABEL_COLLAPSE, "/", ctx.appLocale.LABEL_EXPAND, "");
            i0.ɵɵattribute("aria-expanded", ctx.isActive);
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngClass", ctx.isActive ? "wi-minus" : "wi-plus");
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngClass", ctx.isActive ? "collapse in" : "collapse");
            i0.ɵɵadvance();
            i0.ɵɵproperty("wmSmoothscroll", ctx.smoothscroll);
        } }, dependencies: [i2.NgClass, i3.SmoothScrollDirective], encapsulation: 2 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AccordionPaneComponent, [{
        type: Component,
        args: [{ selector: 'div[wmAccordionPane]', providers: [
                    provideAsWidgetRef(AccordionPaneComponent)
                ], exportAs: 'wmAccordionPane', template: "<div class=\"panel-heading clearfix\" (click)=\"toggle($event)\" [ngClass]=\"{active: isActive}\">\n    <h3 class=\"panel-title\">\n        <a [attr.aria-expanded]=\"isActive\" [attr.aria-label]=\"badgevalue ? title + ' ' + badgevalue : title\"\n           class=\"accordion-toggle\"\n           href=\"javascript:void(0);\" role=\"button\">\n            <div class=\"pull-left\">\n                <i class=\"app-icon panel-icon {{iconclass}}\" [hidden]=\"!iconclass\"></i>\n            </div>\n            <div class=\"pull-left\">\n                <div class=\"heading\" [innerHTML]=\"title\"></div>\n                <div class=\"description\" [innerHTML]=\"subheading\"></div>\n            </div>\n        </a>\n    </h3>\n    <div class=\"panel-actions\">\n        <span class=\"label label-{{badgetype}}\">{{badgevalue}}</span>\n        <button type=\"button\" aria-label=\"Collapse/Expand\" [attr.aria-expanded]=\"isActive\"\n                class=\"app-icon panel-action wi\"\n                title=\"{{appLocale.LABEL_COLLAPSE}}/{{appLocale.LABEL_EXPAND}}\">\n            <i [ngClass]=\"isActive ? 'wi-minus' : 'wi-plus'\"></i>\n        </button>\n    </div>\n</div>\n<div [ngClass]=\"isActive ? 'collapse in' : 'collapse'\" class=\"panel-collapse collapse\">\n    <div class=\"panel-body\" [wmSmoothscroll]=\"smoothscroll\" partial-container-target>\n        <ng-content></ng-content>\n    </div>\n</div>\n" }]
    }], () => [{ type: i0.Injector }, { type: AccordionDirective }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], { reDrawableComponents: [{
            type: ContentChildren,
            args: [RedrawableDirective, { descendants: true }]
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AccordionPaneComponent, { className: "AccordionPaneComponent", filePath: "accordion-pane/accordion-pane.component.ts", lineNumber: 20 }); })();

const DEFAULT_CLS = 'app-accordion panel-group';
const WIDGET_CONFIG = {
    widgetType: 'wm-accordion',
    hostClass: DEFAULT_CLS
};
class AccordionDirective extends StylableComponent {
    static { this.initializeProps = registerProps$1(); }
    constructor(inj, statePersistence, dynamicComponentProvider, explicitContext) {
        let resolveFn = noop;
        super(inj, WIDGET_CONFIG, explicitContext, new Promise(res => resolveFn = res));
        this.promiseResolverFn = resolveFn;
        this.statePersistence = statePersistence;
        this.dynamicComponentProvider = dynamicComponentProvider;
        this.dynamicPanes = [];
        this.dynamicPaneIndex = 0;
        styler(this.nativeElement, this, APPLY_STYLES_TYPE.SCROLLABLE_CONTAINER);
    }
    /**
     * AccordionPane children components invoke this method to communicate with the parent
     * if isExpand is true and when closeothers is true, all the other panes are collapsed
     * if the evt argument is defined on-change callback will be invoked.
     * updates the activePane index property
     * @param {AccordionPaneComponent} paneRef
     * @param {boolean} isExpand
     * @param {Event} evt
     */
    notifyChange(paneRef, isExpand, evt) {
        if (isExpand) {
            this.closePanesExcept(paneRef);
            const index = this.getPaneIndexByRef(paneRef);
            this.activePane = paneRef.getWidget();
            // if the event is defined invoke the change callback.
            // programmatic invocations of expand/collapse on accordion-pane will not trigger change event
            if (evt) {
                this.invokeEventCallback('change', {
                    $event: evt,
                    newPaneIndex: index,
                    oldPaneIndex: this.activePaneIndex
                });
            }
            this.activePaneIndex = index;
        }
        const mode = this.statePersistence.computeMode(this.statehandler);
        if (evt && mode && mode.toLowerCase() !== 'none') {
            const activePanes = [];
            this.panes.forEach(function (pane) {
                if (pane.isActive) {
                    activePanes.push(pane.name);
                }
            });
            if (activePanes.length) {
                this.statePersistence.setWidgetState(this, activePanes);
            }
            else {
                this.statePersistence.removeWidgetState(this);
            }
        }
    }
    /**
     * This method is used to register the dynamic panes.
     * After all panes are initialzed, update the querylist manually based on index.
     * @param paneRef - refrence of the tabpane
     */
    registerDynamicPane(paneRef) {
        this.dynamicPanes.push(paneRef);
        const isLastPane = this.dynamicPanes.length === this.dynamicPaneIndex;
        if (isLastPane) {
            for (let i = 0; i < this.dynamicPanes.length; i++) {
                const newPaneRef = find(this.dynamicPanes, pane => pane.dynamicPaneIndex === i);
                const isDuplicatePane = find(this.panes.toArray(), newPaneRef);
                if (!isDuplicatePane) {
                    this.panes.reset([...this.panes.toArray(), newPaneRef]);
                    if (newPaneRef.active) {
                        newPaneRef.expand();
                    }
                }
            }
        }
    }
    /**
     * This method is to add the tabpane dynamically
     * @param tabpanes - list of tabpanes
     */
    addPane(tabpanes) {
        if (!isArray(tabpanes)) {
            tabpanes = [tabpanes];
        }
        const paneNamesList = [];
        forEach(tabpanes, (pane, index) => {
            const isPaneAlreadyCreated = find(this.panes.toArray(), { name: pane.name });
            const isPaneNameExist = indexOf(paneNamesList, pane.name);
            // If user tries to add tabpane with the same name which is already exists then do not create the pane
            if (isPaneAlreadyCreated || isPaneNameExist > 0) {
                console.warn(`The tab pane with name ${pane.name} already exists`);
                return;
            }
            let paramMarkup = '';
            let propsTmpl = '';
            this.dynamicPaneIndex++;
            const name = pane.name ? pane.name : `accordionpane${this.panes.toArray().length + (index + 1)}`;
            paneNamesList.push(name);
            const partialParams = get(pane, 'params');
            forEach(pane, (value, key) => {
                if (key !== 'params') {
                    propsTmpl = `${propsTmpl} ${key}="${value}"`;
                }
            });
            forEach(partialParams, (value, key) => {
                paramMarkup = `${paramMarkup} <wm-param name="${key}" value="${value}"></wm-param>`;
            });
            const markup = `<wm-accordionpane dynamicPaneIndex="${this.dynamicPaneIndex - 1}" isdynamic="true" name="${name}" ${propsTmpl}>
                            ${paramMarkup}
                        </wm-accordionpane>`;
            if (!this._dynamicContext) {
                this._dynamicContext = Object.create(this.viewParent);
                this._dynamicContext[this.getAttr('wmAccordian')] = this;
            }
            this.dynamicComponentProvider.addComponent(this.getNativeElement(), markup, this._dynamicContext, { inj: this.inj });
        });
        return paneNamesList;
    }
    /**
     * This method is to remove the tabpane
     * @param paneName - name of the pane
     */
    removePane(paneName) {
        const paneRef = this.getPaneRefByName(paneName);
        if (paneRef) {
            paneRef.remove();
        }
    }
    isValidPaneIndex(index) {
        return (index >= 0 && index < this.panes.length);
    }
    getPaneRefByName(name) {
        return find(this.panes.toArray(), { name: name });
    }
    getPaneIndexByRef(paneRef) {
        return this.panes.toArray().indexOf(paneRef);
    }
    getPaneRefByIndex(index) {
        return this.panes.toArray()[index];
    }
    // Except the pane provided close all other panes
    closePanesExcept(paneRef) {
        if (isNumber(paneRef)) {
            paneRef = this.getPaneRefByIndex(paneRef);
        }
        if (this.closeothers) {
            this.panes.forEach(pane => {
                if (pane !== paneRef) {
                    pane.collapse();
                }
            });
        }
    }
    expandPane(index) {
        this.closePanesExcept(index);
        this.panes.toArray()[index].expand();
    }
    onDataChange(newVal) {
        this.fieldDefs = createArrayFrom(newVal);
    }
    onPropertyChange(key, nv, ov) {
        if (key === 'defaultpaneindex') {
            this.defaultpaneindex = nv;
        }
        else if (key === 'dataset') {
            this.onDataChange(nv);
        }
        else if (key === 'statehandler') {
            const widgetState = this.statePersistence.getWidgetState(this);
            let paneToSelect = [];
            if (nv !== 'none' && isArray(widgetState)) {
                widgetState.forEach(paneName => {
                    paneToSelect = this.panes.filter(function (pane) {
                        return paneName === pane.name;
                    });
                    if (!paneToSelect.length) {
                        console.warn('Accordion pane name ' + paneName + ' in State is incorrect.');
                    }
                    else {
                        this.expandPane(this.getPaneIndexByRef(paneToSelect[0]));
                    }
                });
            }
            else {
                if (this.isValidPaneIndex(this.defaultpaneindex)) {
                    this.expandPane(this.defaultpaneindex);
                }
            }
        }
        else {
            super.onPropertyChange(key, nv, ov);
        }
    }
    ngAfterContentInit() {
        super.ngAfterContentInit();
        this.promiseResolverFn();
        this.panes.changes.subscribe(slides => {
            if (this.panes.length) {
                this.expandPane(this.defaultpaneindex);
            }
        });
    }
    static { this.ɵfac = function AccordionDirective_Factory(t) { return new (t || AccordionDirective)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i1.StatePersistence), i0.ɵɵdirectiveInject(i1.DynamicComponentRefProvider), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: AccordionDirective, selectors: [["div", "wmAccordion", ""]], contentQueries: function AccordionDirective_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
            i0.ɵɵcontentQuery(dirIndex, AccordionPaneComponent, 4);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.panes = _t);
        } }, exportAs: ["wmAccordion"], features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(AccordionDirective)
            ]), i0.ɵɵInheritDefinitionFeature] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AccordionDirective, [{
        type: Directive,
        args: [{
                selector: 'div[wmAccordion]',
                exportAs: 'wmAccordion',
                providers: [
                    provideAsWidgetRef(AccordionDirective)
                ]
            }]
    }], () => [{ type: i0.Injector }, { type: i1.StatePersistence }, { type: i1.DynamicComponentRefProvider }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], { panes: [{
            type: ContentChildren,
            args: [AccordionPaneComponent]
        }] }); })();

const components = [
    AccordionPaneComponent,
    AccordionDirective
];
class AccordionModule {
    static { this.ɵfac = function AccordionModule_Factory(t) { return new (t || AccordionModule)(); }; }
    static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: AccordionModule }); }
    static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
            WmComponentsModule] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AccordionModule, [{
        type: NgModule,
        args: [{
                imports: [
                    CommonModule,
                    WmComponentsModule
                ],
                declarations: [...components],
                exports: [...components]
            }]
    }], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(AccordionModule, { declarations: [AccordionPaneComponent,
        AccordionDirective], imports: [CommonModule,
        WmComponentsModule], exports: [AccordionPaneComponent,
        AccordionDirective] }); })();

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

export { AccordionDirective, AccordionModule, AccordionPaneComponent };
//# sourceMappingURL=index.mjs.map
