import { __decorate, __metadata } from "tslib";
import { Host, h, } from "@stencil/core";
import { BEM } from "../../utils/bem";
import { ListenToBreakpoints, balBreakpoints } from "../../utils/breakpoints";
import { ListenToConfig, defaultConfig } from "../../utils/config";
import { i18nControlLabel } from "./bal-pagination.i18n";
import { generatePaginationControl } from "./bal-pagination.util";
export class Pagination {
    constructor() {
        this._value = 1;
        this.isMobile = balBreakpoints.isMobile;
        this.language = defaultConfig.language;
        /**
         * Align the buttons to start, center or end
         */
        this.align = '';
        /**
         * Size of the buttons
         */
        this.size = '';
        /**
         * Defines the layout of the pagination
         */
        this.interface = '';
        /**
         * Disables component
         */
        this.disabled = false;
        /**
         * Current selected page
         */
        this.value = 1;
        /**
         * The total amount of pages
         */
        this.totalPages = 1;
        /**
         * Specify the max visible pages before and after the selected page
         */
        this.pageRange = 2;
        /**
         * If 'true, the pagination will be sticky to the top
         */
        this.sticky = false;
        /**
         * If sticky, the top position will be determined by this value
         */
        this.top = 0;
    }
    valueChanged(newValue) {
        this._value = newValue;
    }
    topValueChanged(newValue) {
        if (this.sticky) {
            this.el.style.top = `${newValue}px`;
        }
    }
    componentWillLoad() {
        this._value = this.value;
        this.topValueChanged(this.top);
    }
    breakpointListener(breakpoints) {
        this.isMobile = breakpoints.mobile;
    }
    /**
     * Go to the next page
     */
    async next() {
        if (this._value < this.totalPages) {
            this._value = this._value + 1;
            this.balChangeEventEmitter.emit(this._value);
        }
    }
    /**
     * Go to the previous page
     */
    async previous() {
        if (this._value !== 1) {
            this._value = this._value - 1;
            this.balChangeEventEmitter.emit(this._value);
        }
    }
    /**
     * @internal define config for the component
     */
    async configChanged(state) {
        this.language = state.language;
    }
    selectPage(pageNumber) {
        this._value = pageNumber;
        this.balChangeEventEmitter.emit(this._value);
    }
    getItems(pageRange = 2) {
        const controls = generatePaginationControl(this._value, this.totalPages, pageRange);
        return controls.map((control) => {
            if (control.type === 'page') {
                return this.renderPageElement(Number(control.label));
            }
            else {
                return this.renderEllipsisElement();
            }
        });
    }
    renderEllipsisElement() {
        const more = BEM.block('pagination').element('nav').element('pagination-list').element('more');
        return (h("li", { "aria-hidden": 'true' }, h("div", { class: Object.assign(Object.assign({}, more.class()), more.modifier('disabled').class(this.disabled)) }, h("span", null, "\u2026"))));
    }
    renderPageElement(pageNumber) {
        const isActive = this._value === pageNumber;
        const dot = BEM.block('pagination').element('nav').element('pagination-list').element('dot');
        if (this.interface === 'small') {
            return (h("li", null, h("span", { role: "button", "aria-current": isActive ? 'true' : undefined, class: Object.assign(Object.assign(Object.assign({}, dot.class()), dot.modifier('active').class(isActive)), dot.modifier('inactive').class(!isActive)), "aria-label": pageNumber, onClick: () => this.selectPage(pageNumber) })));
        }
        return (h("li", null, h("button", { class: {
                'button': true,
                'is-square': true,
                'is-primary': isActive,
                'is-text': !isActive,
                'is-disabled': this.disabled,
                'is-small': this.isMobile || this.size === 'small',
            }, "aria-current": isActive ? 'true' : undefined, onClick: () => this.selectPage(pageNumber), "data-testid": "bal-pagination-page-number" }, pageNumber)));
    }
    render() {
        const mobileItems = this.getItems(1);
        const tabletItems = this.getItems(this.pageRange);
        const block = BEM.block('pagination');
        const elNav = block.element('nav');
        const elPrevious = elNav.element('pagination-previous');
        const elNext = elNav.element('pagination-next');
        const elList = elNav.element('pagination-list');
        const isSmall = this.interface === 'small';
        const buttonColor = isSmall ? 'is-link' : 'is-text';
        const buttonSize = isSmall || this.size === 'small' || this.isMobile ? 'is-small' : '';
        const flat = isSmall;
        const leftControlTitle = i18nControlLabel[this.language].left;
        const rightControlTitle = i18nControlLabel[this.language].right;
        const hasBasicNavigationButtons = this.interface === '' || (isSmall && this.totalPages <= 5);
        const SmallWithText = () => (h("span", { key: '6851055924de8b04d1c2426851296fc43de9d5a8', class: Object.assign(Object.assign({}, elList.class()), elList.modifier(`context-${this.interface}`).class()) }, h("span", { key: '3c7b45ffc1b9844a54b05455444fc27f0947ed23' }, this._value), ' / ' + this.totalPages));
        const PaginationTablet = () => (h("ul", { key: 'ac07986c347c110d113f46ceff2cb77ced99c5da', class: Object.assign(Object.assign(Object.assign({}, elList.class()), elList.modifier(`context-${this.interface}`).class()), { 'is-disabled': this.disabled }), "data-testid": "bal-pagination-list" }, tabletItems));
        const PaginationMobile = () => (h("ul", { key: '9b83d79dd7bb63cfeb8d98ff940f2a91c9db72c8', class: Object.assign(Object.assign(Object.assign({}, elList.class()), elList.modifier(`context-${this.interface}`).class()), { 'is-disabled': this.disabled }), "data-testid": "bal-pagination-list" }, mobileItems));
        return (h(Host, { key: 'c9f4756500a4f05b3d4756c0c568d6e7d930292c', class: Object.assign(Object.assign({}, block.class()), block.modifier('is-sticky').class(this.sticky)) }, h("nav", { key: '463f770907d3b73651eb525c951870d53afb3147', class: Object.assign(Object.assign(Object.assign({}, elNav.class()), elNav.modifier(`context-${this.interface}`).class(this.interface !== '')), elNav.modifier(`align-${this.align}`).class(this.align !== '')), role: "navigation", "aria-label": "pagination" }, !this.disabled ? (h("button", { class: Object.assign(Object.assign({ 'button': true, 'is-square': true, 'is-disabled': this._value < 2, 'is-flat': flat, [buttonColor]: true, [buttonSize]: true }, elPrevious.class()), elPrevious.modifier(`context-${this.interface}`).class()), disabled: this._value < 2, onClick: () => this.previous(), "data-testid": "bal-pagination-controls-left", title: leftControlTitle }, h("bal-icon", { name: "nav-go-left", size: "small", disabled: this._value < 2 }))) : (''), !this.disabled ? (h("button", { class: Object.assign(Object.assign({ 'button': true, 'is-square': true, 'is-disabled': this._value === this.totalPages, 'is-flat': flat, [buttonColor]: true, [buttonSize]: true }, elNext.class()), elNext.modifier(`context-${this.interface}`).class()), disabled: this._value === this.totalPages, onClick: () => this.next(), "data-testid": "bal-pagination-controls-right", title: rightControlTitle }, h("bal-icon", { name: "nav-go-right", size: "small", disabled: this._value === this.totalPages }))) : (''), hasBasicNavigationButtons && this.isMobile ? h(PaginationMobile, null) : '', hasBasicNavigationButtons && !this.isMobile ? h(PaginationTablet, null) : '', !hasBasicNavigationButtons ? h(SmallWithText, null) : '')));
    }
    static get is() { return "bal-pagination"; }
    static get originalStyleUrls() {
        return {
            "$": ["bal-pagination.sass"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bal-pagination.css"]
        };
    }
    static get properties() {
        return {
            "align": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "BalProps.BalPaginationAlignment",
                    "resolved": "\"\" | \"end\" | \"start\"",
                    "references": {
                        "BalProps": {
                            "location": "global",
                            "id": "global::BalProps"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Align the buttons to start, center or end"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "align",
                "defaultValue": "''"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "BalProps.BalPaginationSize",
                    "resolved": "\"\" | \"small\"",
                    "references": {
                        "BalProps": {
                            "location": "global",
                            "id": "global::BalProps"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Size of the buttons"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "size",
                "defaultValue": "''"
            },
            "interface": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "BalProps.BalPaginationInterface",
                    "resolved": "\"\" | \"small\"",
                    "references": {
                        "BalProps": {
                            "location": "global",
                            "id": "global::BalProps"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the layout of the pagination"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "interface",
                "defaultValue": "''"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Disables component"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "value": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Current selected page"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value",
                "defaultValue": "1"
            },
            "totalPages": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The total amount of pages"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "total-pages",
                "defaultValue": "1"
            },
            "pageRange": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Specify the max visible pages before and after the selected page"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "page-range",
                "defaultValue": "2"
            },
            "sticky": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If 'true, the pagination will be sticky to the top"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "sticky",
                "defaultValue": "false"
            },
            "top": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If sticky, the top position will be determined by this value"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "top",
                "defaultValue": "0"
            }
        };
    }
    static get states() {
        return {
            "_value": {},
            "isMobile": {},
            "language": {}
        };
    }
    static get events() {
        return [{
                "method": "balChangeEventEmitter",
                "name": "balChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Triggers when a page change happens"
                },
                "complexType": {
                    "original": "BalEvents.BalPaginationChangeDetail",
                    "resolved": "number",
                    "references": {
                        "BalEvents": {
                            "location": "global",
                            "id": "global::BalEvents"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "next": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Go to the next page",
                    "tags": []
                }
            },
            "previous": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Go to the previous page",
                    "tags": []
                }
            },
            "configChanged": {
                "complexType": {
                    "signature": "(state: BalConfigState) => Promise<void>",
                    "parameters": [{
                            "name": "state",
                            "type": "BalConfigState",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "BalConfigState": {
                            "location": "import",
                            "path": "../../utils/config",
                            "id": "src/utils/config/index.ts::BalConfigState"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "define config for the component"
                        }]
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "valueChanged"
            }, {
                "propName": "top",
                "methodName": "topValueChanged"
            }];
    }
}
__decorate([
    ListenToBreakpoints(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], Pagination.prototype, "breakpointListener", null);
__decorate([
    ListenToConfig(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Pagination.prototype, "configChanged", null);
