// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { HTMLElementEventEmitter } from '@breadstone/mosaik-elements';
import { Emit } from '../../../../../events/Decorators/EmitDecorator';
import { addIntlController } from '../../../../../Intl/IntlController';
import { Themeable } from '../../../../Behaviors/Themeable';
import { Component } from '../../../../Decorators/ComponentDecorator';
import { Property } from '../../../../Decorators/PropertyDecorator';
import { CustomElement } from '../../../Abstracts/CustomElement';
import { CheckboxElement } from '../../../Inputs/CheckBox/CheckBoxElement';
import { SearchBoxElement } from '../../../Inputs/SearchBox/SearchBoxElement';
import { IconElement } from '../../../Media/Icon/IconElement';
import { ScrollElement } from '../../../Primitives/Scroll/ScrollElement';
import { TextElement } from '../../../Primitives/Text/TextElement';
import { TableColumnEditorElementIntl } from './intl/TableColumnEditorElementIntl';
import { ITableColumnEditorElementProps } from './ITableColumnEditorElementProps';
import { tableColumnEditorElementTemplate } from './TableColumnEditorElementTemplate';
import { tableColumnEditorElementCosmopolitanStyle } from './Themes/TableColumnEditorElement.Cosmopolitan';
import { tableColumnEditorElementJoyStyle } from './Themes/TableColumnEditorElement.Joy';
import { tableColumnEditorElementMemphisStyle } from './Themes/TableColumnEditorElement.Memphis';
// #endregion
/**
 * TableColumnEditor - A standalone component for managing table column visibility and order.
 *
 * @description
 * The TableColumnEditor component provides an interface for users to search, toggle visibility,
 * and reorder table columns via drag-and-drop. It is designed to be hosted in any container
 * (Dialog, Popover, Flyout, Drawer) by the consumer.
 *
 * @name TableColumnEditor
 * @element mosaik-table-column-editor
 * @category Selectors
 *
 * @csspart checkbox - The visibility toggle checkbox.
 * @csspart drag-handle - The drag handle icon for reordering.
 * @csspart filter - The filter part.
 * @csspart header - The header row containing the select-all checkbox and search input.
 * @csspart item - A single column item row.
 * @csspart list - The scrollable list of column items.
 * @csspart scroll - The scroll part.
 * @csspart search - The search text input.
 * @csspart select-all - The select/deselect all checkbox.
 * @csspart label - The column title label.
 *
 * @cssprop {String} --table-column-editor-background-color - Background color.
 * @cssprop {String} --table-column-editor-border-color - Border color.
 * @cssprop {String} --table-column-editor-border-radius - Border radius.
 * @cssprop {String} --table-column-editor-font-family - Font family.
 * @cssprop {String} --table-column-editor-font-letter-spacing - Font letter spacing.
 * @cssprop {String} --table-column-editor-font-line-height - Font line height.
 * @cssprop {String} --table-column-editor-font-size - Font size.
 * @cssprop {String} --table-column-editor-font-text-decoration - The column editor font text decoration CSS custom property.
 * @cssprop {String} --table-column-editor-font-text-transform - The column editor font text transform CSS custom property.
 * @cssprop {String} --table-column-editor-font-weight - Font weight.
 * @cssprop {String} --table-column-editor-foreground-color - Foreground color.
 * @cssprop {String} --table-column-editor-gap - Gap between header and list.
 * @cssprop {String} --table-column-editor-item-gap - Gap between items within a row.
 * @cssprop {String} --table-column-editor-item-hover-background-color - Item hover background.
 * @cssprop {String} --table-column-editor-item-padding-bottom - Item padding bottom.
 * @cssprop {String} --table-column-editor-item-padding-left - Item padding left.
 * @cssprop {String} --table-column-editor-item-padding-right - Item padding right.
 * @cssprop {String} --table-column-editor-item-padding-top - Item padding top.
 * @cssprop {String} --table-column-editor-padding-bottom - Root padding bottom.
 * @cssprop {String} --table-column-editor-padding-left - Root padding left.
 * @cssprop {String} --table-column-editor-padding-right - Root padding right.
 * @cssprop {String} --table-column-editor-padding-top - Root padding top.
 * @cssprop {String} --table-column-editor-shadow - The column editor shadow CSS custom property.
 * @cssprop {String} --table-column-editor-shadow-blur - The column editor shadow blur CSS custom property.
 * @cssprop {String} --table-column-editor-shadow-color - The column editor shadow color CSS custom property.
 * @cssprop {String} --table-column-editor-shadow-offset-x - The column editor shadow offset x CSS custom property.
 * @cssprop {String} --table-column-editor-shadow-offset-y - The column editor shadow offset y CSS custom property.
 * @cssprop {String} --table-column-editor-shadow-spread - The column editor shadow spread CSS custom property.
 * @cssprop {String} --table-column-editor-transition-duration - Transition duration.
 * @cssprop {String} --table-column-editor-transition-mode - Transition timing function.
 * @cssprop {String} --table-column-editor-transition-property - Transition property.
 * @cssprop {String} --table-column-editor-translate - The column editor translate CSS custom property.
 *
 * @fires tableColumnEditorChanged {TableColumnEditorChangedEvent} - Fired when columns are changed.
 *
 * @dependency mosaik-checkbox - The Checkbox element.
 * @dependency mosaik-dismiss - The Dismiss element.
 * @dependency mosaik-icon - The Icon element.
 * @dependency mosaik-scroll - The Scroll element.
 * @dependency mosaik-searchbox - The Searchbox element.
 * @dependency mosaik-text - The Text element.
 *
 * @example
 * Column editor hosted inside a dialog for managing table columns:
 * ```html
 * <mosaik-table-column-editor></mosaik-table-column-editor>
 * ```
 *
 * @public
 */
let TableColumnEditorElement = class TableColumnEditorElement extends Themeable(CustomElement) {
    // #region Fields
    _intl;
    _tableColumnEditorChanged;
    _tableColumnEditorDismissed;
    _columns;
    _filter;
    _isUpdating;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._columns = ITableColumnEditorElementProps.DEFAULTS.columns;
        this._filter = '';
        this._intl = addIntlController(this, {
            factory: () => new TableColumnEditorElementIntl()
        });
        this._isUpdating = false;
        this._tableColumnEditorChanged = new HTMLElementEventEmitter(this, 'tableColumnEditorChanged');
        this._tableColumnEditorDismissed = new HTMLElementEventEmitter(this, 'tableColumnEditorDismissed');
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-table-column-editor';
    }
    /**
     * Gets or sets the `columns` property.
     * The columns to display and edit.
     *
     * @public
     */
    get columns() {
        return this._columns;
    }
    set columns(value) {
        this._columns = value ? value.map((c) => ({ ...c })) : [];
        this.requestUpdate('columns');
    }
    /**
     * Gets the `intl` property.
     * The internationalization object for configuring labels and placeholders.
     *
     * @public
     * @readonly
     */
    get intl() {
        return this._intl.intl;
    }
    /**
     * Gets the current filter text.
     *
     * @private
     * @hidden
     */
    get filter() {
        return this._filter;
    }
    /**
     * Gets whether all columns are currently visible.
     *
     * @private
     * @hidden
     */
    get allVisible() {
        return this._columns.length > 0 && this._columns.every((c) => c.visible);
    }
    /**
     * Gets the filtered columns based on the current filter text.
     *
     * @private
     * @hidden
     */
    get filteredColumns() {
        if (!this._filter) {
            return this._columns;
        }
        const search = this._filter.toLowerCase();
        return this._columns.filter((c) => c.title.toLowerCase().includes(search));
    }
    /**
     * Gets whether drag-and-drop reordering is currently enabled.
     * Disabled when a filter is active since indices would not match.
     *
     * @private
     * @hidden
     */
    get isDragEnabled() {
        return !this._filter;
    }
    /**
     * Called when the column editor changes.
     * Provides reference to `ITableColumnEditorChangedEventDetail` as event argument.
     *
     * @public
     * @readonly
     * @eventProperty
     * @type IEventEmitter<ITableColumnEditorChangedEventDetail>
     */
    get tableColumnEditorChanged() {
        return this._tableColumnEditorChanged;
    }
    /**
     * Called when the column editor is dismissed.
     * Provides reference to `IEventDetail` as event argument.
     *
     * @public
     * @readonly
     * @eventProperty
     * @type IEventEmitter<IEventDetail>
     */
    get tableColumnEditorDismissed() {
        return this._tableColumnEditorDismissed;
    }
    // #endregion
    // #region Methods
    /**
     * Dismisses the column editor by emitting the dismissed event.
     *
     * @public
     */
    dismiss() {
        this._tableColumnEditorDismissed.emit({});
    }
    /**
     * Sets the visibility of a column by key.
     *
     * @private
     * @hidden
     */
    setColumnVisibility(key, visible) {
        const column = this._columns.find((c) => c.key === key);
        if (column) {
            this._isUpdating = true;
            column.visible = visible;
            this.requestUpdate('columns');
            this.emitColumnsChanged();
            this.updateComplete.then(() => {
                this._isUpdating = false;
            });
        }
    }
    /**
     * Toggles visibility of all columns.
     *
     * @private
     * @hidden
     */
    toggleAll(visible) {
        if (this._isUpdating) {
            return;
        }
        for (const column of this._columns) {
            column.visible = visible;
        }
        this.requestUpdate('columns');
        this.emitColumnsChanged();
    }
    /**
     * Handles filter input changes from the search box.
     *
     * @private
     * @hidden
     */
    handleFilterChange(query) {
        this._filter = query ?? '';
        this.requestUpdate();
    }
    /**
     * Handles a drop event for reordering columns.
     *
     * @private
     * @hidden
     */
    handleDrop(event) {
        const { previousIndex, currentIndex } = event.detail;
        if (previousIndex === currentIndex) {
            return;
        }
        const item = this._columns.splice(previousIndex, 1)[0];
        this._columns.splice(currentIndex, 0, item);
        this.requestUpdate('columns');
        this.emitColumnsChanged();
    }
    /**
     * Emits the columns changed event with the current state.
     *
     * @private
     */
    emitColumnsChanged() {
        this._tableColumnEditorChanged.emit({
            columns: this._columns.map((c) => ({ ...c }))
        });
    }
};
__decorate([
    Property({ type: Array }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [Array])
], TableColumnEditorElement.prototype, "columns", null);
__decorate([
    Emit({ eventName: 'tableColumnEditorChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], TableColumnEditorElement.prototype, "tableColumnEditorChanged", null);
__decorate([
    Emit({ eventName: 'tableColumnEditorDismissed' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], TableColumnEditorElement.prototype, "tableColumnEditorDismissed", null);
TableColumnEditorElement = __decorate([
    Component({
        selector: 'mosaik-table-column-editor',
        template: tableColumnEditorElementTemplate,
        themes: {
            joy: tableColumnEditorElementJoyStyle,
            memphis: tableColumnEditorElementMemphisStyle,
            cosmopolitan: tableColumnEditorElementCosmopolitanStyle
        },
        options: {
            mode: 'open'
        },
        imports: [
            CheckboxElement,
            SearchBoxElement,
            IconElement,
            TextElement,
            ScrollElement
        ]
    }),
    __metadata("design:paramtypes", [])
], TableColumnEditorElement);
export { TableColumnEditorElement };
//# sourceMappingURL=TableColumnEditorElement.js.map