import * as i3 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, input, output, signal, computed, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
import { AXPSpreadsheetComponent } from '@acorex/platform/layout/components';
import { AXPWidgetsList } from '@acorex/modules/common';
import { AXPEntityService, AXPEntityDataSelectorService, AXPEntityDefinitionRegistryService } from '@acorex/platform/layout/entity';
import { RootConfig } from './acorex-modules-organization-management.mjs';
import * as i1 from '@acorex/components/button';
import { AXButtonModule } from '@acorex/components/button';
import * as i2 from '@acorex/components/decorators';
import { AXDecoratorModule } from '@acorex/components/decorators';
import * as i4 from '@acorex/core/translation';
import { AXTranslationModule } from '@acorex/core/translation';

//#region ----   Imports   ----
//#endregion
//#region ----   Component Definition   ----
class AXMOrganizationManagementResponsibilitiesMatrixComponent {
    //#endregion
    //#region ----   Lifecycle Methods   ----
    constructor() {
        //#endregion
        //#region ----   Services & Dependencies   ----
        this.entityService = inject(AXPEntityService);
        this.responsibilityLevelDataAccessor = this.entityService
            .withEntity(RootConfig.module.name, RootConfig.entities.responsibilityLevel.name)
            .data();
        this.responsibilityDataAccessor = this.entityService
            .withEntity(RootConfig.module.name, RootConfig.entities.responsibility.name)
            .data();
        this.entityDataSelectorService = inject(AXPEntityDataSelectorService);
        this.entityResolver = inject(AXPEntityDefinitionRegistryService);
        //#endregion
        //#region ----   Inputs   ----
        /**
         * Array of job levels to display as columns (e.g., Junior, Mid-Level, Senior)
         */
        this.titles = input([], ...(ngDevMode ? [{ debugName: "titles" }] : []));
        /**
         * Initial matrix data: { [responsibilityId]: { [title.id]: responsibilityLevelId } }
         */
        this.value = input({}, ...(ngDevMode ? [{ debugName: "value" }] : []));
        /**
         * Whether the matrix is in readonly mode
         */
        this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
        /**
         * Initial responsibility IDs (for syncing with parent entity)
         */
        this.responsibilityIds = input([], ...(ngDevMode ? [{ debugName: "responsibilityIds" }] : []));
        //#endregion
        //#region ----   Outputs   ----
        /**
         * Emitted when the matrix value changes
         */
        this.valueChange = output();
        /**
         * Emitted when a single cell value changes
         */
        this.cellChange = output();
        /**
         * Emitted when selected responsibilities change (responsibility IDs array)
         */
        this.responsibilityIdsChange = output();
        //#endregion
        //#region ----   Class Properties   ----
        /**
         * Responsibility levels loaded from the service
         */
        this.responsibilityLevels = signal([], ...(ngDevMode ? [{ debugName: "responsibilityLevels" }] : []));
        /**
         * Selected responsibilities (internal state)
         */
        this.selectedResponsibilities = signal([], ...(ngDevMode ? [{ debugName: "selectedResponsibilities" }] : []));
        /**
         * Responsibility entity definition
         */
        this.responsibilityEntityDef = signal(null, ...(ngDevMode ? [{ debugName: "responsibilityEntityDef" }] : []));
        /**
         * Loading state
         */
        this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
        /**
         * Loading state for responsibility entity
         */
        this.isLoadingResponsibilityEntity = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingResponsibilityEntity" }] : []));
        //#endregion
        //#region ----   Computed Properties   ----
        /**
         * Vertical titles (responsibilities) - rows of the matrix
         */
        this.verticalTitles = computed(() => {
            const responsibilities = this.selectedResponsibilities();
            const result = (responsibilities ?? []).map((responsibility) => ({
                id: responsibility.id,
                title: responsibility.title,
                description: responsibility.description || undefined,
            }));
            return result;
        }, ...(ngDevMode ? [{ debugName: "verticalTitles" }] : []));
        /**
         * Horizontal titles (job levels) - columns of the matrix
         */
        this.horizontalTitles = computed(() => {
            const titlesInput = this.titles();
            const result = (titlesInput ?? []).map((title) => ({
                id: title.id,
                title: title.title,
                description: title.description || undefined,
            }));
            return result;
        }, ...(ngDevMode ? [{ debugName: "horizontalTitles" }] : []));
        /**
         * Cell options (responsibility levels) - dropdown options for each cell, loaded from service
         */
        this.cellOptions = computed(() => {
            const levels = this.responsibilityLevels();
            const result = (levels ?? []).map((level) => ({
                id: level.id,
                title: level.title,
                description: level.description || undefined,
            }));
            return result;
        }, ...(ngDevMode ? [{ debugName: "cellOptions" }] : []));
        /**
         * Spreadsheet columns - converted from horizontalTitles (job levels)
         */
        this.spreadsheetColumns = computed(() => {
            const horizontalTitles = this.horizontalTitles();
            const cellOptions = this.cellOptions();
            // Create SelectBox widget configuration for responsibility levels
            const selectBoxWidget = {
                type: AXPWidgetsList.Editors.SelectBox,
                options: {
                    valueField: 'id',
                    textField: 'title',
                    dataSource: cellOptions.map((option) => ({
                        id: option.id,
                        title: option.title,
                        description: option.description,
                    })),
                },
            };
            // Convert horizontal titles to columns
            return horizontalTitles.map((title) => ({
                name: title.id,
                title: title.title,
                description: title.description,
                path: title.id, // Path to access the value in row object
                widget: selectBoxWidget,
            }));
        }, ...(ngDevMode ? [{ debugName: "spreadsheetColumns" }] : []));
        /**
         * Spreadsheet rows - converted from matrix data and vertical titles
         */
        this.spreadsheetRows = computed(() => {
            const verticalTitles = this.verticalTitles();
            const horizontalTitles = this.horizontalTitles();
            const matrixData = this.value();
            // Convert matrix data to spreadsheet rows
            return verticalTitles.map((responsibility) => {
                const row = {
                    name: responsibility.id, // Required for fixed mode row identification
                    _responsibilityTitle: responsibility.title, // For row header display
                    _responsibilityDescription: responsibility.description, // For row header description
                };
                // Add cell values for each horizontal title (column)
                horizontalTitles.forEach((title) => {
                    const cellValue = matrixData[responsibility.id]?.[title.id] ?? null;
                    row[title.id] = cellValue;
                });
                return row;
            });
        }, ...(ngDevMode ? [{ debugName: "spreadsheetRows" }] : []));
        // Load responsibility levels and responsibility entity definition when component initializes
        this.loadResponsibilityLevels();
        this.loadResponsibilityEntityDef();
        // Watch for responsibilityIds input changes and sync selected responsibilities
        effect(() => {
            const ids = this.responsibilityIds();
            if (ids && ids.length > 0 && this.responsibilityEntityDef()) {
                this.loadResponsibilitiesByIds(ids);
            }
            else if (!ids || ids.length === 0) {
                // Try to extract responsibility IDs from matrix data keys
                const matrixData = this.value();
                const responsibilityIdsFromMatrix = Object.keys(matrixData || {});
                if (responsibilityIdsFromMatrix.length > 0 && this.responsibilityEntityDef()) {
                    this.loadResponsibilitiesByIds(responsibilityIdsFromMatrix);
                }
                else {
                    this.selectedResponsibilities.set([]);
                }
            }
        });
        // Watch for matrix value changes and extract responsibility IDs
        effect(() => {
            const matrixData = this.value();
            const currentResponsibilityIds = this.selectedResponsibilities().map((r) => r.id);
            const responsibilityIdsFromMatrix = Object.keys(matrixData || {});
            // If matrix has responsibilities that aren't in selectedResponsibilities, load them
            const missingIds = responsibilityIdsFromMatrix.filter((id) => !currentResponsibilityIds.includes(id));
            if (missingIds.length > 0 && this.responsibilityEntityDef()) {
                this.loadResponsibilitiesByIds(missingIds);
            }
        });
    }
    //#endregion
    //#region ----   Data Loading Methods   ----
    /**
     * Load responsibility levels from the service
     */
    async loadResponsibilityLevels() {
        try {
            this.isLoading.set(true);
            const query = {
                skip: 0,
                take: 1000,
                sort: [{ field: 'level', dir: 'asc' }],
            };
            const result = await this.responsibilityLevelDataAccessor.query(query);
            this.responsibilityLevels.set(result.items || []);
        }
        catch (error) {
            console.error('Error loading responsibility levels:', error);
            this.responsibilityLevels.set([]);
        }
        finally {
            this.isLoading.set(false);
        }
    }
    /**
     * Load responsibility entity definition
     */
    async loadResponsibilityEntityDef() {
        try {
            this.isLoadingResponsibilityEntity.set(true);
            const entityDef = await this.entityResolver.resolve(RootConfig.module.name, RootConfig.entities.responsibility.name);
            this.responsibilityEntityDef.set(entityDef);
        }
        catch (error) {
            console.error('Error loading responsibility entity definition:', error);
            this.responsibilityEntityDef.set(null);
        }
        finally {
            this.isLoadingResponsibilityEntity.set(false);
        }
    }
    /**
     * Load responsibilities by IDs
     */
    async loadResponsibilitiesByIds(ids) {
        try {
            const responsibilities = [];
            for (const id of ids) {
                try {
                    const responsibility = await this.responsibilityDataAccessor.byKey(id);
                    if (responsibility) {
                        responsibilities.push(responsibility);
                    }
                }
                catch (error) {
                    console.error(`Error loading responsibility ${id}:`, error);
                }
            }
            this.selectedResponsibilities.set(responsibilities);
        }
        catch (error) {
            console.error('Error loading responsibilities by IDs:', error);
        }
    }
    //#endregion
    //#region ----   Data Transformation Methods   ----
    /**
     * Convert spreadsheet rows back to matrix data format
     */
    convertSpreadsheetRowsToMatrixData(rows) {
        const horizontalTitles = this.horizontalTitles();
        const matrixData = {};
        rows.forEach((row) => {
            const responsibilityId = row['name']; // Row identifier (responsibility ID)
            if (!responsibilityId) {
                return;
            }
            matrixData[responsibilityId] = {};
            // Extract cell values for each column
            horizontalTitles.forEach((title) => {
                const cellValue = row[title.id] ?? null;
                matrixData[responsibilityId][title.id] = cellValue;
            });
        });
        return matrixData;
    }
    //#endregion
    //#region ----   Event Handlers   ----
    /**
     * Handle spreadsheet change event - convert to matrix format
     */
    handleSpreadsheetChange(rows) {
        const matrixData = this.convertSpreadsheetRowsToMatrixData(rows);
        this.valueChange.emit(matrixData);
        // Extract responsibility IDs from row names and emit
        const responsibilityIds = rows.map((row) => row['name']).filter((id) => id != null);
        this.responsibilityIdsChange.emit(responsibilityIds);
    }
    /**
     * Handle cell change event from spreadsheet
     */
    handleCellChange(event) {
        this.cellChange.emit(event);
    }
    /**
     * Open responsibility selector dialog
     */
    async handleSelectResponsibilities() {
        const entityDef = this.responsibilityEntityDef();
        if (!entityDef) {
            console.error('Responsibility entity definition not loaded');
            return;
        }
        try {
            // Get currently selected responsibility IDs
            const selectedItemIds = this.selectedResponsibilities()
                .map((responsibility) => responsibility.id)
                .filter((id) => id != null);
            const result = await this.entityDataSelectorService.open({
                entity: entityDef,
                title: 'Select Responsibilities',
                allowMultiple: true,
                selectedItemIds: selectedItemIds.length > 0 ? selectedItemIds : undefined,
            });
            if (result && result.items && result.items.length > 0) {
                // Update selected responsibilities
                this.selectedResponsibilities.set(result.items);
                // Emit responsibility IDs change
                const responsibilityIds = result.items.map((item) => item.id).filter((id) => id != null);
                this.responsibilityIdsChange.emit(responsibilityIds);
            }
        }
        catch (error) {
            console.error('Error opening responsibility selector:', error);
        }
    }
    /**
     * Remove a responsibility from selection
     */
    handleRemoveResponsibility(responsibilityId) {
        const currentResponsibilities = this.selectedResponsibilities();
        const updatedResponsibilities = currentResponsibilities.filter((responsibility) => responsibility.id !== responsibilityId);
        this.selectedResponsibilities.set(updatedResponsibilities);
        // Remove responsibility data from matrix value
        const currentMatrixData = this.value();
        const updatedMatrixData = { ...currentMatrixData };
        delete updatedMatrixData[responsibilityId];
        // Emit updated matrix data
        this.valueChange.emit(updatedMatrixData);
        // Emit responsibility IDs change
        const responsibilityIds = updatedResponsibilities.map((r) => r.id).filter((id) => id != null);
        this.responsibilityIdsChange.emit(responsibilityIds);
    }
    /**
     * Handle row change event from spreadsheet (add/remove)
     */
    handleRowChange(event) {
        if (event.type === 'remove') {
            // Remove responsibility from selection
            this.handleRemoveResponsibility(event.rowId);
        }
        // Note: 'add' type shouldn't happen in fixed mode, but if it does, we can handle it here
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMOrganizationManagementResponsibilitiesMatrixComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AXMOrganizationManagementResponsibilitiesMatrixComponent, isStandalone: true, selector: "axm-responsibilities-matrix", inputs: { titles: { classPropertyName: "titles", publicName: "titles", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, responsibilityIds: { classPropertyName: "responsibilityIds", publicName: "responsibilityIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", cellChange: "cellChange", responsibilityIdsChange: "responsibilityIdsChange" }, host: { classAttribute: "axm-responsibilities-matrix" }, ngImport: i0, template: "<div class=\"__container\">\n  <div class=\"__matrix-section\">\n    <div class=\"__matrix-header ax-sm\">\n      @if (!readonly()) {\n      <ax-button color=\"primary\"\n        [text]=\"'@organization-management:job-definitions.components.responsibilities-matrix.actions.choose-responsibilities.title' | translate | async\"\n        (onClick)=\"handleSelectResponsibilities()\" [disabled]=\"isLoadingResponsibilityEntity()\">\n        <ax-icon icon=\"far fa-plus\"></ax-icon>\n      </ax-button>\n      }\n    </div>\n    @if (isLoading()) {\n    <div class=\"__loading\">\n      <span>{{ '@organization-management:job-definitions.components.responsibilities-matrix.messages.loading-responsibility-levels' | translate | async\n        }}</span>\n    </div>\n    } @else {\n    <axp-spreadsheet [title]=\"'Responsibility / Level'\" [columns]=\"spreadsheetColumns()\" [rowsInput]=\"spreadsheetRows()\"\n      [rowMode]=\"'fixed'\" [readonly]=\"readonly()\" [allowRemoveRows]=\"true\" [rowTitlePath]=\"'_responsibilityTitle'\"\n      [rowDescriptionPath]=\"'_responsibilityDescription'\" (cellChange)=\"handleCellChange($event)\"\n      (spreadsheetChange)=\"handleSpreadsheetChange($event)\" (rowChange)=\"handleRowChange($event)\"></axp-spreadsheet>\n    }\n  </div>\n</div>\n", styles: [".axm-responsibilities-matrix{display:block;height:100%;width:100%}.axm-responsibilities-matrix .__container,.axm-responsibilities-matrix .__matrix-section{display:flex;flex-direction:column}.axm-responsibilities-matrix .__matrix-header{margin-bottom:.75rem;display:flex;justify-content:flex-end}.axm-responsibilities-matrix .__loading{display:flex;align-items:center;justify-content:center;padding:2rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPSpreadsheetComponent, selector: "axp-spreadsheet", inputs: ["title", "columns", "rowMode", "rowsInput", "rowsModel", "readonly", "emptyCellPlaceholder", "rowTitlePath", "rowDescriptionPath", "allowAddRows", "allowRemoveRows"], outputs: ["rowsModelChange", "cellChange", "rowChange", "spreadsheetChange"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.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: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMOrganizationManagementResponsibilitiesMatrixComponent, decorators: [{
            type: Component,
            args: [{ selector: 'axm-responsibilities-matrix', standalone: true, imports: [
                        CommonModule,
                        AXPSpreadsheetComponent,
                        AXButtonModule,
                        AXDecoratorModule,
                        AXTranslationModule,
                    ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        class: 'axm-responsibilities-matrix',
                    }, template: "<div class=\"__container\">\n  <div class=\"__matrix-section\">\n    <div class=\"__matrix-header ax-sm\">\n      @if (!readonly()) {\n      <ax-button color=\"primary\"\n        [text]=\"'@organization-management:job-definitions.components.responsibilities-matrix.actions.choose-responsibilities.title' | translate | async\"\n        (onClick)=\"handleSelectResponsibilities()\" [disabled]=\"isLoadingResponsibilityEntity()\">\n        <ax-icon icon=\"far fa-plus\"></ax-icon>\n      </ax-button>\n      }\n    </div>\n    @if (isLoading()) {\n    <div class=\"__loading\">\n      <span>{{ '@organization-management:job-definitions.components.responsibilities-matrix.messages.loading-responsibility-levels' | translate | async\n        }}</span>\n    </div>\n    } @else {\n    <axp-spreadsheet [title]=\"'Responsibility / Level'\" [columns]=\"spreadsheetColumns()\" [rowsInput]=\"spreadsheetRows()\"\n      [rowMode]=\"'fixed'\" [readonly]=\"readonly()\" [allowRemoveRows]=\"true\" [rowTitlePath]=\"'_responsibilityTitle'\"\n      [rowDescriptionPath]=\"'_responsibilityDescription'\" (cellChange)=\"handleCellChange($event)\"\n      (spreadsheetChange)=\"handleSpreadsheetChange($event)\" (rowChange)=\"handleRowChange($event)\"></axp-spreadsheet>\n    }\n  </div>\n</div>\n", styles: [".axm-responsibilities-matrix{display:block;height:100%;width:100%}.axm-responsibilities-matrix .__container,.axm-responsibilities-matrix .__matrix-section{display:flex;flex-direction:column}.axm-responsibilities-matrix .__matrix-header{margin-bottom:.75rem;display:flex;justify-content:flex-end}.axm-responsibilities-matrix .__loading{display:flex;align-items:center;justify-content:center;padding:2rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}\n"] }]
        }], ctorParameters: () => [], propDecorators: { titles: [{ type: i0.Input, args: [{ isSignal: true, alias: "titles", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], responsibilityIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsibilityIds", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], responsibilityIdsChange: [{ type: i0.Output, args: ["responsibilityIdsChange"] }] } });

export { AXMOrganizationManagementResponsibilitiesMatrixComponent as A };
//# sourceMappingURL=acorex-modules-organization-management-responsibilities-matrix.component-BM-jMzZf.mjs.map
