import * as i1$1 from '@acorex/platform/layout/widget-core';
import { AXPWidgetCoreModule, AXPValueWidgetComponent } from '@acorex/platform/layout/widget-core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, signal, computed, input, output, ViewEncapsulation, Component, ChangeDetectionStrategy } from '@angular/core';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { AXFormModule } from '@acorex/components/form';
import * as i2$1 from '@acorex/components/check-box';
import { AXCheckBoxModule } from '@acorex/components/check-box';
import { AXLabelModule } from '@acorex/components/label';
import * as i6 from '@acorex/core/translation';
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
import * as i4 from '@acorex/components/tooltip';
import { AXTooltipModule } from '@acorex/components/tooltip';
import { AXPModuleManifestRegistry } from '@acorex/platform/core';

//#region ----   Imports   ----
//#endregion
//#region ----   Features Editor Component   ----
class AXPFeaturesEditorComponent {
    constructor() {
        //#region ----   Class Properties   ----
        /** Service for fetching module manifests and feature definitions */
        this.manifestRegistry = inject(AXPModuleManifestRegistry);
        /** Translation service for loading translated titles */
        this.translationService = inject(AXTranslationService);
        /** All available module manifests with translated titles */
        this.allModules = signal([], ...(ngDevMode ? [{ debugName: "allModules" }] : []));
        /** Sorted modules by translated title */
        this.modules = computed(() => {
            const modules = [...this.allModules()];
            return modules.sort((a, b) => {
                const titleA = a.translatedTitle || a.title || '';
                const titleB = b.translatedTitle || b.title || '';
                return titleA.localeCompare(titleB, undefined, { sensitivity: 'base' });
            });
        }, ...(ngDevMode ? [{ debugName: "modules" }] : []));
        /** Initial value: { modules: string[], features: Record<string, any> } */
        this.initialValue = input({}, ...(ngDevMode ? [{ debugName: "initialValue" }] : []));
        /** Whether the editor is in read-only mode */
        this.readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : []));
        /** Selected module names */
        this.selectedModules = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedModules" }] : []));
        /** Expanded module names */
        this.expandedModules = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedModules" }] : []));
        /** Expanded feature full names */
        this.expandedFeatures = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedFeatures" }] : []));
        /** Map of feature values: Record<featureName, featureValue> */
        this.featureValues = signal({}, ...(ngDevMode ? [{ debugName: "featureValues" }] : []));
        /** Required module names (always enabled, cannot be disabled) */
        this.requiredModules = computed(() => {
            return new Set(this.allModules()
                .filter((m) => m.required === true)
                .map((m) => m.name));
        }, ...(ngDevMode ? [{ debugName: "requiredModules" }] : []));
        /** Modules that are dependencies of selected modules (auto-selected and disabled) */
        this.dependencyModules = computed(() => {
            const selected = this.selectedModules();
            const allManifests = this.manifestRegistry.getAll();
            const dependencySet = new Set();
            // Find all modules that are dependencies of selected modules
            for (const manifest of allManifests) {
                if (selected.has(manifest.name) && manifest.dependencies) {
                    for (const dep of manifest.dependencies) {
                        // Only add module dependencies (skip features which contain a dot)
                        if (!dep.includes('.')) {
                            dependencySet.add(dep);
                        }
                    }
                }
            }
            return dependencySet;
        }, ...(ngDevMode ? [{ debugName: "dependencyModules" }] : []));
        /** Event emitted when modules/features selection/values change */
        this.valueChanged = output();
        /** Cache for widget nodes to prevent re-creation and blinking */
        this.widgetNodeCache = new Map();
        /** Cache for feature data to prevent re-computation */
        this.moduleFeaturesCache = new Map();
        /** Set of modules that are currently loading features */
        this.loadingFeatures = signal(new Set(), ...(ngDevMode ? [{ debugName: "loadingFeatures" }] : []));
        /** Signal to trigger change detection when features are loaded */
        this.featuresLoaded = signal(0, ...(ngDevMode ? [{ debugName: "featuresLoaded" }] : []));
    }
    //#endregion
    //#region ----   Lifecycle Methods   ----
    /**
     * Initializes the component and loads module manifests.
     */
    async ngOnInit() {
        // Ensure registry is initialized before loading manifests
        await this.manifestRegistry.initialize();
        // Load all modules regardless of whether they have features
        const manifests = this.manifestRegistry.getAll();
        // Load translated titles for all modules
        const modulesWithTranslations = await Promise.all(manifests.map(async (manifest) => {
            const translatedTitle = await this.translationService.translateAsync(manifest.title);
            return {
                ...manifest,
                translatedTitle,
            };
        }));
        this.allModules.set(modulesWithTranslations);
        // Load initial value
        const initialValue = this.initialValue();
        const initialModules = new Set(initialValue.modules || []);
        // Extract module names from feature keys (both module-level and regular features)
        if (initialValue.features) {
            for (const featureKey of Object.keys(initialValue.features)) {
                // Extract module name from feature key (format: ModuleName:Feature:...)
                const [moduleName] = featureKey.split(':');
                if (moduleName) {
                    initialModules.add(moduleName);
                }
            }
        }
        // Always include required modules
        const requiredModules = this.requiredModules();
        requiredModules.forEach((moduleName) => {
            initialModules.add(moduleName);
        });
        // Auto-select dependencies for initially selected modules
        this.ensureDependencies(initialModules);
        this.selectedModules.set(initialModules);
        // Update dependency modules after setting selected modules
        // This ensures dependencyModules computed signal is updated
        if (initialValue.features) {
            this.featureValues.set(initialValue.features);
        }
        // Clear caches when initializing
        this.widgetNodeCache.clear();
        this.moduleFeaturesCache.clear();
    }
    //#endregion
    //#region ----   Utility Methods   ----
    /**
     * Creates or retrieves a cached widget node from feature interface definition.
     * Uses caching to prevent widget re-rendering and blinking.
     */
    createWidgetNode(definition, fullName) {
        if (!definition.interface) {
            return null;
        }
        const currentValue = this.featureValues()[fullName];
        const defaultValue = currentValue !== undefined && currentValue !== null ? currentValue : definition.defaultValue;
        // Check cache first
        let widgetNode = this.widgetNodeCache.get(fullName);
        if (!widgetNode) {
            // Create new widget node
            widgetNode = {
                type: definition.interface.type,
                name: fullName,
                defaultValue: defaultValue,
                options: definition.interface.options || {},
            };
            this.widgetNodeCache.set(fullName, widgetNode);
        }
        else {
            // Update defaultValue only if it actually changed (to prevent re-renders)
            if (widgetNode.defaultValue !== defaultValue) {
                widgetNode.defaultValue = defaultValue;
            }
            // Keep the same reference to prevent widget re-initialization
        }
        return widgetNode;
    }
    /**
     * Gets the current value (modules and features).
     */
    getValue() {
        return {
            modules: Array.from(this.selectedModules()),
            features: this.featureValues(),
        };
    }
    /**
     * Sets the value (modules and features).
     */
    setValue(value) {
        if (value.modules) {
            this.selectedModules.set(new Set(value.modules));
        }
        if (value.features) {
            this.featureValues.set(value.features);
        }
        this.emitValueChanged();
    }
    /**
     * Emits the current value.
     */
    emitValueChanged() {
        this.valueChanged.emit(this.getValue());
    }
    /**
     * Ensures all dependencies for the given modules are selected.
     * Recursively checks and adds dependencies.
     */
    ensureDependencies(modules) {
        const allManifests = this.manifestRegistry.getAll();
        let changed = true;
        while (changed) {
            changed = false;
            for (const manifest of allManifests) {
                if (modules.has(manifest.name) && manifest.dependencies) {
                    for (const dep of manifest.dependencies) {
                        // Only add module dependencies (skip features which contain a dot)
                        if (!dep.includes('.')) {
                            if (!modules.has(dep)) {
                                modules.add(dep);
                                changed = true;
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * Gets features for a module with caching to prevent re-computation.
     * Features are loaded from feature definition providers and registered in the manifest registry.
     * This method is read-only and should not update signals during template rendering.
     */
    getModuleFeatures(module) {
        // Access featuresLoaded signal to make this reactive to feature loading
        // This is a read operation, which is safe during template rendering
        this.featuresLoaded();
        // Get features from manifest registry
        const moduleFeatures = this.manifestRegistry.getModuleFeatures(module.name);
        if (moduleFeatures.length === 0) {
            return [];
        }
        const cacheKey = module.name;
        const currentValues = this.featureValues();
        // Check if we need to invalidate cache (if feature values changed)
        const cached = this.moduleFeaturesCache.get(cacheKey);
        if (cached) {
            // Update isEnabled status and widget node values without recreating objects
            cached.forEach((feature) => {
                const currentValue = currentValues[feature.fullName];
                feature.isEnabled = currentValue !== undefined && currentValue !== null;
                // Update widget node defaultValue if it exists
                if (feature.widgetNode) {
                    const newDefaultValue = currentValue !== undefined && currentValue !== null
                        ? currentValue
                        : feature.definition.defaultValue;
                    if (feature.widgetNode.defaultValue !== newDefaultValue) {
                        feature.widgetNode.defaultValue = newDefaultValue;
                    }
                }
            });
            return cached;
        }
        // Create new cache entry from registry features
        const features = moduleFeatures.map((featureDef) => {
            const fullName = featureDef.name;
            const shortKey = featureDef.key;
            const currentValue = currentValues[fullName];
            const isEnabled = currentValue !== undefined && currentValue !== null;
            const widgetNode = this.createWidgetNode(featureDef, fullName);
            return {
                key: shortKey,
                fullName,
                definition: featureDef,
                isEnabled,
                widgetNode,
            };
        });
        this.moduleFeaturesCache.set(cacheKey, features);
        return features;
    }
    /**
     * Loads features for a module.
     * Features are already loaded and registered during manifest registry initialization,
     * so this method just triggers cache invalidation for change detection.
     */
    async loadModuleFeatures(module) {
        try {
            // Features are already loaded during manifest registry initialization
            // Just clear cache to force re-computation
            this.moduleFeaturesCache.delete(module.name);
            // Trigger change detection
            this.featuresLoaded.update(v => v + 1);
        }
        finally {
            // Remove from loading set
            this.loadingFeatures.update(set => {
                const newSet = new Set(set);
                newSet.delete(module.name);
                return newSet;
            });
        }
    }
    //#endregion
    //#region ----   UI Handlers   ----
    /**
     * Toggles module expansion.
     */
    toggleModule(module) {
        const moduleName = module.name;
        const expanded = new Set(this.expandedModules());
        if (expanded.has(moduleName)) {
            expanded.delete(moduleName);
        }
        else {
            expanded.add(moduleName);
            // Features are already loaded during manifest registry initialization
            // Just trigger cache refresh if needed
            if (!this.loadingFeatures().has(moduleName)) {
                this.loadingFeatures.update(set => new Set(set).add(moduleName));
                this.loadModuleFeatures(module).catch(error => {
                    console.error(`Failed to refresh features for module ${moduleName}:`, error);
                });
            }
        }
        this.expandedModules.set(expanded);
    }
    /**
     * Toggles feature expansion.
     */
    toggleFeature(fullName) {
        const expanded = new Set(this.expandedFeatures());
        if (expanded.has(fullName)) {
            expanded.delete(fullName);
        }
        else {
            expanded.add(fullName);
        }
        this.expandedFeatures.set(expanded);
    }
    /**
     * Checks if module is expanded.
     */
    isModuleExpanded(moduleName) {
        return this.expandedModules().has(moduleName);
    }
    /**
     * Checks if feature is expanded.
     */
    isFeatureExpanded(fullName) {
        return this.expandedFeatures().has(fullName);
    }
    /**
     * Checks if module is selected.
     * A module is considered selected if:
     * 1. It's in the selectedModules set, OR
     * 2. The module name is enabled as a feature (module name itself is used as feature key)
     */
    isModuleSelected(moduleName) {
        if (this.selectedModules().has(moduleName)) {
            return true;
        }
        // Check if module name is enabled as a feature
        const featureValue = this.featureValues()[moduleName];
        return featureValue !== undefined && featureValue !== null;
    }
    /**
     * Checks if module is required (always enabled, cannot be disabled).
     */
    isModuleRequired(moduleName) {
        return this.requiredModules().has(moduleName);
    }
    /**
     * Checks if module is a dependency of other selected modules (auto-selected and disabled).
     */
    isModuleDependency(moduleName) {
        return this.dependencyModules().has(moduleName);
    }
    /**
     * Checks if module should be disabled (required or dependency).
     */
    isModuleDisabled(moduleName) {
        return this.isModuleRequired(moduleName) || this.isModuleDependency(moduleName);
    }
    /**
     * Checks if module can be enabled (dependencies are satisfied).
     */
    canEnableModule(moduleName) {
        const manifest = this.manifestRegistry.get(moduleName);
        if (!manifest?.dependencies || manifest.dependencies.length === 0) {
            return true;
        }
        const selected = this.selectedModules();
        // Only check module dependencies (skip features which contain a dot)
        const moduleDeps = manifest.dependencies.filter((dep) => !dep.includes('.'));
        return moduleDeps.every((dep) => selected.has(dep));
    }
    /**
     * Gets missing dependencies for a module.
     */
    getMissingDependencies(moduleName) {
        const manifest = this.manifestRegistry.get(moduleName);
        if (!manifest?.dependencies || manifest.dependencies.length === 0) {
            return [];
        }
        const selected = this.selectedModules();
        // Only check module dependencies (skip features which contain a dot)
        const moduleDeps = manifest.dependencies.filter((dep) => !dep.includes('.'));
        return moduleDeps.filter((dep) => !selected.has(dep));
    }
    /**
     * Gets modules that depend on the given module.
     */
    getDependentModules(moduleName) {
        const allManifests = this.manifestRegistry.getAll();
        return allManifests
            .filter((m) => m.dependencies?.includes(moduleName))
            .map((m) => m.name);
    }
    /**
     * Gets the tooltip text for a dependency module showing which modules depend on it.
     */
    getDependencyTooltip(moduleName) {
        const dependentModules = this.getDependentModules(moduleName);
        const selectedDependents = dependentModules.filter((m) => this.isModuleSelected(m));
        if (selectedDependents.length === 0) {
            return 'Required dependency';
        }
        return `Required dependency of: ${selectedDependents.join(', ')}`;
    }
    /**
     * Gets the icon class for a module, with fallback to default cube icon.
     */
    getModuleIcon(module) {
        return module.icon || 'fa-light fa-cube';
    }
    /**
     * Checks if module has features.
     * Returns true if features are already loaded.
     * Features are loaded from feature definition providers on-demand.
     */
    hasModuleFeatures(module) {
        const moduleFeatures = this.manifestRegistry.getModuleFeatures(module.name);
        // If features are already loaded, return true
        return moduleFeatures.length > 0;
    }
    /**
     * Handles module checkbox toggle.
     * When enabled, enables the module name as a feature (module name itself is used as feature key).
     * When disabled, removes the module name feature.
     */
    onModuleToggle(module, event) {
        if (this.readOnly() || this.isModuleDisabled(module.name)) {
            return;
        }
        const selectedModules = new Set(this.selectedModules());
        const currentValues = { ...this.featureValues() };
        if (event.value) {
            selectedModules.add(module.name);
            // Enable module name as feature (module name itself is used as feature key)
            currentValues[module.name] = true;
            // Auto-select dependencies recursively
            this.ensureDependencies(selectedModules);
            // Features are already loaded during manifest registry initialization
            // Just trigger cache refresh if needed
            if (!this.loadingFeatures().has(module.name)) {
                setTimeout(() => {
                    this.loadingFeatures.update(set => new Set(set).add(module.name));
                    this.loadModuleFeatures(module).catch(error => {
                        console.error(`Failed to refresh features for module ${module.name}:`, error);
                        this.loadingFeatures.update(set => {
                            const newSet = new Set(set);
                            newSet.delete(module.name);
                            return newSet;
                        });
                    });
                }, 0);
            }
        }
        else {
            // Check if other modules depend on this one
            const dependentModules = this.getDependentModules(module.name);
            const hasSelectedDependents = dependentModules.some((dep) => selectedModules.has(dep));
            if (hasSelectedDependents) {
                // Don't allow disabling if other selected modules depend on it
                return;
            }
            selectedModules.delete(module.name);
            // Remove module name feature when module is deselected
            delete currentValues[module.name];
        }
        this.selectedModules.set(selectedModules);
        this.featureValues.set(currentValues);
        this.emitValueChanged();
    }
    /**
     * Handles feature checkbox toggle.
     */
    onFeatureToggle(feature, event) {
        if (this.readOnly()) {
            return;
        }
        const currentValues = { ...this.featureValues() };
        if (event.value) {
            // Enable feature - use default value if not set
            if (currentValues[feature.fullName] === undefined || currentValues[feature.fullName] === null) {
                currentValues[feature.fullName] = feature.definition.defaultValue;
            }
        }
        else {
            // Disable feature - remove from values
            delete currentValues[feature.fullName];
        }
        this.featureValues.set(currentValues);
        this.emitValueChanged();
    }
    /**
     * Handles feature widget value change.
     */
    onFeatureValueChange(featureFullName, value) {
        if (this.readOnly()) {
            return;
        }
        const currentValues = { ...this.featureValues() };
        currentValues[featureFullName] = value;
        this.featureValues.set(currentValues);
        this.emitValueChanged();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPFeaturesEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AXPFeaturesEditorComponent, isStandalone: true, selector: "axm-features-editor", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChanged: "valueChanged" }, host: { classAttribute: "ax-flex" }, ngImport: i0, template: "<div class=\"ax-px-3 ax-py-6\">\n  <div class=\"ax-flex ax-flex-col ax-gap-3\">\n    @for (module of modules(); track module.name) {\n    <ng-container *ngTemplateOutlet=\"moduleTemplate; context: { $implicit: module, level: 0 }\">\n    </ng-container>\n    }\n  </div>\n</div>\n\n<!-- Module Template -->\n<ng-template #moduleTemplate let-module let-level=\"level\">\n  <div class=\"ax-flex ax-flex-col\">\n    <!-- Module Row -->\n    <div class=\"ax-flex ax-items-center ax-gap-3 ax-rounded hover:ax-bg-surface-lowest\"\n      [style.padding-left.px]=\"level * 32\">\n      <!-- Spacer for alignment -->\n      <span class=\"ax-w-4\"></span>\n\n      <!-- Module Checkbox -->\n      <ax-check-box [ngModel]=\"isModuleSelected(module.name)\" [readonly]=\"readOnly() || isModuleDisabled(module.name)\"\n        [class.ax-opacity-50]=\"isModuleDependency(module.name) && !isModuleRequired(module.name)\"\n        (onValueChanged)=\"onModuleToggle(module, $event)\" (click)=\"$event.stopPropagation()\">\n      </ax-check-box>\n\n      <!-- Module Icon -->\n      <i [class]=\"getModuleIcon(module) + ' ax-text-primary fa-fw'\"></i>\n\n      <!-- Module Title -->\n      <span class=\"ax-flex-1 ax-font-semibold\">{{ module.title | translate | async }}</span>\n\n      <!-- Required Badge -->\n      @if (isModuleRequired(module.name)) {\n      <span class=\"ax-text-xs ax-text-primary ax-font-medium\" [axTooltip]=\"'Required module'\">\n        (Required)\n      </span>\n      }\n\n      <!-- Dependency Badge -->\n      @if (isModuleDependency(module.name) && !isModuleRequired(module.name)) {\n      <span class=\"ax-text-xs ax-text-secondary ax-font-medium\" [axTooltip]=\"getDependencyTooltip(module.name)\">\n        (Dependency)\n      </span>\n      }\n    </div>\n\n    <!-- Features (shown when module is checked and has features) -->\n    @if (isModuleSelected(module.name) && hasModuleFeatures(module)) {\n    <div class=\"ax-flex ax-flex-col ax-gap-3 ax-py-6 ax-px-3\">\n      @for (feature of getModuleFeatures(module); track feature.fullName) {\n      <ng-container\n        *ngTemplateOutlet=\"featureTemplate; context: { $implicit: feature, module: module, level: level + 1 }\">\n      </ng-container>\n      }\n    </div>\n    }\n  </div>\n</ng-template>\n\n<!-- Feature Template -->\n<ng-template #featureTemplate let-feature let-module=\"module\" let-level=\"level\">\n  <div class=\"ax-flex ax-flex-col\">\n    <!-- Feature Row -->\n    <div class=\"ax-flex ax-items-start ax-gap-3 ax-rounded hover:ax-bg-surface-lowest\"\n      [style.padding-left.px]=\"level * 32\">\n      <!-- Spacer for alignment -->\n      <span class=\"ax-w-4\"></span>\n\n      <!-- Feature Checkbox -->\n      <ax-check-box [ngModel]=\"feature.isEnabled\" [readonly]=\"readOnly()\"\n        (onValueChanged)=\"onFeatureToggle(feature, $event)\" (click)=\"$event.stopPropagation()\"></ax-check-box>\n\n      <!-- Feature Content (Icon, Title, Description) -->\n      <div class=\"ax-flex ax-flex-col ax-flex-1 ax-gap-1.5\">\n        <div class=\"ax-flex ax-items-center ax-gap-2\">\n          <!-- Feature Icon -->\n          <i class=\"fa-light fa-toggle-on ax-text-secondary\"></i>\n          <!-- Feature Title -->\n          <span class=\"ax-font-semibold\">{{ feature.definition.title | translate | async }}</span>\n        </div>\n\n        <!-- Feature Description -->\n        @if (feature.definition.description) {\n        <div class=\"ax-text-sm ax-text-muted ax-ms-6 ax-leading-relaxed\">\n          {{ feature.definition.description | translate | async }}\n        </div>\n        }\n        <!-- Widget (shown when feature is enabled and has widget) -->\n        @if (feature.isEnabled && feature.widgetNode) {\n        <div class=\"ax-mt-3 ax-ms-6 ax-sm\">\n          <ng-container axp-widget-renderer [node]=\"feature.widgetNode\" [mode]=\"readOnly() ? 'view' : 'edit'\"\n            (onValueChanged)=\"onFeatureValueChange(feature.fullName, $event.widget.getValue())\">\n          </ng-container>\n        </div>\n        }\n      </div>\n    </div>\n\n\n  </div>\n</ng-template>", styles: [".axm-features-editor{display:flex;height:100%;flex-direction:column}.axm-features-editor .__modules .__tabs{height:100%}.axm-features-editor .__features .__header .__title{font-size:1rem;font-weight:500;line-height:1rem}.axm-features-editor .__features .__content .__feature-item{width:100%}.axm-features-editor .__features .__content .__feature-item .__feature-widget{border-left-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lighter-surface),var(--tw-border-opacity, 1));padding-left:1rem}\n"], dependencies: [{ kind: "ngmodule", type: 
                // Angular
                CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: 
                // ACoreX
                AXFormModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$1.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i4.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "ngmodule", type: 
                // Widget Renderer
                AXPWidgetCoreModule }, { kind: "directive", type: i1$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPFeaturesEditorComponent, decorators: [{
            type: Component,
            args: [{ selector: 'axm-features-editor', imports: [
                        // Angular
                        CommonModule,
                        FormsModule,
                        // ACoreX
                        AXFormModule,
                        AXCheckBoxModule,
                        AXLabelModule,
                        AXTranslationModule,
                        AXTooltipModule,
                        // Widget Renderer
                        AXPWidgetCoreModule,
                    ], encapsulation: ViewEncapsulation.None, host: {
                        class: 'ax-flex',
                    }, template: "<div class=\"ax-px-3 ax-py-6\">\n  <div class=\"ax-flex ax-flex-col ax-gap-3\">\n    @for (module of modules(); track module.name) {\n    <ng-container *ngTemplateOutlet=\"moduleTemplate; context: { $implicit: module, level: 0 }\">\n    </ng-container>\n    }\n  </div>\n</div>\n\n<!-- Module Template -->\n<ng-template #moduleTemplate let-module let-level=\"level\">\n  <div class=\"ax-flex ax-flex-col\">\n    <!-- Module Row -->\n    <div class=\"ax-flex ax-items-center ax-gap-3 ax-rounded hover:ax-bg-surface-lowest\"\n      [style.padding-left.px]=\"level * 32\">\n      <!-- Spacer for alignment -->\n      <span class=\"ax-w-4\"></span>\n\n      <!-- Module Checkbox -->\n      <ax-check-box [ngModel]=\"isModuleSelected(module.name)\" [readonly]=\"readOnly() || isModuleDisabled(module.name)\"\n        [class.ax-opacity-50]=\"isModuleDependency(module.name) && !isModuleRequired(module.name)\"\n        (onValueChanged)=\"onModuleToggle(module, $event)\" (click)=\"$event.stopPropagation()\">\n      </ax-check-box>\n\n      <!-- Module Icon -->\n      <i [class]=\"getModuleIcon(module) + ' ax-text-primary fa-fw'\"></i>\n\n      <!-- Module Title -->\n      <span class=\"ax-flex-1 ax-font-semibold\">{{ module.title | translate | async }}</span>\n\n      <!-- Required Badge -->\n      @if (isModuleRequired(module.name)) {\n      <span class=\"ax-text-xs ax-text-primary ax-font-medium\" [axTooltip]=\"'Required module'\">\n        (Required)\n      </span>\n      }\n\n      <!-- Dependency Badge -->\n      @if (isModuleDependency(module.name) && !isModuleRequired(module.name)) {\n      <span class=\"ax-text-xs ax-text-secondary ax-font-medium\" [axTooltip]=\"getDependencyTooltip(module.name)\">\n        (Dependency)\n      </span>\n      }\n    </div>\n\n    <!-- Features (shown when module is checked and has features) -->\n    @if (isModuleSelected(module.name) && hasModuleFeatures(module)) {\n    <div class=\"ax-flex ax-flex-col ax-gap-3 ax-py-6 ax-px-3\">\n      @for (feature of getModuleFeatures(module); track feature.fullName) {\n      <ng-container\n        *ngTemplateOutlet=\"featureTemplate; context: { $implicit: feature, module: module, level: level + 1 }\">\n      </ng-container>\n      }\n    </div>\n    }\n  </div>\n</ng-template>\n\n<!-- Feature Template -->\n<ng-template #featureTemplate let-feature let-module=\"module\" let-level=\"level\">\n  <div class=\"ax-flex ax-flex-col\">\n    <!-- Feature Row -->\n    <div class=\"ax-flex ax-items-start ax-gap-3 ax-rounded hover:ax-bg-surface-lowest\"\n      [style.padding-left.px]=\"level * 32\">\n      <!-- Spacer for alignment -->\n      <span class=\"ax-w-4\"></span>\n\n      <!-- Feature Checkbox -->\n      <ax-check-box [ngModel]=\"feature.isEnabled\" [readonly]=\"readOnly()\"\n        (onValueChanged)=\"onFeatureToggle(feature, $event)\" (click)=\"$event.stopPropagation()\"></ax-check-box>\n\n      <!-- Feature Content (Icon, Title, Description) -->\n      <div class=\"ax-flex ax-flex-col ax-flex-1 ax-gap-1.5\">\n        <div class=\"ax-flex ax-items-center ax-gap-2\">\n          <!-- Feature Icon -->\n          <i class=\"fa-light fa-toggle-on ax-text-secondary\"></i>\n          <!-- Feature Title -->\n          <span class=\"ax-font-semibold\">{{ feature.definition.title | translate | async }}</span>\n        </div>\n\n        <!-- Feature Description -->\n        @if (feature.definition.description) {\n        <div class=\"ax-text-sm ax-text-muted ax-ms-6 ax-leading-relaxed\">\n          {{ feature.definition.description | translate | async }}\n        </div>\n        }\n        <!-- Widget (shown when feature is enabled and has widget) -->\n        @if (feature.isEnabled && feature.widgetNode) {\n        <div class=\"ax-mt-3 ax-ms-6 ax-sm\">\n          <ng-container axp-widget-renderer [node]=\"feature.widgetNode\" [mode]=\"readOnly() ? 'view' : 'edit'\"\n            (onValueChanged)=\"onFeatureValueChange(feature.fullName, $event.widget.getValue())\">\n          </ng-container>\n        </div>\n        }\n      </div>\n    </div>\n\n\n  </div>\n</ng-template>", styles: [".axm-features-editor{display:flex;height:100%;flex-direction:column}.axm-features-editor .__modules .__tabs{height:100%}.axm-features-editor .__features .__header .__title{font-size:1rem;font-weight:500;line-height:1rem}.axm-features-editor .__features .__content .__feature-item{width:100%}.axm-features-editor .__features .__content .__feature-item .__feature-widget{border-left-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lighter-surface),var(--tw-border-opacity, 1));padding-left:1rem}\n"] }]
        }], propDecorators: { initialValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValue", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], valueChanged: [{ type: i0.Output, args: ["valueChanged"] }] } });

class AXPModuleFeatureEditorWidgetEditComponent extends AXPValueWidgetComponent {
    // #region ----------------   UI Handlers   ----------------
    /**
     * Handles value changes from the editor.
     */
    onEditorValueChanged(value) {
        this.setValue(value);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPModuleFeatureEditorWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: AXPModuleFeatureEditorWidgetEditComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
    <axm-features-editor
      [initialValue]="getValue() || {}"
      [readOnly]="false"
      (valueChanged)="onEditorValueChanged($event)">
    </axm-features-editor>
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: 
                // Angular
                CommonModule }, { kind: "component", type: 
                // Local
                AXPFeaturesEditorComponent, selector: "axm-features-editor", inputs: ["initialValue", "readOnly"], outputs: ["valueChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPModuleFeatureEditorWidgetEditComponent, decorators: [{
            type: Component,
            args: [{
                    template: `
    <axm-features-editor
      [initialValue]="getValue() || {}"
      [readOnly]="false"
      (valueChanged)="onEditorValueChanged($event)">
    </axm-features-editor>
  `,
                    standalone: true,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    imports: [
                        // Angular
                        CommonModule,
                        // Local
                        AXPFeaturesEditorComponent
                    ]
                }]
        }] });

export { AXPModuleFeatureEditorWidgetEditComponent };
//# sourceMappingURL=acorex-modules-application-management-features-widget-edit.component-ggFf9p9g.mjs.map
