// #region Imports
import { html } from '../../../../Dom/Html';
import { drag, dropList } from '../../../../DragDrop';
import { Icons } from '../../../../Resources/Icons';
import { repeat, when } from '../../../Directives/Directives';
// #endregion
/**
 * The template of the `DataTableElement`.
 *
 * @public
 */
export function dataTableElementTemplate(e) {
    return html `
        <mosaik-table part="table"
                      .columns="${e.getColumnsLayout()}"
                      .selectionType="${e.selectionType}"
                      .selectionMode="${e.selectionMode}"
                      .caption="${e.caption}"
                      .sortMode="${e.sortMode}"
                      ?resizable="${e.resizable}"
                      ?alternating="${e.alternating}"
                      @columnsChanged="${e.onColumnsChanged}"
                      @tableChooseColumns="${() => e.openEditor()}">
            ${when(e.allColumnsHidden, () => html `
            <mosaik-banner part="banner"
                           slot="caption"
                           .icon="${Icons.chooseColumns}"
                           .isOpen="${true}"
                           .variant="${'warning'}"
                           .appearance="${'plain'}"
                           .header="${e.intl.allColumnsHiddenLabel}"
                           .subHeader="${e.intl.allColumnsHiddenSubLabel}">
                <mosaik-button slot="actions"
                               .label="${e.intl.chooseColumnsLabel}"
                               .appearance="${'plain'}"
                               .variant="${'warning'}"
                               @click="${() => e.openEditor()}"></mosaik-button>
            </mosaik-banner>
            `)}
            <mosaik-table-header>
                <mosaik-table-header-row ?disabled="${e.disabled}"
                                         ${dropList({ orientation: 'horizontal', disabled: !e.reorderable })}
                                         @drop="${(ev) => e.handleHeaderCellDrop(ev)}">
                    ${repeat(e.getColumns().filter((c) => !c.hidden), (column) => column.key, (column) => html `
                    <mosaik-table-header-cell .key="${column.key}"
                                              .text="${column.headerCellTemplate ? '' : (column.title ?? column.key)}"
                                              .sortDirection="${column.sortDirection ?? 'none'}"
                                              .pinned="${column.pinned ?? 'none'}"
                                              .minWidth="${column.minWidth ?? ''}"
                                              .maxWidth="${column.maxWidth ?? ''}"
                                              .intl="${e.intl}"
                                              .sortable="${column.sortable ?? e.sortable}"
                                              .pinable="${column.pinable ?? e.pinable}"
                                              .resizable="${column.resizable ?? e.resizable}"
                                              .hideable="${column.hideable ?? e.hideable}"
                                              .autoSizeable="${column.autoSizeable ?? e.autoSizeable}"
                                              .columnChoosable="${column.columnChoosable ?? e.columnChoosable}"
                                              .columnHidden="${false}"
                                              ?disabled="${e.disabled}"
                                              ${drag({ disabled: !(column.reorderable ?? e.reorderable), lockAxis: 'x', dragStartDistance: 3 })}
                                              @tableSortChanged="${e.onSortChanged}">${when(column.headerCellTemplate, () => column.headerCellTemplate(column))}</mosaik-table-header-cell>
                    `)}
                </mosaik-table-header-row>
            </mosaik-table-header>
            <mosaik-table-body>
                ${repeat(e.sortedSource, (item) => item, (item) => html `
                <mosaik-table-body-row ?disabled="${e.disabled}">
                    ${repeat(e.getColumns().filter((c) => !c.hidden), (column) => column.key, (column) => {
        const value = resolveColumnValue(item, column);
        return html `<mosaik-table-body-cell .text="${column.cellTemplate ? '' : value}"
                                                            ?disabled="${e.disabled}">${when(column.cellTemplate, () => column.cellTemplate(item, column, value))}</mosaik-table-body-cell>`;
    })}
                </mosaik-table-body-row>
                `)}
            </mosaik-table-body>
        </mosaik-table>
        <mosaik-backdrop part="editor-panel-backdrop"
                         ?hidden="${!e.editorOpened}"
                         @click="${() => e.closeEditor()}"></mosaik-backdrop>
        <div part="editor-panel"
             data-visible="${e.editorOpened}">
            <mosaik-table-column-editor part="editor"
                                        .searchPlaceholder="${e.intl.searchPlaceholder}"
                                        @tableColumnEditorChanged="${(event) => e.applyColumnEditorChanges(event.detail)}"
                                        @tableColumnEditorDismissed="${() => e.closeEditor()}"></mosaik-table-column-editor>
        </div>
    `;
}
/**
 * Retrieves the value of a nested property from an object using a dot-separated path.
 * Supports array traversal via `[]` segments (e.g., `approvals.[].approvedBy`),
 * which iterates each array element and collects values from the remaining path.
 *
 * @param obj - The object from which to retrieve the value.
 * @param path - The dot-separated path to the property (e.g., "address.street.name").
 * @returns The value of the nested property, or `undefined` if any part of the path is invalid.
 *
 * @example
 * const user = { name: 'Alice', address: { street: { name: 'Main St' } } };
 * const streetName = getObjectValueByPath(user, 'address.street.name'); // Returns 'Main St'
 * const invalidPath = getObjectValueByPath(user, 'address.city.name'); // Returns undefined
 *
 * @example
 * const order = { approvals: [{ approvedBy: 'Alice' }, { approvedBy: 'Bob' }] };
 * const names = getObjectValueByPath(order, 'approvals.[].approvedBy'); // Returns 'Alice, Bob'
 *
 * @remarks
 * This function safely traverses the object structure and returns `undefined` if any part of the path does not exist, preventing runtime errors.
 *
 * @private
 */
function getObjectValueByPath(obj, path) {
    if (!path) {
        return obj;
    }
    const parts = path.split('.');
    let current = obj;
    for (let i = 0; i < parts.length; i++) {
        const part = parts[i];
        if (part === '[]') {
            if (!Array.isArray(current)) {
                return undefined;
            }
            const remainingPath = parts.slice(i + 1).join('.');
            const values = current
                .map((item) => getObjectValueByPath(item, remainingPath))
                .filter((v) => v !== undefined && v !== null);
            return values.join(', ');
        }
        if (current && typeof current === 'object' && part in current) {
            current = current[part];
        }
        else {
            return undefined;
        }
    }
    return current;
}
/**
 * Resolves the display value for a column from a data item.
 * Supports both a dot-separated string path and a value getter callback function.
 *
 * @param item - The data item for the current row.
 * @param column - The column definition.
 * @returns The resolved string value, or an empty string if no path or function is provided.
 *
 * @private
 */
function resolveColumnValue(item, column) {
    const pathOrFn = column.pathFn;
    if (!pathOrFn) {
        return '';
    }
    if (typeof pathOrFn === 'function') {
        const value = pathOrFn(item);
        return value !== undefined && value !== null ? String(value) : '';
    }
    return getObjectValueByPath(item, pathOrFn)?.toString() ?? '';
}
//# sourceMappingURL=DataTableElementTemplate.js.map