import * as i2 from '@acorex/components/button';
import { AXButtonModule } from '@acorex/components/button';
import { AXCommonModule } from '@acorex/cdk/common';
import * as i3 from '@acorex/components/decorators';
import { AXDecoratorModule } from '@acorex/components/decorators';
import { AXBasePageComponent } from '@acorex/components/page';
import * as i4 from '@acorex/components/search-box';
import { AXSearchBoxModule } from '@acorex/components/search-box';
import { AXPSettingService } from '@acorex/platform/common';
import { AXPPlatformScope } from '@acorex/platform/core';
import * as i2$1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, Injector, runInInjectionContext, signal, model, computed, ViewEncapsulation, Component } from '@angular/core';
import * as i1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { orderBy } from 'lodash-es';
import * as i3$1 from '@acorex/core/translation';
import { AXTranslationModule } from '@acorex/core/translation';
import * as i5 from '@acorex/components/tree-view';
import { AXTreeViewModule } from '@acorex/components/tree-view';
import { AXPWidgetItemComponent, AXPStateMessageComponent } from '@acorex/platform/layout/components';
import { AXMEntityCrudServiceImpl } from '@acorex/platform/layout/entity';
import { R as RootConfig } from './acorex-modules-form-template-management-acorex-modules-form-template-management-DCKQMU5_.mjs';

/**
 * Maps AXPDisplayWidgetProvided to generic AXPWidgetItemData
 */
function mapToWidgetItemData(widget) {
    return {
        title: widget.title,
        description: widget.description,
        icon: widget.icon ?? 'fa-solid fa-cube',
        isPinned: widget.pinned,
        data: widget
    };
}
class AXPTemplateWidgetPickerComponent extends AXBasePageComponent {
    constructor() {
        super(...arguments);
        this.settingService = inject(AXPSettingService);
        this.injector = inject(Injector);
        this.categoryEntityService = runInInjectionContext(this.injector, () => new AXMEntityCrudServiceImpl(`${RootConfig.module.name}.Category`));
        this.expandedCategoriesKey = 'forms:templates:picker:expandedCategories';
        // Track expanded category IDs
        this.expandedCategoryIds = signal([], ...(ngDevMode ? [{ debugName: "expandedCategoryIds" }] : []));
        this.pinnedSettingKey = 'forms:templates:picker:pinned';
        this.searchTerm = model('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
        // Data properties - populated by popup service
        this.widgets = [];
        // Signals
        this.displayWidgets = signal([], ...(ngDevMode ? [{ debugName: "displayWidgets" }] : []));
        // Signal to track selected widgets
        this.selectedWidgets = signal([], ...(ngDevMode ? [{ debugName: "selectedWidgets" }] : []));
        // Computed for filtered and ordered widget list
        this.orderedList = computed(() => {
            const search = this.searchTerm().toLowerCase();
            const selectedCategory = this.selectedCategory();
            const selectedCategoryId = selectedCategory ? selectedCategory.id : null;
            const filterByCategory = (widget) => {
                if (!selectedCategoryId || selectedCategoryId == 'all')
                    return true;
                return selectedCategoryId === widget.group.name;
            };
            return orderBy(this.displayWidgets().filter((w) => {
                const matchesCategory = filterByCategory(w);
                const matchesSearch = !search || w.title.toLowerCase().includes(search) || w.description?.toLowerCase().includes(search);
                return matchesCategory && matchesSearch;
            }), ['pinned', 'title'], ['desc', 'asc']);
        }, ...(ngDevMode ? [{ debugName: "orderedList" }] : []));
        // Pinned and regular lists
        this.pinnedList = computed(() => this.orderedList().filter((c) => c.pinned), ...(ngDevMode ? [{ debugName: "pinnedList" }] : []));
        this.regularList = computed(() => this.orderedList().filter((c) => !c.pinned), ...(ngDevMode ? [{ debugName: "regularList" }] : []));
        // Mapped data for generic widget items
        this.pinnedWidgetItems = computed(() => this.pinnedList().map(mapToWidgetItemData), ...(ngDevMode ? [{ debugName: "pinnedWidgetItems" }] : []));
        this.regularWidgetItems = computed(() => this.regularList().map(mapToWidgetItemData), ...(ngDevMode ? [{ debugName: "regularWidgetItems" }] : []));
        // Computed property to check if we're in search mode
        this.isSearchMode = computed(() => this.searchTerm().trim().length > 0, ...(ngDevMode ? [{ debugName: "isSearchMode" }] : []));
        // Computed property to check if there are any results
        this.hasResults = computed(() => this.orderedList().length > 0, ...(ngDevMode ? [{ debugName: "hasResults" }] : []));
        //#region Category Tree
        this.provideLazyTreeView = async (selectedItemId) => {
            if (selectedItemId == 'all') {
                const categories = await this.categoryEntityService.getRoots({});
                const items = categories.items.map((item) => ({
                    id: item.id,
                    title: item.title,
                    hasChild: item.childCount > 0,
                    expanded: this.expandedCategoryIds().includes(item.id),
                }));
                return items;
            }
            else if (selectedItemId) {
                const categories = (await this.categoryEntityService.getChildren({ parentId: selectedItemId }))?.items.map((item) => ({
                    id: item.id,
                    title: item.title,
                    parentId: item.parentId,
                    hasChild: item.childCount > 0,
                    expanded: this.expandedCategoryIds().includes(item.id),
                }));
                return categories;
            }
            else {
                return [
                    {
                        hasChild: true,
                        id: "all",
                        title: "All Items",
                        expanded: true,
                    }
                ];
            }
        };
        this.selectedCategory = signal(null, ...(ngDevMode ? [{ debugName: "selectedCategory" }] : []));
    }
    async ngOnInit() {
        super.ngOnInit();
        // Load expanded categories from settings
        const savedExpandedIds = (await this.settingService.get(this.expandedCategoriesKey)) || [];
        this.expandedCategoryIds.set(savedExpandedIds);
        //
        const pinnedWidgets = (await this.settingService.get(this.pinnedSettingKey)) || [];
        this.displayWidgets.set(this.widgets.map((c) => ({
            ...c,
            pinned: pinnedWidgets.includes(c.id),
            icon: c.icon ?? 'fa-solid fa-file-invoice',
        })));
    }
    handleWidgetClick(clickEvent) {
        const { event, widget } = clickEvent;
        const originalWidget = widget.data;
        if (event.ctrlKey) {
            const currentSelection = this.selectedWidgets();
            const isAlreadySelected = currentSelection.some((w) => w === originalWidget);
            if (isAlreadySelected) {
                // Deselect widget if already selected
                this.selectedWidgets.set(currentSelection.filter((w) => w !== originalWidget));
            }
            else {
                // Add widget to selection
                this.selectedWidgets.set([...currentSelection, originalWidget]);
            }
        }
        else {
            // If CTRL is not pressed, select only the clicked widget
            this.close({ widgets: [originalWidget] });
        }
    }
    async handleWidgetPinClick(clickEvent) {
        const { widget } = clickEvent;
        const originalWidget = widget.data;
        originalWidget.pinned = !originalWidget.pinned;
        // Get the current list of pinned widgets from settings
        let pinnedWidgets = (await this.settingService.get(this.pinnedSettingKey)) || [];
        // Update the list of pinned widgets based on the pinned status
        if (originalWidget.pinned) {
            if (!pinnedWidgets.includes(originalWidget.id)) {
                pinnedWidgets.push(originalWidget.id);
            }
        }
        else {
            pinnedWidgets = pinnedWidgets.filter((name) => name !== originalWidget.id);
        }
        // Save the updated list of pinned widgets
        await this.settingService.scope(AXPPlatformScope.User).set(this.pinnedSettingKey, pinnedWidgets);
        // Trigger a re-render of the widgets
        this.displayWidgets.set([...this.displayWidgets()]);
    }
    // Check if a widget is selected
    isWidgetSelected(widget) {
        return this.selectedWidgets().includes(widget);
    }
    // Check if a generic widget item is selected
    isWidgetItemSelected(widgetItem) {
        const originalWidget = widgetItem.data;
        return this.isWidgetSelected(originalWidget);
    }
    handleConfirmSelection() {
        this.close({ widgets: this.selectedWidgets() });
    }
    handleNodeClick(event) {
        const item = event.data;
        this.selectedCategory.set(item);
    }
    async handleCollapseChanged(event) {
        const item = event.data;
        const currentExpanded = this.expandedCategoryIds();
        if (item.expanded) {
            // Category was expanded - add to expanded list
            if (!currentExpanded.includes(item.id)) {
                const newExpanded = [...currentExpanded, item.id];
                this.expandedCategoryIds.set(newExpanded);
                await this.settingService.scope(AXPPlatformScope.User).set(this.expandedCategoriesKey, newExpanded);
            }
        }
        else {
            // Category was collapsed - remove from expanded list
            const newExpanded = currentExpanded.filter(id => id !== item.id);
            this.expandedCategoryIds.set(newExpanded);
            await this.settingService.scope(AXPPlatformScope.User).set(this.expandedCategoriesKey, newExpanded);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPTemplateWidgetPickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: AXPTemplateWidgetPickerComponent, isStandalone: true, selector: "ng-component", inputs: { searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchTerm: "searchTermChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"ax-flex ax-flex-col lg:ax-h-[60vh]\">\n  <div class=\"ax-p-2 ax-surface-lowest ax-border-b ax-flex-none\">\n    <ax-search-box\n      look=\"fill\"\n      placeholder=\"e.g. Button, Text, ...\"\n      class=\"ax-sm\"\n      [(ngModel)]=\"searchTerm\"\n      [delayTime]=\"300\"\n    >\n      <ax-clear-button></ax-clear-button>\n    </ax-search-box>\n  </div>\n  <div class=\"ax-flex ax-flex-grow ax-h-full\">\n    <!-- Category Tree - Hidden in search mode -->\n    @if (!isSearchMode()) {\n      <div\n        class=\"ax-flex ax-h-full ax-p-2 ax-overflow-auto ax-w-1/3 ax-justify-start ax-items-start ax-surface-lowest ax-border-e\"\n      >\n        <ax-tree-view\n          [showCheckbox]=\"false\"\n          [itemTemplate]=\"categoryTemplate\"\n          [textField]=\"'title'\"\n          [hasChildField]=\"'hasChild'\"\n          [valueField]=\"'id'\"\n          [expandedField]=\"'expanded'\"\n          [items]=\"provideLazyTreeView\"\n          (onNodeClick)=\"handleNodeClick($event)\"\n          (onCollapsedChanged)=\"handleCollapseChanged($event)\"\n          class=\"ax-w-full\"\n        >\n        </ax-tree-view>\n\n        <ng-template #categoryTemplate let-item>\n          <ax-icon class=\"fa-solid fa-folder ax-text-yellow-500 fa-fw\"></ax-icon>\n          {{ item.title | translate | async }}\n        </ng-template>\n      </div>\n    }\n\n    <!-- Widget Grid - Full width in search mode, 2/3 width otherwise -->\n    <div\n      [class]=\"\n        isSearchMode()\n          ? 'ax-flex ax-h-full ax-flex-col ax-w-full ax-overflow-hidden'\n          : 'ax-flex ax-h-full ax-flex-col ax-w-2/3 ax-overflow-hidden'\n      \"\n    >\n      @if (hasResults()) {\n        <div class=\"ax-flex ax-flex-col ax-p-4\">\n          <div class=\"ax-grid ax-grid-cols-2 ax-gap-2\">\n            @for (widgetItem of pinnedWidgetItems(); track widgetItem.title) {\n              <axp-widget-item\n                [widget]=\"widgetItem\"\n                [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n                (onWidgetClick)=\"handleWidgetClick($event)\"\n                (onPinClick)=\"handleWidgetPinClick($event)\"\n              >\n              </axp-widget-item>\n            }\n          </div>\n          @if (pinnedWidgetItems().length) {\n            <hr class=\"ax-my-4 ax-border-dashed\" />\n          }\n          <div class=\"ax-grid ax-grid-cols-2 ax-gap-2\">\n            @for (widgetItem of regularWidgetItems(); track widgetItem.title) {\n              <axp-widget-item\n                [widget]=\"widgetItem\"\n                [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n                (onWidgetClick)=\"handleWidgetClick($event)\"\n                (onPinClick)=\"handleWidgetPinClick($event)\"\n              >\n              </axp-widget-item>\n            }\n          </div>\n        </div>\n      } @else {\n        <!-- Empty State -->\n        <axp-state-message\n          icon=\"fa-light fa-search\"\n          [title]=\"'@form-template-management:template-picker.no-templates-found.title'\"\n          [description]=\"\n            isSearchMode()\n              ? '@form-template-management:template-picker.no-templates-found-search.description'\n              : '@form-template-management:template-picker.no-templates-found-category.description'\n          \"\n        >\n          @if (isSearchMode()) {\n            <ax-button\n              look=\"blank\"\n              [text]=\"'@form-template-management:template-picker.clear-search' | translate | async\"\n              class=\"ax-mt-4\"\n              (onClick)=\"searchTerm.set('')\"\n            ></ax-button>\n          }\n        </axp-state-message>\n      }\n    </div>\n  </div>\n</div>\n\n@if (selectedWidgets().length) {\n  <ax-footer>\n    <ax-suffix>\n      <ax-button\n        look=\"solid\"\n        color=\"primary\"\n        text=\"{{ selectedWidgets().length }} Selected\"\n        (onClick)=\"handleConfirmSelection()\"\n      ></ax-button>\n    </ax-suffix>\n  </ax-footer>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: 
                //
                AXCommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: i5.AXTreeViewComponent, selector: "ax-tree-view", inputs: ["items", "showCheckbox", "hasCheckboxField", "selectionMode", "selectionBehavior", "selectionScope", "focusNodeEnabled", "valueField", "textField", "visibleField", "disableField", "hasChildField", "selectedField", "expandedField", "tooltipField", "childrenField", "activeField", "indeterminateField", "parentField", "iconField", "toggleIcons", "look", "showEmptyNodeMassage", "itemTemplate", "emptyTemplate", "expandOn"], outputs: ["onSelectionChanged", "onItemSelectedChanged", "onNodeClick", "onCollapsedChanged", "onNodedbClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPWidgetItemComponent, selector: "axp-widget-item", inputs: ["widget", "isSelected", "showPinButton", "customClasses"], outputs: ["onWidgetClick", "onPinClick"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPTemplateWidgetPickerComponent, decorators: [{
            type: Component,
            args: [{ imports: [
                        CommonModule,
                        FormsModule,
                        //
                        AXCommonModule,
                        AXButtonModule,
                        AXDecoratorModule,
                        AXSearchBoxModule,
                        AXTreeViewModule,
                        AXTranslationModule,
                        AXPWidgetItemComponent,
                        AXPStateMessageComponent,
                    ], encapsulation: ViewEncapsulation.None, template: "<div class=\"ax-flex ax-flex-col lg:ax-h-[60vh]\">\n  <div class=\"ax-p-2 ax-surface-lowest ax-border-b ax-flex-none\">\n    <ax-search-box\n      look=\"fill\"\n      placeholder=\"e.g. Button, Text, ...\"\n      class=\"ax-sm\"\n      [(ngModel)]=\"searchTerm\"\n      [delayTime]=\"300\"\n    >\n      <ax-clear-button></ax-clear-button>\n    </ax-search-box>\n  </div>\n  <div class=\"ax-flex ax-flex-grow ax-h-full\">\n    <!-- Category Tree - Hidden in search mode -->\n    @if (!isSearchMode()) {\n      <div\n        class=\"ax-flex ax-h-full ax-p-2 ax-overflow-auto ax-w-1/3 ax-justify-start ax-items-start ax-surface-lowest ax-border-e\"\n      >\n        <ax-tree-view\n          [showCheckbox]=\"false\"\n          [itemTemplate]=\"categoryTemplate\"\n          [textField]=\"'title'\"\n          [hasChildField]=\"'hasChild'\"\n          [valueField]=\"'id'\"\n          [expandedField]=\"'expanded'\"\n          [items]=\"provideLazyTreeView\"\n          (onNodeClick)=\"handleNodeClick($event)\"\n          (onCollapsedChanged)=\"handleCollapseChanged($event)\"\n          class=\"ax-w-full\"\n        >\n        </ax-tree-view>\n\n        <ng-template #categoryTemplate let-item>\n          <ax-icon class=\"fa-solid fa-folder ax-text-yellow-500 fa-fw\"></ax-icon>\n          {{ item.title | translate | async }}\n        </ng-template>\n      </div>\n    }\n\n    <!-- Widget Grid - Full width in search mode, 2/3 width otherwise -->\n    <div\n      [class]=\"\n        isSearchMode()\n          ? 'ax-flex ax-h-full ax-flex-col ax-w-full ax-overflow-hidden'\n          : 'ax-flex ax-h-full ax-flex-col ax-w-2/3 ax-overflow-hidden'\n      \"\n    >\n      @if (hasResults()) {\n        <div class=\"ax-flex ax-flex-col ax-p-4\">\n          <div class=\"ax-grid ax-grid-cols-2 ax-gap-2\">\n            @for (widgetItem of pinnedWidgetItems(); track widgetItem.title) {\n              <axp-widget-item\n                [widget]=\"widgetItem\"\n                [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n                (onWidgetClick)=\"handleWidgetClick($event)\"\n                (onPinClick)=\"handleWidgetPinClick($event)\"\n              >\n              </axp-widget-item>\n            }\n          </div>\n          @if (pinnedWidgetItems().length) {\n            <hr class=\"ax-my-4 ax-border-dashed\" />\n          }\n          <div class=\"ax-grid ax-grid-cols-2 ax-gap-2\">\n            @for (widgetItem of regularWidgetItems(); track widgetItem.title) {\n              <axp-widget-item\n                [widget]=\"widgetItem\"\n                [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n                (onWidgetClick)=\"handleWidgetClick($event)\"\n                (onPinClick)=\"handleWidgetPinClick($event)\"\n              >\n              </axp-widget-item>\n            }\n          </div>\n        </div>\n      } @else {\n        <!-- Empty State -->\n        <axp-state-message\n          icon=\"fa-light fa-search\"\n          [title]=\"'@form-template-management:template-picker.no-templates-found.title'\"\n          [description]=\"\n            isSearchMode()\n              ? '@form-template-management:template-picker.no-templates-found-search.description'\n              : '@form-template-management:template-picker.no-templates-found-category.description'\n          \"\n        >\n          @if (isSearchMode()) {\n            <ax-button\n              look=\"blank\"\n              [text]=\"'@form-template-management:template-picker.clear-search' | translate | async\"\n              class=\"ax-mt-4\"\n              (onClick)=\"searchTerm.set('')\"\n            ></ax-button>\n          }\n        </axp-state-message>\n      }\n    </div>\n  </div>\n</div>\n\n@if (selectedWidgets().length) {\n  <ax-footer>\n    <ax-suffix>\n      <ax-button\n        look=\"solid\"\n        color=\"primary\"\n        text=\"{{ selectedWidgets().length }} Selected\"\n        (onClick)=\"handleConfirmSelection()\"\n      ></ax-button>\n    </ax-suffix>\n  </ax-footer>\n}\n" }]
        }] });

export { AXPTemplateWidgetPickerComponent };
//# sourceMappingURL=acorex-modules-form-template-management-template-picker.component-B_3DSrcW.mjs.map
