import { Host, h } from "@stencil/core";
import { PagerSizeOption } from '../../utils/utils';
import Tunnel from '../locale/i18n.provider';
const MAX_SHOWN_PAGES = 5;
export class Pager {
    constructor() {
        this.pageCount = 1;
        /**
         * If true, the pager will allows users to jump to the first page and last page
         */
        this.firstLast = false;
        /**
         * If true, the pager will display the displayed record range and record total
         */
        this.info = false;
        /**
         * The current page
         */
        this.page = 1;
        /**
         * The number of results to show per page. Default is 20.
         */
        this.size = PagerSizeOption.Medium;
    }
    onPageChange() {
        this.calculateRange();
    }
    onSizeChange() {
        this.calculatePageCount();
    }
    onTotalChange(newVal, oldVal) {
        this.calculatePageCount();
        if (isNaN(oldVal) || isNaN(newVal))
            return;
        if (newVal < oldVal && this.page > this.pageCount) {
            this.page = this.pageCount;
        }
    }
    componentDidLoad() {
        this.calculatePageCount();
        this.anjPagerDidLoad.emit();
    }
    onSizeSelect({ detail }) {
        const previous = this.page;
        this.page = 1;
        this.size = detail.value;
        this.emitChange(previous);
    }
    calculatePageCount() {
        this.pageCount = this.total ? Math.ceil(this.total / this.size) : 1;
        this.calculateRange();
    }
    calculateRange() {
        const base = this.size * this.page;
        const last = this.total && base > this.total ? base - this.size + (this.total % this.size) : base;
        const first = base - this.size;
        this.range = [first, last];
    }
    onPage(page) {
        const previous = this.page;
        if (page !== this.page && page > 0 && page <= this.pageCount) {
            this.page = page;
            this.emitChange(previous);
        }
    }
    emitChange(prev) {
        this.anjPage.emit({ page: this.page, rangeMin: this.range[0], rangeMax: this.range[1], size: this.size, total: this.total, previousPage: prev });
    }
    generateInfo() {
        const from = this.numberFormatter((this.total) ? this.range[0] + 1 : 0);
        const to = this.numberFormatter((this.total) ? this.range[1] : 0);
        const total = this.numberFormatter(this.total);
        return `${from} - ${to} | ${total}`;
    }
    generatePages() {
        const pages = [];
        let min = this.page - 2 > 0 ? this.page - 2 : 1;
        if (min + MAX_SHOWN_PAGES > this.pageCount + 1) {
            min = this.pageCount + 1 - MAX_SHOWN_PAGES;
        }
        for (let i = min > 0 ? min : 1; i < this.pageCount + 1; i++) {
            pages.push(i);
            if (pages.length === 5) {
                break;
            }
        }
        return pages;
    }
    showSizes() {
        return this.sizes && this.sizes.length > 0;
    }
    pageButtons(pages) {
        const prevDisabled = this.page === 1;
        const nextDisabled = this.page === this.pageCount;
        const buttons = [
            h("anj-button", { context: "text", disabled: prevDisabled, onClick: () => this.onPage(this.page - 1), "aria-label": "Previous" },
                h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" },
                    h("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }))),
            pages.map(p => h("anj-button", { context: "text", class: "anj-page-number", disabled: p === this.page, active: p === this.page, onClick: () => this.onPage(p) }, this.numberFormatter(p))),
            h("anj-button", { context: "text", disabled: nextDisabled, onClick: () => this.onPage(this.page + 1), "aria-label": "Next" },
                h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" },
                    h("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" })))
        ];
        if (this.firstLast) {
            buttons.unshift(h("anj-button", { context: "text", disabled: prevDisabled, onClick: () => this.onPage(1), "aria-label": "First" },
                h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" },
                    h("path", { d: "M18.41 16.59L13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z" }))));
            buttons.push(h("anj-button", { context: "text", disabled: nextDisabled, onClick: () => this.onPage(this.pageCount), "aria-label": "Last" },
                h("svg", { slot: "icon-only", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" },
                    h("path", { d: "M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z" }))));
        }
        return buttons;
    }
    render() {
        return (h(Host, { class: { 'anj-page-sizable': this.showSizes() } },
            this.showSizes() ?
                h("div", { class: "anj-pager-group anj-page-sizer" },
                    h("anj-select", { value: this.size }, this.sizes.map(s => h("anj-option", { value: s }, s))),
                    h("span", { class: "anj-page-text" }, "per page")) : undefined,
            h("div", { class: "anj-pager-group anj-page-buttons" },
                this.info && this.range && this.total
                    ? h("span", { class: "anj-pager-info" }, this.generateInfo())
                    : undefined,
                this.pageButtons(this.generatePages()))));
    }
    static get is() { return "anj-pager"; }
    static get encapsulation() { return "scoped"; }
    static get originalStyleUrls() { return {
        "$": ["pager.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["pager.css"]
    }; }
    static get properties() { return {
        "firstLast": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "If true, the pager will allows users to jump to the first page and last page"
            },
            "attribute": "first-last",
            "reflect": false,
            "defaultValue": "false"
        },
        "numberFormatter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "IntlFormatFn",
                "resolved": "(value: any, variables?: any) => string",
                "references": {
                    "IntlFormatFn": {
                        "location": "import",
                        "path": "../locale/i18n.provider"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [{
                        "text": undefined,
                        "name": "internal"
                    }],
                "text": ""
            }
        },
        "info": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "If true, the pager will display the displayed record range and record total"
            },
            "attribute": "info",
            "reflect": false,
            "defaultValue": "false"
        },
        "page": {
            "type": "number",
            "mutable": true,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The current page"
            },
            "attribute": "page",
            "reflect": false,
            "defaultValue": "1"
        },
        "range": {
            "type": "unknown",
            "mutable": true,
            "complexType": {
                "original": "RecordBounds",
                "resolved": "[number, number]",
                "references": {
                    "RecordBounds": {
                        "location": "import",
                        "path": "../../types/types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The range between first displayed record and last"
            }
        },
        "size": {
            "type": "number",
            "mutable": true,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The number of results to show per page. Default is 20."
            },
            "attribute": "size",
            "reflect": false,
            "defaultValue": "PagerSizeOption.Medium"
        },
        "sizes": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "number[]",
                "resolved": "number[]",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Sizes"
            }
        },
        "total": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The total (known) number of records"
            },
            "attribute": "total",
            "reflect": false
        }
    }; }
    static get states() { return {
        "pageCount": {}
    }; }
    static get events() { return [{
            "method": "anjPagerDidLoad",
            "name": "anjPagerDidLoad",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the use selects a new page"
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjPage",
            "name": "anjPage",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the use selects a new page"
            },
            "complexType": {
                "original": "PageChange",
                "resolved": "PageChange",
                "references": {
                    "PageChange": {
                        "location": "import",
                        "path": "../../types/types"
                    }
                }
            }
        }]; }
    static get elementRef() { return "element"; }
    static get watchers() { return [{
            "propName": "page",
            "methodName": "onPageChange"
        }, {
            "propName": "size",
            "methodName": "onSizeChange"
        }, {
            "propName": "total",
            "methodName": "onTotalChange"
        }]; }
    static get listeners() { return [{
            "name": "anjChange",
            "method": "onSizeSelect",
            "target": undefined,
            "capture": false,
            "passive": false
        }]; }
}
Tunnel.injectProps(Pager, ['numberFormatter']);
