import { Importer } from './abstract-importer.class';
import { Marker } from '../marker';
import { FilterItem } from '../filter-item';
import { notifyErrorIfInDevelopment } from '../../../common/development-error-notification';

export class ApiImporter extends Importer {

    /**
     * @returns {Promise}
     */
    import() {
        const promises = [];
        if (this.settings.markerUrl) {
            promises.push(this.importMarkers(this.settings.markerUrl));
        }
        if (this.settings.filterItemUrl) {
            promises.push(this.importFilterItems(this.settings.filterItemUrl));
        }
        return Promise.all(promises);
    }

    async importMarkers(url) {
        const body = await this.sendRequest(url);
        const markers = Object.values(body).map(data => this.dataToMarker(data));
        this.source.addMarkers(markers);
    }

    async importFilterItems(url) {
        const body = await this.sendRequest(url);
        const items = Object.values(body).map(item => this.dataToFilterItem(item));
        this.source.addFilterItems(items);
    }

    async sendRequest(url) {
        const response = await fetch(url, { credentials: 'same-origin' });
        const body = await response.json();
        if (response.status !== 200 || body.error) {
            if (body.error) {
                const trace = body.error.trace;
                delete body.error.trace;
                console.error(body.error);
                // eslint-disable-next-line no-console
                console.table(trace);
                notifyErrorIfInDevelopment(body.error);
            }
            throw new Error(`Requesting ${url} failed: ${response.statusText}`);
        }
        return body;
    }

    dataToFilterItem(data, parent = null) {
        const filterItem = new FilterItem();
        filterItem.title = data.title;
        filterItem.path = data.path;
        filterItem.style = data.style;
        filterItem.overwriteMarkerStyles = !!data.overwriteMarkerStyles;
        filterItem.parent = parent;
        filterItem.openByDefault = !!data.openByDefault;
        filterItem.children = Object.values(data.children).map(child => this.dataToFilterItem(child, filterItem));
        return filterItem;
    }

    dataToMarker(data) {
        const marker = new Marker();

        if (data.paths) {
            marker.paths = data.paths;
        } else if (data.path) {
            marker.paths = [ data.path ];
        }
        marker.title = data.title || '';
        marker.description = data.description || '';
        marker.categoryTitle = data.categoryTitle || '';
        marker.image = data.image || null;
        marker.style = data.defaultStyle || {};
        marker.defaultStyle = data.defaultStyle || {};
        marker.coordinates = data.coordinates || { latitude: 0, longitude: 0 };
        marker.tour = data.tour || null;
        marker.outdoorActiveTrackingId = data.outdoorActiveTrackingId || null;
        marker.url = data.url || null;
        marker.detailApiEndpoints = data.detailApiEndpoints || {};

        return marker;
    }

}
