import { Host, h } from "@stencil/core";
export class SpwTable {
    constructor() {
        /** Si le header du tableau doit être sticky ou non */
        this.isSticky = false;
        /** Si défini, apparition d'une scrollbar horizontale et max-width  */
        this.minWidth = '600';
        /** Permet de définir le table-layout (auto ou fixed)  */
        this.tableLayout = 'auto';
        /** Définit un background de couleur différent une ligne sur 2 */
        this.isZebra = false;
        /** Désactive le tri natif pour permettre l'utilisation d'une fonction de tri personnalisée */
        this.disableSort = false;
        /** Active le redimensionnement manuel de la hauteur du tableau avec un handle */
        this.resizable = false;
        /** Hauteur minimale autorisée lors du redimensionnement (en pixels) */
        this.minHeight = 200;
        this.isResizing = false;
        this.startY = 0;
        this.startHeight = 0;
        this.handleResizeStart = (event) => {
            var _a;
            event.preventDefault();
            this.isResizing = true;
            this.startY = event.clientY;
            const wrapper = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.spw-table-wrapper');
            if (wrapper) {
                this.containerElement = wrapper;
                this.startHeight = wrapper.offsetHeight;
            }
            document.addEventListener('mousemove', this.handleMouseMove);
            document.addEventListener('mouseup', this.handleMouseUp);
            document.body.style.cursor = 'ns-resize';
            document.body.style.userSelect = 'none';
        };
        this.handleMouseMove = (event) => {
            if (!this.isResizing || !this.containerElement)
                return;
            const deltaY = event.clientY - this.startY;
            const newHeight = Math.max(this.minHeight, this.startHeight + deltaY);
            this.currentHeight = newHeight;
            this.spwResize.emit({ height: newHeight });
        };
        this.handleMouseUp = () => {
            if (!this.isResizing)
                return;
            this.isResizing = false;
            this.cleanupResizeListeners();
            document.body.style.cursor = '';
            document.body.style.userSelect = '';
        };
        this.checkboxChangeHandler = () => this.updateMasterCheckboxState();
    }
    onCurrentSortChange(newSort) {
        if (newSort) {
            this.updateHeadersSortState(newSort);
        }
    }
    onIsStickyChange() {
        this.applyStickyToChildren();
    }
    componentDidLoad() {
        var _a;
        this.updateZebra();
        this.applyStickyToChildren();
        const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])');
        if (slot) {
            slot.addEventListener('slotchange', () => {
                this.setupHeaderCheckboxListener();
                this.updateMasterCheckboxState();
                this.applyStickyToChildren();
            });
        }
        this.setupHeaderCheckboxListener();
        this.setupBodyCheckboxListener();
        this.setupTableBodyObserver();
        this.setupHeaderObserver();
        setTimeout(() => {
            this.updateMasterCheckboxState();
        }, 0);
        if (this.resizable && this.maxHeight) {
            this.currentHeight = parseInt(this.maxHeight, 10);
        }
    }
    disconnectedCallback() {
        if (this.mutationObserver) {
            this.mutationObserver.disconnect();
        }
        if (this.headerMutationObserver) {
            this.headerMutationObserver.disconnect();
        }
        this.cleanupResizeListeners();
    }
    cleanupResizeListeners() {
        document.removeEventListener('mousemove', this.handleMouseMove);
        document.removeEventListener('mouseup', this.handleMouseUp);
    }
    setupTableBodyObserver() {
        const body = Array.from(this.el.children).find(el => el.tagName.toLowerCase() === 'spw-table-body');
        if (!body)
            return;
        this.mutationObserver = new MutationObserver(() => {
            this.setupBodyCheckboxListener();
            setTimeout(() => {
                this.updateMasterCheckboxState();
            }, 0);
        });
        this.mutationObserver.observe(body, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['checked', 'disabled'],
        });
    }
    setupHeaderObserver() {
        const head = Array.from(this.el.children).find(el => el.tagName.toLowerCase() === 'spw-table-head');
        if (!head)
            return;
        this.headerMutationObserver = new MutationObserver(() => {
            this.applyStickyToChildren();
        });
        this.headerMutationObserver.observe(head, {
            childList: true,
            subtree: true,
        });
    }
    getMasterCheckboxColumnIndex() {
        var _a;
        const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])');
        if (!slot)
            return null;
        const assignedElements = slot.assignedElements({ flatten: true });
        const head = assignedElements.find(el => el.tagName.toLowerCase() === 'spw-table-head');
        if (!head)
            return null;
        const headerRow = head.querySelector('spw-table-row');
        if (!headerRow)
            return null;
        const headerCells = Array.from(headerRow.querySelectorAll('spw-table-header'));
        for (let i = 0; i < headerCells.length; i++) {
            if (headerCells[i].querySelector('spw-checkbox')) {
                return i;
            }
        }
        return null;
    }
    isCheckboxDisabled(checkbox) {
        return (checkbox === null || checkbox === void 0 ? void 0 : checkbox.disabled) === true || (checkbox === null || checkbox === void 0 ? void 0 : checkbox.getAttribute('disabled')) === 'true' || (checkbox === null || checkbox === void 0 ? void 0 : checkbox.getAttribute('disabled')) === '';
    }
    updateMasterCheckboxState() {
        var _a;
        const columnIndex = this.getMasterCheckboxColumnIndex();
        if (columnIndex === null)
            return;
        const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])');
        const assignedElements = slot === null || slot === void 0 ? void 0 : slot.assignedElements({ flatten: true });
        if (!assignedElements)
            return;
        const head = assignedElements.find(el => el.tagName.toLowerCase() === 'spw-table-head');
        const body = assignedElements.find(el => el.tagName.toLowerCase() === 'spw-table-body');
        if (!head || !body)
            return;
        const headerRow = head.querySelector('spw-table-row');
        const headerCell = headerRow === null || headerRow === void 0 ? void 0 : headerRow.querySelectorAll('spw-table-header')[columnIndex];
        const masterCheckbox = headerCell === null || headerCell === void 0 ? void 0 : headerCell.querySelector('spw-checkbox');
        const rows = body.querySelectorAll('spw-table-row');
        const checkboxData = Array.from(rows).map(row => {
            const cell = row.querySelectorAll('spw-table-cell')[columnIndex];
            const cb = cell === null || cell === void 0 ? void 0 : cell.querySelector('spw-checkbox');
            return {
                checked: (cb === null || cb === void 0 ? void 0 : cb.checked) === true || (cb === null || cb === void 0 ? void 0 : cb.getAttribute('checked')) === 'true',
                disabled: this.isCheckboxDisabled(cb),
            };
        });
        const enabledCheckboxes = checkboxData.filter(item => !item.disabled);
        if (enabledCheckboxes.length === 0)
            return;
        const allChecked = enabledCheckboxes.every(item => item.checked);
        const noneChecked = enabledCheckboxes.every(item => !item.checked);
        if (!masterCheckbox)
            return;
        if (allChecked) {
            masterCheckbox.checked = true;
            masterCheckbox.setAttribute('checked', 'true');
            masterCheckbox.setAttribute('icon', 'fa-check');
        }
        else if (noneChecked) {
            masterCheckbox.checked = false;
            masterCheckbox.setAttribute('checked', 'false');
            masterCheckbox.setAttribute('icon', 'fa-check');
        }
        else {
            masterCheckbox.checked = true;
            masterCheckbox.setAttribute('checked', 'true');
            masterCheckbox.setAttribute('icon', 'fa-minus');
        }
    }
    setupHeaderCheckboxListener() {
        var _a;
        const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])');
        const assignedElements = slot === null || slot === void 0 ? void 0 : slot.assignedElements({ flatten: true });
        if (!assignedElements)
            return;
        const head = assignedElements.find(el => el.tagName.toLowerCase() === 'spw-table-head');
        if (!head)
            return;
        const headerRows = head.querySelectorAll('spw-table-row');
        headerRows.forEach(row => {
            const checkboxes = row.querySelectorAll('spw-checkbox');
            checkboxes.forEach(cb => {
                cb.addEventListener('spwChange', (event) => {
                    this.toggleAllRowCheckboxes(event.detail);
                });
            });
        });
    }
    setupBodyCheckboxListener() {
        const body = Array.from(this.el.children).find(el => el.tagName.toLowerCase() === 'spw-table-body');
        if (!body)
            return;
        const rows = body.querySelectorAll('spw-table-row');
        rows.forEach(row => {
            const checkboxes = row.querySelectorAll('spw-checkbox');
            checkboxes.forEach(cb => {
                cb.removeEventListener('spwChange', this.checkboxChangeHandler);
                cb.addEventListener('spwChange', this.checkboxChangeHandler);
            });
        });
    }
    toggleAllRowCheckboxes(checked) {
        var _a;
        const columnIndex = this.getMasterCheckboxColumnIndex();
        if (columnIndex === null)
            return;
        const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])');
        const assignedElements = slot === null || slot === void 0 ? void 0 : slot.assignedElements({ flatten: true });
        if (!assignedElements)
            return;
        const body = assignedElements.find(el => el.tagName.toLowerCase() === 'spw-table-body');
        if (!body)
            return;
        const rows = body.querySelectorAll('spw-table-row');
        rows.forEach(row => {
            const cells = Array.from(row.querySelectorAll('spw-table-cell'));
            const targetCell = cells[columnIndex];
            const checkbox = targetCell === null || targetCell === void 0 ? void 0 : targetCell.querySelector('spw-checkbox');
            if (checkbox && !this.isCheckboxDisabled(checkbox)) {
                checkbox.checked = checked;
                checkbox.setAttribute('checked', checked.toString());
            }
        });
        setTimeout(() => {
            this.updateMasterCheckboxState();
        }, 0);
    }
    handleHeaderClick(event) {
        const columnId = event.detail;
        const current = this.currentSort;
        const newSort = {
            column: columnId,
            direction: (current === null || current === void 0 ? void 0 : current.column) === columnId && current.direction === 'asc' ? 'desc' : 'asc',
        };
        this.currentSort = newSort;
        this.spwSort.emit(newSort);
        if (!this.disableSort) {
            this.sortRows(newSort.column, newSort.direction);
        }
        this.updateHeadersSortState(newSort);
        this.updateZebra();
    }
    updateZebra() {
        const slot = this.el.shadowRoot.querySelector('slot:not([name])');
        if (!slot)
            return;
        const assignedElements = slot.assignedElements({ flatten: true });
        const body = assignedElements.find((el) => el.tagName.toLowerCase() === 'spw-table-body');
        if (body) {
            if (this.isZebra) {
                body.setAttribute('is-zebra', 'true');
            }
            else {
                body.removeAttribute('is-zebra');
            }
            if (typeof body.updateZebraStyles === 'function') {
                body.updateZebraStyles();
            }
        }
    }
    applyStickyToChildren() {
        requestAnimationFrame(() => {
            const stickyClass = '--is-sticky';
            const headers = this.el.querySelectorAll('spw-table-header');
            const cells = this.el.querySelectorAll('spw-table-cell');
            const footer = this.el.querySelector('spw-table-footer');
            if (this.isSticky) {
                headers.forEach(header => header.classList.add(stickyClass));
                footer === null || footer === void 0 ? void 0 : footer.classList.add(stickyClass);
            }
            else {
                headers.forEach(header => header.classList.remove(stickyClass));
                cells.forEach(cell => cell.classList.remove(stickyClass));
                footer === null || footer === void 0 ? void 0 : footer.classList.remove(stickyClass);
            }
        });
    }
    sortRows(columnId, direction) {
        var _a;
        const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])');
        const body = slot === null || slot === void 0 ? void 0 : slot.assignedElements().find(el => el.tagName.toLowerCase() === 'spw-table-body');
        if (!body)
            return;
        const rows = Array.from(body.querySelectorAll('spw-table-row'));
        const columnIndex = Array.from(this.el.querySelectorAll('spw-table-header')).findIndex((header) => header.columnId === columnId);
        if (columnIndex === -1)
            return;
        rows.sort((a, b) => {
            const aCell = a.querySelectorAll('spw-table-cell')[columnIndex];
            const bCell = b.querySelectorAll('spw-table-cell')[columnIndex];
            if (!aCell || !bCell)
                return 0;
            const aValue = aCell.textContent.trim();
            const bValue = bCell.textContent.trim();
            if (!isNaN(Number(aValue)) && !isNaN(Number(bValue))) {
                return direction === 'asc' ? +aValue - +bValue : +bValue - +aValue;
            }
            return direction === 'asc' ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
        });
        rows.forEach(row => body.appendChild(row));
        const bodyComponent = body;
        if (bodyComponent === null || bodyComponent === void 0 ? void 0 : bodyComponent.updateZebraStyles) {
            bodyComponent.updateZebraStyles();
        }
    }
    updateHeadersSortState(sort) {
        const headers = this.el.querySelectorAll('spw-table-header');
        headers.forEach((header) => {
            const isCurrent = header.columnId === sort.column;
            header.isSorted = isCurrent;
            header.sortDirection = isCurrent ? sort.direction : undefined;
        });
    }
    formatSize(value) {
        if (value === undefined || value === null) {
            return 'auto';
        }
        return `${value}px`;
    }
    get elementClass() {
        return {
            'spw-table': true,
            'spw-table--is-sticky': this.isSticky,
            'spw-table--resizable': this.resizable,
            [`spw-table--layout-${this.tableLayout}`]: true,
        };
    }
    get containerClass() {
        return {
            'spw-table-container': true,
            'spw-table-container--resizable': this.resizable,
        };
    }
    getMaxHeight() {
        if (this.resizable && this.currentHeight) {
            return `${this.currentHeight}px`;
        }
        return this.formatSize(this.maxHeight);
    }
    render() {
        return (h(Host, { key: 'dd8d60d59f80d90f6cf89dafa53ab7d028e0e035', style: {
                '--spw-table-max-height': this.getMaxHeight(),
                '--spw-table-min-width': this.formatSize(this.minWidth),
            } }, h("div", { key: 'c2c8bc325f257d4d06e45d6e235d6865d50f4435', class: this.containerClass }, h("slot", { key: 'c827c807198079ebeeaa5e1b1271c268a43fe9d2', name: "table-sidebar" }, " "), h("div", { key: '2e77cedb34c6fd92174c1b41b624323af9e2efe0', class: "spw-table-wrapper" }, h("table", { key: 'b35355295ce2f0e417364364c8f07b3d8209f523', part: "table", class: this.elementClass, role: "table", "aria-label": this.accAriaLabel }, h("slot", { key: 'b3ac17bf068bb6884335d49a8d4589c28a11269f' })))), this.resizable && (h("div", { key: '8d8126725c6fafe48800b3dd95a946f87b457a11', class: "spw-table-resize-handle", onMouseDown: this.handleResizeStart, role: "separator", "aria-orientation": "horizontal", "aria-label": "Redimensionner le tableau" }, h("div", { key: 'e46d904ad87ca2092400cf4130066ad554dec7b9', class: "spw-table-resize-handle__bar" }))), h("slot", { key: '5947ad704784b2b29071927ae29393801cd95e43', name: "table-footer" })));
    }
    static get is() { return "spw-table"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["spw-table.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["spw-table.css"]
        };
    }
    static get properties() {
        return {
            "accAriaLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Propri\u00E9t\u00E9 pour l'aria-label, \u00E0 des fins d'accessibilit\u00E9"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "acc-aria-label"
            },
            "isSticky": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Si le header du tableau doit \u00EAtre sticky ou non"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "is-sticky",
                "defaultValue": "false"
            },
            "maxHeight": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Si d\u00E9fini, apparition d'une scrollbar verticale et max-height"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "max-height"
            },
            "minWidth": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Si d\u00E9fini, apparition d'une scrollbar horizontale et max-width"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "min-width",
                "defaultValue": "'600'"
            },
            "tableLayout": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'auto' | 'fixed'",
                    "resolved": "\"auto\" | \"fixed\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Permet de d\u00E9finir le table-layout (auto ou fixed)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "table-layout",
                "defaultValue": "'auto'"
            },
            "isZebra": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "D\u00E9finit un background de couleur diff\u00E9rent une ligne sur 2"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "is-zebra",
                "defaultValue": "false"
            },
            "disableSort": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "D\u00E9sactive le tri natif pour permettre l'utilisation d'une fonction de tri personnalis\u00E9e"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disable-sort",
                "defaultValue": "false"
            },
            "currentSort": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "SortEvent",
                    "resolved": "SortEvent",
                    "references": {
                        "SortEvent": {
                            "location": "local",
                            "path": "/Users/pectonite/Desktop/SPW/spw-design-system/packages/spw-stencil-library/src/components/spw-table/spw-table.tsx",
                            "id": "src/components/spw-table/spw-table.tsx::SortEvent"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "\u00C9tat du tri actuel (colonne et direction). Peut \u00EAtre d\u00E9fini de l'ext\u00E9rieur pour un tri personnalis\u00E9"
                },
                "getter": false,
                "setter": false
            },
            "resizable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Active le redimensionnement manuel de la hauteur du tableau avec un handle"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "resizable",
                "defaultValue": "false"
            },
            "minHeight": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Hauteur minimale autoris\u00E9e lors du redimensionnement (en pixels)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "min-height",
                "defaultValue": "200"
            }
        };
    }
    static get states() {
        return {
            "currentHeight": {}
        };
    }
    static get events() {
        return [{
                "method": "spwSort",
                "name": "spwSort",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "SortEvent",
                    "resolved": "SortEvent",
                    "references": {
                        "SortEvent": {
                            "location": "local",
                            "path": "/Users/pectonite/Desktop/SPW/spw-design-system/packages/spw-stencil-library/src/components/spw-table/spw-table.tsx",
                            "id": "src/components/spw-table/spw-table.tsx::SortEvent"
                        }
                    }
                }
            }, {
                "method": "spwResize",
                "name": "spwResize",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u00C9v\u00E9nement \u00E9mis lorsque la hauteur du tableau est redimensionn\u00E9e"
                },
                "complexType": {
                    "original": "{ height: number }",
                    "resolved": "{ height: number; }",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "currentSort",
                "methodName": "onCurrentSortChange"
            }, {
                "propName": "isSticky",
                "methodName": "onIsStickyChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "spwHeaderClick",
                "method": "handleHeaderClick",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
