import Fragment from "../../helpers/Fragment";
import { h, Host } from "@stencil/core";
import { validateProp } from "../../helpers/Validate/props";
import { PaginationClass, PaginationColors, PaginationSizes, PaginationTypes, } from "./constants";
import { govHost, prepareClasses, toBoolAttrIfDefined } from "../../helpers/Dom/template";
import { paginate } from "./pagination";
import { createID } from "../../utils/string.utils";
import { createArrayRange } from "../../utils/array.utils";
import { AttributeObserver } from "../../helpers/Dom/attribute";
import { ariaAttributes } from "../../helpers/Accessibility/attributes";
import { inheritAriaAttributes } from "../../helpers/Accessibility/accessibility";
export class GovPagination {
    constructor() {
        /**
         * Pagination type
         */
        this.type = "button";
        /**
         * Currently displayed page
         */
        this.current = 1;
        /**
         * Total count of entries
         */
        this.total = 0;
        /**
         * Pagination's size
         */
        this.size = "m";
        /**
         * Style variation of the pagination.
         */
        this.color = "primary";
        /**
         * Maximum number of entries per page
         */
        this.pageSize = 10;
        /**
         * Maximum pages displayed for selection
         */
        this.maxPages = 5;
        /**
         * Adds accessible label for the page select
         */
        this.accessibleSelectLabel = "Vybrat stranu";
        /**
         * Adds accessible label for the page item
         */
        this.accessiblePageLabel = "Strana";
        /**
         * Description of the possibility to go back one page
         */
        this.labelPrev = 'Přejít o stranu zpět';
        /**
         * Description of the option to go to the top of paging
         */
        this.labelStart = 'Přejít na začátek';
        /**
         * Description of the option to go to the end of paging
         */
        this.labelNext = 'Přejít na další stranu';
        /**
         * Description of the option to move one page forward
         */
        this.labelEnd = 'Přejít na konec';
        this.inheritedAttributes = {};
        this.h = govHost(this.host);
        this.pageSelectId = createID("GovPageSelect");
        this.selectId = createID("GovSelect");
    }
    validateType(newValue) {
        validateProp(PaginationTypes, newValue, PaginationClass.root);
    }
    validateSize(newValue) {
        validateProp(PaginationSizes, newValue, PaginationClass.root);
    }
    validateColor(newValue) {
        validateProp(PaginationColors, newValue, PaginationClass.root);
    }
    recalculate() {
        this.recalculatePagination(this.current);
    }
    componentDidLoad() {
        this.attributeObserver = new AttributeObserver(this.host, (attributeName, newValue) => {
            this.onAriaAttributeChange(attributeName, newValue);
        });
        this.attributeObserver.startObserving(ariaAttributes);
    }
    componentWillLoad() {
        this.recalculatePagination(this.current);
        this.validateSize(this.size);
        this.validateColor(this.color);
        this.inheritedAttributes = inheritAriaAttributes(this.host);
    }
    disconnectedCallback() {
        var _a;
        (_a = this.attributeObserver) === null || _a === void 0 ? void 0 : _a.stopObserving();
    }
    onAriaAttributeChange(attributeName, newValue) {
        this.host.removeAttribute(attributeName);
        this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [attributeName]: newValue });
    }
    recalculatePagination(currentPage) {
        this.pagination = paginate(this.total, currentPage, this.pageSize, this.maxPages);
    }
    isActivePageClass(originalClass, page) {
        if (this.pagination.currentPage === page) {
            return originalClass + " is-active";
        }
        else {
            return originalClass;
        }
    }
    prepareLinkUrl(page) {
        if (this.link) {
            return String(this.link).replace("{PAGE}", String(page));
        }
        return undefined;
    }
    resetSelectValue() {
        if (this.spreadSelectRef) {
            this.spreadSelectRef.getRef()
                .then((el) => {
                el.value = '...';
            });
        }
    }
    render() {
        const pageResolver = (page, content, description) => {
            const isDisabled = page === -1;
            const ariaCurrent = toBoolAttrIfDefined(this.pagination.currentPage === page ? true : undefined);
            return (h("gov-button", { href: this.prepareLinkUrl(page), color: this.color, size: this.size, type: "base", disabled: isDisabled, "on-gov-click": (e) => this.onClickHandler(e, page), "aria-label": description ? description : page > -1 ? `${this.accessiblePageLabel} ${page}` : undefined, "aria-current": ariaCurrent, class: PaginationClass.inner, focusable: true }, content));
        };
        return (h(Host, { class: this.h.classes(PaginationClass.root), type: this.type, color: this.color, size: this.size }, h("nav", Object.assign({}, this.inheritedAttributes), h("ul", { class: PaginationClass.list }, h("li", { class: prepareClasses([PaginationClass.item, PaginationClass.itemArrow]) }, pageResolver(this.pagination.currentPage > 1 ? 1 : -1, h("gov-icon", { class: PaginationClass.arrow, name: "chevron-double-left", type: "components" }), this.labelStart)), h("li", { class: prepareClasses([PaginationClass.item, PaginationClass.itemArrow]) }, pageResolver(this.pagination.startPage < this.pagination.currentPage ? this.pagination.currentPage - 1 : -1, h("gov-icon", { class: PaginationClass.arrow, name: "chevron-left", type: "components" }), this.labelPrev)), this.type == "select" ? (h("li", { class: prepareClasses([PaginationClass.item, PaginationClass.itemSelect]) }, h("span", { class: PaginationClass.inner }, h("span", { id: this.pageSelectId, hidden: true }, this.accessibleSelectLabel), h("gov-form-select", { size: this.size, color: this.color, identifier: this.selectIdentifier || this.selectId, "aria-labelledby": this.pageSelectId, "on-gov-change": this.onSelectHandler.bind(this) }, createArrayRange(1, this.pagination.totalPages).map(page => (h("option", { value: page, selected: this.pagination.currentPage === page }, page))))))) : (h(Fragment, null, this.pagination.pages.map(page => (h("li", { class: this.isActivePageClass(PaginationClass.item, page) }, pageResolver(page, page, '')))), this.pagination.totalPages ? (h("li", { class: prepareClasses([PaginationClass.item, PaginationClass.itemMore]) }, h("span", { class: PaginationClass.inner }, h("span", { id: this.pageSelectId, hidden: true }, this.accessibleSelectLabel), h("gov-form-select", { size: this.size, color: this.color, identifier: this.selectIdentifier || this.selectId, "aria-labelledby": this.pageSelectId, ref: el => (this.spreadSelectRef = el), "on-gov-change": this.onSelectHandler.bind(this) }, h("option", { selected: true, hidden: true }, "..."), createArrayRange(1, this.pagination.totalPages).map(page => (h("option", { value: page, selected: false }, page))))))) : null)), h("li", { class: prepareClasses([PaginationClass.item, PaginationClass.itemArrow]) }, pageResolver(this.pagination.totalPages > this.pagination.currentPage ? this.pagination.currentPage + 1 : -1, h("gov-icon", { class: PaginationClass.arrow, name: "chevron-right", type: "components" }), this.labelNext)), h("li", { class: prepareClasses([PaginationClass.item, PaginationClass.itemArrow]) }, pageResolver(this.pagination.totalPages > this.pagination.currentPage ? this.pagination.totalPages : -1, h("gov-icon", { class: PaginationClass.arrow, name: "chevron-double-right", type: "components" }), this.labelEnd))))));
    }
    onClickHandler(e, page) {
        e.stopPropagation();
        this.recalculatePagination(page);
        this.govPage.emit({
            component: PaginationClass.root,
            pagination: this.pagination
        });
    }
    onSelectHandler(e) {
        e.stopPropagation();
        const value = e.detail.value;
        const page = parseInt(value);
        this.resetSelectValue();
        if (isNaN(page) === false) {
            this.recalculatePagination(page);
            if (this.link) {
                window.location.href = this.prepareLinkUrl(page);
            }
            else {
                this.govPage.emit({
                    component: PaginationClass.root,
                    pagination: this.pagination
                });
            }
        }
    }
    static get is() { return "gov-pagination"; }
    static get properties() {
        return {
            "type": {
                "type": "string",
                "attribute": "type",
                "mutable": false,
                "complexType": {
                    "original": "PaginationType",
                    "resolved": "\"button\" | \"select\"",
                    "references": {
                        "PaginationType": {
                            "location": "import",
                            "path": "./constants",
                            "id": "../../../packages/core/src/components/gov-pagination/constants.ts::PaginationType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Pagination type"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"button\""
            },
            "current": {
                "type": "number",
                "attribute": "current",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Currently displayed page"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "1"
            },
            "total": {
                "type": "number",
                "attribute": "total",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Total count of entries"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "0"
            },
            "selectIdentifier": {
                "type": "string",
                "attribute": "select-identifier",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Custom select identifier."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "size": {
                "type": "string",
                "attribute": "size",
                "mutable": false,
                "complexType": {
                    "original": "PaginationSizeType",
                    "resolved": "\"m\" | \"s\"",
                    "references": {
                        "PaginationSizeType": {
                            "location": "import",
                            "path": "./constants",
                            "id": "../../../packages/core/src/components/gov-pagination/constants.ts::PaginationSizeType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Pagination's size"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"m\""
            },
            "color": {
                "type": "string",
                "attribute": "color",
                "mutable": false,
                "complexType": {
                    "original": "PaginationColorType",
                    "resolved": "\"neutral\" | \"primary\"",
                    "references": {
                        "PaginationColorType": {
                            "location": "import",
                            "path": "./constants",
                            "id": "../../../packages/core/src/components/gov-pagination/constants.ts::PaginationColorType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Style variation of the pagination."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"primary\""
            },
            "pageSize": {
                "type": "number",
                "attribute": "page-size",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Maximum number of entries per page"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "10"
            },
            "maxPages": {
                "type": "number",
                "attribute": "max-pages",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Maximum pages displayed for selection"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "5"
            },
            "link": {
                "type": "string",
                "attribute": "link",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Setting a link to redirect to a given page.\r\nThe {PAGE} wildcard can be used in the link to replace the page number.\r\nNote that in the case of paging through a link, it is always necessary to send to the component the current page where the user is."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "accessibleSelectLabel": {
                "type": "string",
                "attribute": "accessible-select-label",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Adds accessible label for the page select"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"Vybrat stranu\""
            },
            "accessiblePageLabel": {
                "type": "string",
                "attribute": "accessible-page-label",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Adds accessible label for the page item"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"Strana\""
            },
            "labelPrev": {
                "type": "string",
                "attribute": "label-prev",
                "mutable": false,
                "complexType": {
                    "original": "\"P\u0159ej\u00EDt o stranu zp\u011Bt\"",
                    "resolved": "\"P\u0159ej\u00EDt o stranu zp\u011Bt\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Description of the possibility to go back one page"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'P\u0159ej\u00EDt o stranu zp\u011Bt'"
            },
            "labelStart": {
                "type": "string",
                "attribute": "label-start",
                "mutable": false,
                "complexType": {
                    "original": "\"P\u0159ej\u00EDt na za\u010D\u00E1tek\"",
                    "resolved": "\"P\u0159ej\u00EDt na za\u010D\u00E1tek\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Description of the option to go to the top of paging"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'P\u0159ej\u00EDt na za\u010D\u00E1tek'"
            },
            "labelNext": {
                "type": "string",
                "attribute": "label-next",
                "mutable": false,
                "complexType": {
                    "original": "\"P\u0159ej\u00EDt na dal\u0161\u00ED stranu\"",
                    "resolved": "\"P\u0159ej\u00EDt na dal\u0161\u00ED stranu\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Description of the option to go to the end of paging"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'P\u0159ej\u00EDt na dal\u0161\u00ED stranu'"
            },
            "labelEnd": {
                "type": "string",
                "attribute": "label-end",
                "mutable": false,
                "complexType": {
                    "original": "\"P\u0159ej\u00EDt na konec\"",
                    "resolved": "\"P\u0159ej\u00EDt na konec\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Description of the option to move one page forward"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'P\u0159ej\u00EDt na konec'"
            }
        };
    }
    static get states() {
        return {
            "pagination": {},
            "inheritedAttributes": {}
        };
    }
    static get events() {
        return [{
                "method": "govPage",
                "name": "gov-page",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Event called when changing the page with the current setting of the whole paging"
                },
                "complexType": {
                    "original": "PaginationEvent",
                    "resolved": "PaginationEvent",
                    "references": {
                        "PaginationEvent": {
                            "location": "import",
                            "path": "./gov-pagination.types",
                            "id": "../../../packages/core/src/components/gov-pagination/gov-pagination.types.ts::PaginationEvent"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "type",
                "methodName": "validateType"
            }, {
                "propName": "size",
                "methodName": "validateSize"
            }, {
                "propName": "color",
                "methodName": "validateColor"
            }, {
                "propName": "current",
                "methodName": "recalculate"
            }, {
                "propName": "total",
                "methodName": "recalculate"
            }, {
                "propName": "pageSize",
                "methodName": "recalculate"
            }, {
                "propName": "maxPages",
                "methodName": "recalculate"
            }];
    }
}
//# sourceMappingURL=gov-pagination.js.map
