// #region Imports
import { DomServiceLocator } from '../../../../../Dom/Dom';
import { Disableable } from '../../../../Behaviors/Disableable';
import { CustomElement } from '../../../Abstracts/CustomElement';
import { TableElement } from '../TableElement';
// #endregion
/**
 * Table Row Base Element - The foundational base class for all table row components.
 *
 * @description
 * TableRowBaseElement provides the core functionality and behavior patterns for all table row
 * components in the Mosaik design system. It manages grid column layout by subscribing to the
 * parent TableElement's column changes and auto-sizing cells via slot change detection.
 * Header, body, and footer row variants extend this base class to inherit consistent
 * grid management behavior.
 *
 * @public
 *
 * @remarks
 * This class applies the Disableable behavior mixin. Concrete subclasses add Themeable
 * and any section-specific behaviors (e.g., Selectable for body rows).
 * @abstract
 */
export class TableRowBaseElement extends Disableable(CustomElement) {
    // #region Fields
    _columnsChangedSubscription;
    _hasTableColumns;
    /**
     * Reference to the parent table element.
     *
     * @protected
     */
    _table;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._columnsChangedSubscription = null;
        this._hasTableColumns = false;
        this._table = null;
    }
    // #endregion
    // #region Properties
    // #endregion
    // #region Methods
    /**
     * Handles slot changes to auto-size grid columns when the parent table has no explicit columns.
     *
     * @public
     */
    onSlotChange(event) {
        const slot = event.target;
        const elements = slot.assignedElements();
        if (!this._hasTableColumns) {
            this.style.gridTemplateColumns = elements.map(() => '1fr')
                .join(' ');
        }
        this.applyColumnMetadata(elements);
    }
    /**
     * @public
     * @override
     */
    disconnectedCallback() {
        super.disconnectedCallback();
        this._columnsChangedSubscription?.dispose();
        this._columnsChangedSubscription = null;
    }
    /**
     * @public
     * @override
     */
    connectedCallback() {
        super.connectedCallback();
        if (this._table && !this._columnsChangedSubscription) {
            this.applyGridColumns(this._table.columns);
            this.subscribeToColumnsChanged(this._table);
        }
    }
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        const table = DomServiceLocator.current.findAncestor(this, TableElement);
        if (table) {
            this._table = table;
            if (table.columns) {
                this._hasTableColumns = true;
            }
            this.applyGridColumns(table.columns);
            this.subscribeToColumnsChanged(table);
        }
    }
    /**
     * Subscribes to the parent table's `columnsChanged` event to keep the row's grid layout in sync.
     *
     * @private
     */
    subscribeToColumnsChanged(table) {
        this._columnsChangedSubscription = table.on('columnsChanged', (d) => {
            if (table.columns) {
                this._hasTableColumns = true;
            }
            const columns = d.detail.columns;
            const colStr = typeof columns === 'string' ? columns : [...columns].join(' ');
            this.applyGridColumns(colStr);
            this.applyColumnMetadata(Array.from(this.children));
        });
    }
    /**
     * Applies grid column widths, collapsing hidden columns to `0px`.
     *
     * @private
     */
    applyGridColumns(columns) {
        if (!columns) {
            return;
        }
        if (!this._table) {
            this.style.gridTemplateColumns = columns;
            return;
        }
        const metadata = this._table.getColumnMetadata();
        const parts = columns.trim().split(/\s+/);
        const adjusted = parts.map((width, i) => (i < metadata.length && metadata[i].hidden) ? '0px' : width);
        this.style.gridTemplateColumns = adjusted.join(' ');
    }
    /**
     * Applies pinning and hiding attributes to child cells based on header cell metadata.
     *
     * @private
     */
    applyColumnMetadata(cells) {
        if (!this._table) {
            return;
        }
        const metadata = this._table.getColumnMetadata();
        let leftOffset = 0;
        for (let i = 0; i < cells.length && i < metadata.length; i++) {
            const cell = cells[i];
            const meta = metadata[i];
            // Apply pinning
            if (meta.pinned !== 'none') {
                cell.setAttribute('pinned', meta.pinned);
                if (meta.pinned === 'left') {
                    cell.style.setProperty('--table-column-pinned-offset', `${leftOffset}px`);
                    leftOffset += cell.getBoundingClientRect().width || 0;
                }
            }
            else {
                cell.removeAttribute('pinned');
                cell.style.removeProperty('--table-column-pinned-offset');
            }
            // Apply column hidden
            if (meta.hidden) {
                cell.setAttribute('column-hidden', '');
            }
            else {
                cell.removeAttribute('column-hidden');
            }
        }
        // Handle right-pinned columns (reverse for cumulative offset)
        let rightOffset = 0;
        for (let i = cells.length - 1; i >= 0; i--) {
            if (i < metadata.length && metadata[i].pinned === 'right') {
                cells[i].style.setProperty('--table-column-pinned-offset', `${rightOffset}px`);
                rightOffset += cells[i].getBoundingClientRect().width || 0;
            }
        }
    }
}
//# sourceMappingURL=TableRowBaseElement.js.map