// #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 { Disableable } from '../../../Behaviors/Disableable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { ItemsElement } from '../Abstracts/Items/ItemsElement';
import { TableCellElement } from '../Table/TableCellElement';
import { TableElement } from '../Table/TableElement';
import { dataTableElementTemplate } from './DataTableElementTemplate';
import { dataTableElementJoyStyle } from './Themes/DataTableElement.Joy';
import { dataTableElementMemphisStyle } from './Themes/DataTableElement.Memphis';
import { dataTableElementCosmopolitanStyle } from './Themes/DataTableElement.Cosmopolitan';
import { TableHeaderElement } from '../Table/TableHeaderElement';
import { TableRowElement } from '../Table/TableRowElement';
import { Themeable } from '../../../Behaviors/Themeable';
// #endregion
/**
 * DataTable - A comprehensive data presentation component for displaying structured information in rows and columns.
 *
 * Provides advanced data table functionality including sorting, filtering, pagination, and selection
 * capabilities. Designed for displaying large datasets with efficient rendering and user interaction
 * features for data analysis and management tasks.
 *
 * @name DataTableElement
 * @element mosaik-data-table
 * @category Selectors
 *
 * @slot - Default content area for custom table content and additional elements
 * @slot header - Table header area for titles, filters, and actions
 * @slot footer - Table footer area for pagination, totals, and summary information
 *
 * @csspart table - Main table container element
 * @csspart header - Table header section
 * @csspart body - Table body containing data rows
 * @csspart footer - Table footer section
 * @csspart row - Individual table row
 * @csspart cell - Individual table cell
 * @csspart sort-button - Sortable column header buttons
 * @csspart pagination - Pagination controls container
 *
 * @cssprop --data-table-border-color - Color for table borders and grid lines
 * @cssprop --data-table-header-background - Background color for table headers
 * @cssprop --data-table-row-background - Background color for table rows
 * @cssprop --data-table-row-background-hover - Hover state background for rows
 * @cssprop --data-table-row-background-selected - Selected row background color
 * @cssprop --data-table-cell-padding - Internal padding for table cells
 * @cssprop --data-table-header-font-weight - Font weight for header text
 *
 * @dependency TableElement - Base table structure and layout
 * @dependency TableHeaderElement - For table header rows and column definitions
 * @dependency TableRowElement - For data rows and content presentation
 * @dependency TableCellElement - For individual data cells and content
 *
 * @example
 * ```html
 * <!-- Basic data table with auto-generated columns -->
 * <mosaik-data-table
 *   items='[
 *     {"id": 1, "name": "John Doe", "email": "john@example.com", "role": "Admin"},
 *     {"id": 2, "name": "Jane Smith", "email": "jane@example.com", "role": "User"}
 *   ]'
 *   auto-generate-columns="true"
 *   sortable="true">
 * </mosaik-data-table>
 *
 * <!-- Data table with custom column definitions -->
 * <mosaik-data-table
 *   items="users"
 *   selectable="true"
 *   paginated="true"
 *   page-size="25">
 *   <div slot="header">
 *     <mosaik-text variant="headline">User Management</mosaik-text>
 *     <mosaik-button onclick="addUser()">Add User</mosaik-button>
 *   </div>
 * </mosaik-data-table>
 *
 * <!-- Data table with filtering and actions -->
 * <mosaik-data-table
 *   items="products"
 *   alternating="true"
 *   multi-select="true"
 *   searchable="true">
 *   <div slot="header">
 *     <mosaik-search-box placeholder="Search products..." onInput="filterProducts"></mosaik-search-box>
 *     <div class="table-actions">
 *       <mosaik-button appearance="soft">Export</mosaik-button>
 *       <mosaik-button appearance="primary">Bulk Edit</mosaik-button>
 *     </div>
 *   </div>
 *   <div slot="footer">
 *     <mosaik-text variant="caption">Showing 1-25 of 150 products</mosaik-text>
 *   </div>
 * </mosaik-data-table>
 *
 * <!-- Data table with custom cell renderers -->
 * <mosaik-data-table items="orders" expandable-rows="true">
 *   <!-- Custom column templates would be defined via column definitions -->
 * </mosaik-data-table>
 * ```
 *
 * @public
 */
let DataTableElement = class DataTableElement extends Themeable(Disableable(ItemsElement)) {
    // #region Fields
    _alternating;
    _autoGenerateColumns;
    _columnDefinitions;
    _sorted;
    _sortedSource;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._alternating = false;
        this._autoGenerateColumns = false;
        this._columnDefinitions = new Array();
        this._sorted = false;
        this._sortedSource = new Array();
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     *
     * @public
     * @static
     * @readonly
    */
    static get is() {
        return 'mosaik-data-table';
    }
    /**
     * Gets or sets the `alternating` property.
     *
     * @public
     * @attr
     */
    get alternating() {
        return this._alternating;
    }
    set alternating(value) {
        if (this._alternating !== value) {
            this._alternating = value;
            this.requestUpdate('alternating');
        }
    }
    /**
     * Gets or sets the `autoGenerateColumns` property.
     *
     * @public
     * @attr
     */
    get autoGenerateColumns() {
        return this._autoGenerateColumns;
    }
    set autoGenerateColumns(value) {
        if (this._autoGenerateColumns !== value) {
            this._autoGenerateColumns = value;
            this.requestUpdate('autoGenerateColumns');
        }
    }
    /**
     * Gets or sets the `columnDefinitions` property.
     *
     * @public
     */
    get columnDefinitions() {
        return this._columnDefinitions;
    }
    set columnDefinitions(value) {
        if (this._columnDefinitions !== value) {
            this._columnDefinitions = value;
            this.requestUpdate('columnDefinitions');
        }
    }
    /**
     * Gets a `boolean` that indecates the table header is sorted or not.
     * Returns `true` if the table header is sorted, otherwise `false`.
     *
     * @public
     * @readonly
     * @attr
     */
    get sorted() {
        return this._sorted;
    }
    /**
     * @public
     * @readonly
     */
    get sortedSource() {
        return this._sorted ? this._sortedSource : this.source;
    }
    // #endregion
    // #region Methods
    /**
     * @protected
     * @override
     */
    onSourceChanged(prev, next) {
        super.onSourceChanged(prev, next);
        this._sortedSource = [...this.source];
    }
    /**
     * @template
     * @private
     */
    getColumns() {
        let columns;
        if (this._autoGenerateColumns) {
            // TODO: find a way to get all object keys of array.
            // const first = this.source[0];
            // const firstKeys = Object.keys(first);
            // return firstKeys;
            const row = this.source[0];
            columns = Object.getOwnPropertyNames(row).map((x) => ({
                key: x,
                path: x
            }));
        }
        columns = this._columnDefinitions.map((x) => ({
            ...x,
            ...{ path: x.path ?? x.key }
        }));
        return columns;
    }
    /**
     * @template
     * @private
     */
    onSortChanged(e) {
        this.sortByColumn(this._sortedSource, e.detail.sortKey, e.detail.sortDirection);
        this._sorted = e.detail.sortDirection !== 'none';
        this.requestUpdate('sortedSource');
        this.requestUpdate('sorted');
    }
    /**
     * @private
     */
    sortByColumn(source, column, direction) {
        const sortedSource = source.sort((a, b) => {
            if (a[column] > b[column]) {
                return direction === 'desc' ? 1 : -1;
            }
            if (a[column] < b[column]) {
                return direction === 'desc' ? -1 : 1;
            }
            return 0;
        });
        return sortedSource;
    }
};
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], DataTableElement.prototype, "alternating", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], DataTableElement.prototype, "autoGenerateColumns", null);
__decorate([
    Property({ type: Array }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [Array])
], DataTableElement.prototype, "columnDefinitions", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [])
], DataTableElement.prototype, "sorted", null);
__decorate([
    Property({ type: Array }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [])
], DataTableElement.prototype, "sortedSource", null);
DataTableElement = __decorate([
    Component({
        selector: 'mosaik-data-table',
        template: dataTableElementTemplate,
        themes: {
            joy: dataTableElementJoyStyle,
            memphis: dataTableElementMemphisStyle,
            cosmopolitan: dataTableElementCosmopolitanStyle
        },
        imports: [
            TableElement,
            TableHeaderElement,
            TableRowElement,
            TableCellElement
        ]
    }),
    __metadata("design:paramtypes", [])
], DataTableElement);
export { DataTableElement };
//# sourceMappingURL=DataTableElement.js.map