import { h } from "@stencil/core";
import { Row } from '../row/row';
import { ALL_ROWS_KEY, TableClasses } from '../table.utils';
export class RowSelection {
    constructor() {
        this.rowsDidChangeListener = () => this.onRowsDidChange();
        /**
         * The mode of selection
         * Possible values are: `"batch"`, and `"single`. Defaults to "single"
         */
        this.mode = 'single';
        /**
         * Renderer to use for cell content when the selected cell conditions are met
         */
        this.row = this.renderRow.bind(this);
        /**
         * For batch selection only, will renderer a "select all" checkbox
         */
        this.showCheckAll = false;
        /**
         * If true, will render checkboxes for batch selection and radio buttons for single
         */
        this.showChecks = false;
        /**
         * Rules to use for using this as a renderer
         */
        this.when = this.useAsRenderer.bind(this);
    }
    connectedCallback() {
        this.table = this.element.closest('anj-table');
        this.table.addEventListener('anjRowsDidLoad', this.rowsDidChangeListener);
    }
    componentDidLoad() {
        this.anjRowControlDidLoad.emit();
    }
    disconnectedCallback() {
        this.table.removeEventListener('anjRowsDidLoad', this.rowsDidChangeListener);
    }
    static clearStyles(el) {
        if (el) {
            el.removeAttribute('style');
        }
    }
    onRowsDidChange() {
        if (this.headerControl) {
            return this.checkSelectAll();
        }
    }
    async onSelection(event) {
        event.stopPropagation();
        const detail = event.detail;
        this.table.selectedRowKeys = this.table.selectedRowKeys.includes(detail.key) ? this.table.selectedRowKeys.filter(k => k !== detail.key)
            : (this.mode === 'batch') ? this.table.selectedRowKeys.concat([detail.key]) : [detail.key];
        if (this.mode === 'batch' && this.showCheckAll) {
            await this.checkSelectAll();
        }
        this.anjRowSelect.emit({ key: detail.key, selectedRowKeys: this.table.selectedRowKeys });
    }
    async onSelectAll(event) {
        event.stopPropagation();
        const checkbox = this.headerControl.querySelector('anj-checkbox');
        const rows = await this.table.getRows();
        const rowKeys = rows.map(r => r[this.table.rowKey]);
        const selectAll = (checkbox.checked || checkbox.indeterminate);
        this.table.selectedRowKeys = selectAll
            ? this.table.selectedRowKeys.concat(rowKeys.filter(k => !this.table.selectedRowKeys.includes(k)))
            : this.table.selectedRowKeys.filter(k => !rowKeys.includes(k));
        this.anjRowSelect.emit({ key: undefined, selectedRowKeys: this.table.selectedRowKeys });
        return this.checkSelectAll(rows, rowKeys, checkbox);
    }
    /**
     * This is a little wonky but the main thrust is that we get all the args in onSelectAll, so if we're calling this from there, it doesn't make sense to
     * get it all again.
     */
    async checkSelectAll(rs, keys, check) {
        const rows = rs || await this.table.getRows();
        const checkbox = check || this.headerControl.querySelector('anj-checkbox');
        const rowKeys = keys || rows.map(r => r[this.table.rowKey]);
        const selectedKeys = rowKeys.filter(k => this.table.selectedRowKeys.includes(k));
        checkbox.indeterminate = selectedKeys.length < rows.length && selectedKeys.length > 0;
        this.headerControl.selected = selectedKeys.length > 0;
        checkbox.checked = selectedKeys.length > 0;
    }
    renderRow(props) {
        const attrs = { colspan: props.columns.length - 1 };
        // The first cell is a dummy cell to keep things kosher
        return (h(Row, Object.assign({}, props),
            h("tr", { class: TableClasses.detailRow },
                h("td", { style: { border: '0', 'border-color': 'transparent', width: '0', padding: '0' } }),
                h("td", Object.assign({}, attrs, { class: TableClasses.detailCell, ref: (r) => { RowSelection.clearStyles(r); } }),
                    h("div", { class: TableClasses.detailWrapper }, this.template
                        ? h("div", { class: TableClasses.detail, ref: r => this.table.renderer.fromTemplate(this.template, r, props.row, props.rowIndex) })
                        : this.formatter ? h("div", { class: TableClasses.detail, innerHTML: this.formatter(props.row, props.rowIndex) })
                            : h("div", { class: TableClasses.detail }, this.renderer(props.row, props.rowIndex)))))));
    }
    cell(data) {
        return h("anj-row-select-control", { showCheck: this.showChecks, rowKey: data[this.table.rowKey], selected: this.selected(data), mode: this.mode, labelFormatter: this.labelFormatter, onAnjRowSelectClick: e => this.onSelection(e) });
    }
    header() {
        return this.mode === 'batch' && this.showCheckAll ?
            h("anj-row-select-control", { showCheck: true, rowKey: ALL_ROWS_KEY, mode: this.mode, labelFormatter: this.labelFormatter, ref: e => this.headerControl = e, onAnjRowSelectClick: e => this.onSelectAll(e) }) : undefined;
    }
    selected(data) {
        return this.table.selectedRowKeys.includes(data[this.table.rowKey]);
    }
    hasDetail() {
        return !!(this.template || this.renderer || this.formatter);
    }
    useAsRenderer(data) {
        return (this.hasDetail() && this.selected(data));
    }
    render() {
        return h("anj-column", { filterable: false, internal: true, pinned: "left", editable: false, sizable: false, pinnable: false, orderable: false, selectable: false, sortable: false, name: `row-selection${this.showChecks ? '-checks' : ''}`, width: this.showChecks ? '42px' : '0', cellRenderer: (data) => this.cell(data), headerRenderer: () => this.header() });
    }
    static get is() { return "anj-row-selection"; }
    static get originalStyleUrls() { return {
        "$": ["row-selection.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["row-selection.css"]
    }; }
    static get properties() { return {
        "formatter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "DetailFormatter",
                "resolved": "(row: RowData, index?: number, colspan?: number) => string",
                "references": {
                    "DetailFormatter": {
                        "location": "import",
                        "path": "../table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Function to use to format the detail"
            }
        },
        "labelFormatter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "BooleanLabelFormatter",
                "resolved": "(key: any, selected: boolean) => string",
                "references": {
                    "BooleanLabelFormatter": {
                        "location": "import",
                        "path": "../../../types/types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Formatter for the hidden label for multi-select checkboxes"
            }
        },
        "mode": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "RowSelectionMode",
                "resolved": "\"batch\" | \"single\"",
                "references": {
                    "RowSelectionMode": {
                        "location": "import",
                        "path": "../table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The mode of selection\nPossible values are: `\"batch\"`, and `\"single`. Defaults to \"single\""
            },
            "attribute": "mode",
            "reflect": true,
            "defaultValue": "'single'"
        },
        "renderer": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "DetailRenderer",
                "resolved": "(row: RowData, index?: number, colspan?: number) => any",
                "references": {
                    "DetailRenderer": {
                        "location": "import",
                        "path": "../table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Function to use to format the detail"
            }
        },
        "row": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "RowRenderFn",
                "resolved": "(props: RowProps) => any",
                "references": {
                    "RowRenderFn": {
                        "location": "import",
                        "path": "../table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Renderer to use for cell content when the selected cell conditions are met"
            },
            "defaultValue": "this.renderRow.bind(this)"
        },
        "showCheckAll": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "For batch selection only, will renderer a \"select all\" checkbox"
            },
            "attribute": "show-check-all",
            "reflect": false,
            "defaultValue": "false"
        },
        "showChecks": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "If true, will render checkboxes for batch selection and radio buttons for single"
            },
            "attribute": "show-checks",
            "reflect": false,
            "defaultValue": "false"
        },
        "template": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Template to use for master/detail selection"
            },
            "attribute": "template",
            "reflect": false
        },
        "when": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "RowRenderTest",
                "resolved": "(row: RowData) => boolean",
                "references": {
                    "RowRenderTest": {
                        "location": "import",
                        "path": "../table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Rules to use for using this as a renderer"
            },
            "defaultValue": "this.useAsRenderer.bind(this)"
        }
    }; }
    static get events() { return [{
            "method": "anjRowControlDidLoad",
            "name": "anjRowControlDidLoad",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the selector has been created."
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjRowSelect",
            "name": "anjRowSelect",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the selected rows changes"
            },
            "complexType": {
                "original": "RowSelectionChange",
                "resolved": "RowSelectionChange",
                "references": {
                    "RowSelectionChange": {
                        "location": "import",
                        "path": "../table.types"
                    }
                }
            }
        }]; }
    static get elementRef() { return "element"; }
}
