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;
};
import { css, customElement, html, ifDefined, property, repeat, state, when, } from '../../../../external/lit/index.js';
import { UmbLitElement } from '../../lit-element/index.js';
import { UmbSorterController } from '../../sorter/index.js';
import { UmbTextStyles } from '../../style/index.js';
export class UmbTableSelectedEvent extends Event {
    #itemId;
    constructor(args) {
        super('selected', { bubbles: true, composed: true });
        this.#itemId = args?.itemId;
    }
    getItemId() {
        return this.#itemId;
    }
}
export class UmbTableDeselectedEvent extends Event {
    #itemId;
    constructor(args) {
        super('deselected', { bubbles: true, composed: true });
        this.#itemId = args?.itemId;
    }
    getItemId() {
        return this.#itemId;
    }
}
export class UmbTableOrderedEvent extends Event {
    constructor() {
        super('ordered', { bubbles: true, composed: true });
    }
}
export class UmbTableSortedEvent extends Event {
    #itemId;
    constructor({ itemId }) {
        super('sorted', { bubbles: true, composed: true });
        this.#itemId = itemId;
    }
    getItemId() {
        return this.#itemId;
    }
}
/**
 *  @element umb-table
 *  @description - Element for displaying a table
 *  @fires {UmbTableSelectedEvent} selected - fires when a row is selected
 *  @fires {UmbTableDeselectedEvent} deselected - fires when a row is deselected
 *  @fires {UmbTableOrderedEvent} sort - fires when a column order is changed
 *  @augments LitElement
 */
let UmbTableElement = class UmbTableElement extends UmbLitElement {
    get items() {
        return this._items;
    }
    set items(value) {
        this._items = value;
        this.#sorter.setModel(value);
    }
    get sortable() {
        return this._sortable;
    }
    set sortable(newVal) {
        const oldVal = this._sortable;
        if (oldVal === newVal)
            return;
        this._sortable = newVal;
        if (this._sortable) {
            this.#sorter.enable();
        }
        else {
            this.#sorter.disable();
        }
        this.requestUpdate('sortable', oldVal);
    }
    updated(changedProperties) {
        super.updated(changedProperties);
        if (changedProperties.has('selection')) {
            this._selectionMode = this.selection.length > 0;
        }
    }
    #sorter;
    constructor() {
        super();
        /**
         * Table Items
         * @type {Array<UmbTableItem>}
         * @memberof UmbTableElement
         */
        this._items = [];
        /**
         * @description Table Columns
         * @type {Array<UmbTableColumn>}
         * @memberof UmbTableElement
         */
        this.columns = [];
        /**
         * @description Table Config
         * @type {UmbTableConfig}
         * @memberof UmbTableElement
         */
        this.config = {
            allowSelection: false,
            selectOnly: false,
            hideIcon: false,
        };
        /**
         * @description Table Selection
         * @type {Array<string>}
         * @memberof UmbTableElement
         */
        this.selection = [];
        this.orderingColumn = '';
        this.orderingDesc = false;
        this._sortable = false;
        this._selectionMode = false;
        this.#sorter = new UmbSorterController(this, {
            getUniqueOfElement: (element) => {
                return element.dataset.sortableId;
            },
            getUniqueOfModel: (item) => {
                return item.id;
            },
            identifier: 'Umb.SorterIdentifier.UmbTable',
            itemSelector: 'uui-table-row',
            containerSelector: 'uui-table',
            onChange: ({ model }) => {
                const oldValue = this.items;
                this.items = model;
                this.requestUpdate('items', oldValue);
            },
            onEnd: ({ item }) => {
                this.dispatchEvent(new UmbTableSortedEvent({ itemId: item.id }));
            },
        });
        this._renderRow = (item) => {
            const isItemSelectable = this.#isSelectableItem(item);
            return html `
			<uui-table-row
				data-sortable-id=${item.id}
				?selectable=${this.config.allowSelection && !this._sortable && isItemSelectable}
				?select-only=${this._selectionMode || this.config.selectOnly}
				?selected=${this._isSelected(item.id)}
				@selected=${() => this._selectRow(item)}
				@deselected=${() => this._deselectRow(item)}>
				${this._renderRowCheckboxCell(item)} ${this.columns.map((column) => this._renderRowCell(column, item))}
			</uui-table-row>
		`;
        };
        this.#sorter.disable();
    }
    _isSelected(key) {
        return this.selection.includes(key);
    }
    #isSelectableItem(item) {
        return item.selectable !== false;
    }
    _handleRowCheckboxChange(event, item) {
        const checkboxElement = event.target;
        if (checkboxElement.checked) {
            this._selectRow(item);
        }
        else {
            this._deselectRow(item);
        }
    }
    _handleAllRowsCheckboxChange(event) {
        const checkboxElement = event.target;
        if (checkboxElement.checked) {
            this._selectAllRows();
        }
        else {
            this._deselectAllRows();
        }
    }
    _handleOrderingChange(column) {
        this.orderingDesc = this.orderingColumn === column.alias ? !this.orderingDesc : false;
        this.orderingColumn = column.alias;
        this.dispatchEvent(new UmbTableOrderedEvent());
    }
    _selectAllRows() {
        if (this.config.allowSelectAll === false) {
            throw new Error('Select all is not allowed in the current table configuration.');
        }
        this.selection = this.items.filter((item) => this.#isSelectableItem(item)).map((item) => item.id);
        this._selectionMode = true;
        this.dispatchEvent(new UmbTableSelectedEvent());
    }
    _deselectAllRows() {
        if (this.config.allowSelectAll === false) {
            throw new Error('Select all is not allowed in the current table configuration.');
        }
        this.selection = [];
        this._selectionMode = false;
        this.dispatchEvent(new UmbTableDeselectedEvent());
    }
    _selectRow(item) {
        const isSelectble = this.#isSelectableItem(item);
        if (!isSelectble) {
            throw new Error(`Item with id ${item.id} is not selectable.`);
        }
        this.selection = [...this.selection, item.id];
        this._selectionMode = this.selection.length > 0;
        this.dispatchEvent(new UmbTableSelectedEvent({ itemId: item.id }));
    }
    _deselectRow(item) {
        this.selection = this.selection.filter((selectionKey) => selectionKey !== item.id);
        this._selectionMode = this.selection.length > 0;
        this.dispatchEvent(new UmbTableDeselectedEvent({ itemId: item.id }));
    }
    render() {
        const style = !(this.config.allowSelection === false && this.config.hideIcon === true) ? 'width: 60px' : undefined;
        return html `
			<uui-table class="uui-text">
				<uui-table-column style=${ifDefined(style)}></uui-table-column>
				<uui-table-head>
					${this._renderHeaderCheckboxCell()} ${this.columns.map((column) => this._renderHeaderCell(column))}
				</uui-table-head>
				${repeat(this.items, (item) => item.id, this._renderRow)}
			</uui-table>
		`;
    }
    _renderHeaderCell(column) {
        return html `
			<uui-table-head-cell style="--uui-table-cell-padding: 0 var(--uui-size-5)">
				${column.allowSorting
            ? html `${this._renderSortingUI(column)}`
            : html `<span style="text-align:${column.align ?? 'left'};">${column.name}</span>`}
			</uui-table-head-cell>
		`;
    }
    _renderSortingUI(column) {
        return html `
			<button
				style="padding: var(--uui-size-5) var(--uui-size-1);"
				@click="${() => this._handleOrderingChange(column)}">
				<span style="text-align:${column.align ?? 'left'};">${column.name}</span>
				<uui-symbol-sort ?active=${this.orderingColumn === column.alias} ?descending=${this.orderingDesc}>
				</uui-symbol-sort>
			</button>
		`;
    }
    _renderHeaderCheckboxCell() {
        if (this.config.hideIcon && !this.config.allowSelection)
            return;
        return html `
			<uui-table-head-cell style="--uui-table-cell-padding: 0; text-align: center;">
				${when(this.config.allowSelection && this.config.allowSelectAll !== false, () => html `
						<uui-checkbox
							aria-label=${this.localize.term('general_selectAll')}
							style="padding: var(--uui-size-4) var(--uui-size-5);"
							@change="${this._handleAllRowsCheckboxChange}"
							?checked=${this.selection.length === this.items.length}></uui-checkbox>
					`)}
			</uui-table-head-cell>
		`;
    }
    _renderRowCheckboxCell(item) {
        if (this.sortable === true) {
            return html `
				<uui-table-cell style="text-align: center;">
					<uui-icon name="icon-grip"></uui-icon>
				</uui-table-cell>
			`;
        }
        if (this.config.hideIcon && !this.config.allowSelection)
            return;
        const isItemSelectable = this.#isSelectableItem(item);
        return html `
			<uui-table-cell style="text-align: center;">
				${when(!this.config.hideIcon, () => html `<umb-icon name="${ifDefined(item.icon ?? undefined)}"></umb-icon>`)}
				${when(this.config.allowSelection && isItemSelectable, () => html `
						<uui-checkbox
							aria-label=${this.localize.term('buttons_select')}
							@click=${(e) => e.stopPropagation()}
							@change=${(event) => this._handleRowCheckboxChange(event, item)}
							?checked=${this._isSelected(item.id)}></uui-checkbox>
					`)}
			</uui-table-cell>
		`;
    }
    _renderRowCell(column, item) {
        return html `
			<uui-table-cell
				style="--uui-table-cell-padding: 0 var(--uui-size-5); text-align:${column.align ?? 'left'}; width: ${column.width || 'auto'};"
				?clip-text=${column.clipText}
				>
					${this._renderCellContent(column, item)}
			</uui-table-cell>
		</uui-table-cell>
		`;
    }
    _renderCellContent(column, item) {
        const value = item.data.find((data) => data.columnAlias === column.alias)?.value;
        if (column.elementName) {
            const element = document.createElement(column.elementName);
            element.column = column;
            element.item = item;
            element.value = value;
            return element;
        }
        if (column.labelTemplate) {
            import('../../../ufm/index.js');
            const element = document.createElement('umb-ufm-render');
            element.inline = true;
            element.markdown = column.labelTemplate;
            element.value = { value };
            return element;
        }
        return value;
    }
    static { this.styles = [
        UmbTextStyles,
        css `
			:host {
				height: fit-content;
			}

			:host([sortable]) {
				uui-table-row:hover {
					cursor: grab;
				}

				uui-table-row:active {
					cursor: grabbing;
				}
			}

			uui-table {
				box-shadow: var(--uui-shadow-depth-1);
			}

			uui-table-head {
				position: sticky;
				top: 0;
				z-index: 1;
				background-color: var(--uui-color-surface, #fff);
			}

			uui-table-row uui-checkbox {
				display: none;
			}

			uui-table-row[selectable]:focus umb-icon,
			uui-table-row[selectable]:focus-within umb-icon,
			uui-table-row[selectable]:hover umb-icon,
			uui-table-row[select-only] umb-icon {
				display: none;
			}

			uui-table-row[selectable]:focus uui-checkbox,
			uui-table-row[selectable]:focus-within uui-checkbox,
			uui-table-row[selectable]:hover uui-checkbox,
			uui-table-row[select-only] uui-checkbox {
				display: inline-block;
			}

			uui-table-head-cell:focus,
			uui-table-head-cell:focus-within,
			uui-table-head-cell:hover {
				--uui-symbol-sort-hover: 1;
			}

			uui-table-head-cell button {
				padding: 0;
				background-color: transparent;
				color: inherit;
				border: none;
				cursor: pointer;
				font-weight: inherit;
				font-size: inherit;
				display: inline-flex;
				align-items: center;
				justify-content: space-between;
				width: 100%;
			}

			uui-table-head-cell button > span {
				flex: 1 0 auto;
			}

			uui-table-cell umb-icon {
				vertical-align: top;
			}
		`,
    ]; }
};
__decorate([
    property({ type: Array, attribute: false })
], UmbTableElement.prototype, "_items", void 0);
__decorate([
    property({ type: Array, attribute: false })
], UmbTableElement.prototype, "columns", void 0);
__decorate([
    property({ type: Object, attribute: false })
], UmbTableElement.prototype, "config", void 0);
__decorate([
    property({ type: Array, attribute: false })
], UmbTableElement.prototype, "selection", void 0);
__decorate([
    property({ type: String, attribute: false })
], UmbTableElement.prototype, "orderingColumn", void 0);
__decorate([
    property({ type: Boolean, attribute: false })
], UmbTableElement.prototype, "orderingDesc", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbTableElement.prototype, "sortable", null);
__decorate([
    state()
], UmbTableElement.prototype, "_selectionMode", void 0);
UmbTableElement = __decorate([
    customElement('umb-table')
], UmbTableElement);
export { UmbTableElement };
export default UmbTableElement;
