import { h } from '@stencil/core';
import { _t } from '../i18n/i18n';
import { getMap } from '../utils';
export class FeatureList {
    constructor() {
        this.data = {};
        this.batchSize = 20;
        this.display = 'visible';
        this.features = [];
        this.item = true;
        this.loadingSpinner = 'bubbles';
        this.loadingText = _t('webmapgl.feature-list.loading');
        this.order = 'asc';
    }
    componentWillLoad() {
        this.handleSourceId();
        const map = this.getMap();
        if (map)
            map.on('moveend', () => this.filter());
    }
    handleInfiniteScroll(e) {
        this.limit += this.batchSize;
        e.target.complete();
    }
    handleStyleUpdated(e) {
        if (e.detail.id === this.styleId)
            this.handleSourceId();
    }
    async handleSourceId() {
        const style = document.querySelector(`#${this.styleId}`);
        if (!style || !style.json.sources)
            return;
        const data = style.json.sources[this.sourceId].data;
        if (typeof data === 'string') {
            let res = await fetch(data);
            this.data = await res.json();
        }
        else {
            this.data = data;
        }
        this.filter();
    }
    getMap() {
        return getMap(this.mapId).map;
    }
    async filter() {
        if (!this.data.features)
            return;
        let features;
        if (this.display === 'all') {
            features = this.data.features;
        }
        else {
            let bounds = this.getMap().getBounds();
            features = this.data.features.filter((feature) => {
                let [lng, lat] = feature.geometry.coordinates;
                return lng >= bounds.getWest() && lng <= bounds.getEast() &&
                    lat >= bounds.getSouth() && lat <= bounds.getNorth();
            });
        }
        this.limit = this.batchSize;
        this.features = this.sort(features);
    }
    sort(features) {
        if (this.order === 'none' || !this.orderBy)
            return features;
        features.sort((aFeature, bFeature) => {
            const a = aFeature.properties[this.orderBy];
            const b = bFeature.properties[this.orderBy];
            if (a < b)
                return (this.order === 'asc') ? -1 : 1;
            if (a > b)
                return (this.order === 'asc') ? 1 : -1;
            return 0;
        });
        return features;
    }
    render() {
        let ComponentTag = this.component;
        let features = (this.limit) ?
            this.features.slice(0, this.limit) : this.features;
        let hasMore = features.length < this.features.length;
        let items = features.map((feature) => {
            let component = h(ComponentTag, Object.assign({ feature: feature }, this.componentOptions));
            return (this.item) ? h("ion-item", null, component) : component;
        });
        return ([
            h("ion-list", null,
                h("slot", { name: "start" }),
                items,
                h("slot", { name: "end" })),
            h("ion-infinite-scroll", { disabled: !hasMore },
                h("ion-infinite-scroll-content", { "loading-spinner": this.loadingSpinner, "loading-text": this.loadingText }))
        ]);
    }
    static get is() { return "gl-feature-list"; }
    static get properties() { return {
        "batchSize": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "batch-size",
            "reflect": false,
            "defaultValue": "20"
        },
        "component": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "component",
            "reflect": false
        },
        "componentOptions": {
            "type": "any",
            "mutable": false,
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "component-options",
            "reflect": false
        },
        "display": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "'all' | 'visible'",
                "resolved": "\"all\" | \"visible\"",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "display",
            "reflect": false,
            "defaultValue": "'visible'"
        },
        "features": {
            "type": "unknown",
            "mutable": true,
            "complexType": {
                "original": "any[]",
                "resolved": "any[]",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "defaultValue": "[]"
        },
        "item": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "item",
            "reflect": false,
            "defaultValue": "true"
        },
        "loadingSpinner": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "loading-spinner",
            "reflect": false,
            "defaultValue": "'bubbles'"
        },
        "loadingText": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "loading-text",
            "reflect": false,
            "defaultValue": "_t('webmapgl.feature-list.loading')"
        },
        "mapId": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "map-id",
            "reflect": false
        },
        "orderBy": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "order-by",
            "reflect": false
        },
        "order": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "'asc' | 'desc' | 'none'",
                "resolved": "\"asc\" | \"desc\" | \"none\"",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "order",
            "reflect": false,
            "defaultValue": "'asc'"
        },
        "styleId": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "style-id",
            "reflect": false
        },
        "sourceId": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "source-id",
            "reflect": false
        }
    }; }
    static get states() { return {
        "data": {},
        "limit": {}
    }; }
    static get watchers() { return [{
            "propName": "styleId",
            "methodName": "handleSourceId"
        }, {
            "propName": "sourceId",
            "methodName": "handleSourceId"
        }]; }
    static get listeners() { return [{
            "name": "ionInfinite",
            "method": "handleInfiniteScroll",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "glStyleElementModified",
            "method": "handleStyleUpdated",
            "target": "body",
            "capture": false,
            "passive": false
        }]; }
}
