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,
            "attr": "batch-size"
        },
        "component": {
            "type": String,
            "attr": "component"
        },
        "componentOptions": {
            "type": "Any",
            "attr": "component-options"
        },
        "data": {
            "state": true
        },
        "display": {
            "type": String,
            "attr": "display"
        },
        "features": {
            "type": "Any",
            "attr": "features",
            "mutable": true
        },
        "item": {
            "type": Boolean,
            "attr": "item"
        },
        "limit": {
            "state": true
        },
        "loadingSpinner": {
            "type": String,
            "attr": "loading-spinner"
        },
        "loadingText": {
            "type": String,
            "attr": "loading-text"
        },
        "mapId": {
            "type": String,
            "attr": "map-id"
        },
        "order": {
            "type": String,
            "attr": "order"
        },
        "orderBy": {
            "type": String,
            "attr": "order-by"
        },
        "sourceId": {
            "type": String,
            "attr": "source-id",
            "watchCallbacks": ["handleSourceId"]
        },
        "styleId": {
            "type": String,
            "attr": "style-id",
            "watchCallbacks": ["handleSourceId"]
        }
    }; }
    static get listeners() { return [{
            "name": "ionInfinite",
            "method": "handleInfiniteScroll"
        }, {
            "name": "body:glStyleElementModified",
            "method": "handleStyleUpdated"
        }]; }
}
