import { AbstractMapWithMarkers } from '../abstract-map-with-markers';
import { initializeMap } from '../map-factory';

/**
 * A map renderer that starts out as a dynamic map and converts to a dynamic map on
 * click. The 2 map instances must be passed as constructor arguments.
 */
export class StaticDynamicMapSwitcher extends AbstractMapWithMarkers {

    /**
     * @var {boolean}
     * @private
     */
    static = true;

    /** @private */
    initializers = {
        static: null,
        dynamic: null,
    };

    /**
     * @var {AbstractStaticMap|null}
     * @private
     */
    staticMap = null;

    /**
     * @var {AbstractMapWithMarkers|null}
     * @private
     */
    dynamicMap = null;

    /**
     * @type {Marker[]}
     * @private
     */
    lastRenderedMarkers = [];

    /**
     * @private
     */
    lastDrawnTour = null;

    async initialize () {
        this.staticMap = await initializeMap(this.options.staticMapType, this.node, this.options, 'google-maps-static');

        if (this.lastRenderedMarkers.length > 0) {
            await this.staticMap.render(this.lastRenderedMarkers);
        }
        if (this.lastDrawnTour && this.staticMap.drawTourOntoMap) {
            await this.staticMap.drawTourOntoMap(this.lastDrawnTour);
        }

        this.staticMap.picture.addEventListener('click', async () => {
            const size = this.staticMap.picture.getBoundingClientRect();
            this.node.style.width = `${size.width}px`;
            this.node.style.height = `${size.height}px`;

            this.staticMap.picture.parentNode.removeChild(this.staticMap.picture);
            this.dynamicMap = await initializeMap(this.options.dynamicMapType, this.node, this.options);
            this.listeners.markerClick.forEach(cb => this.dynamicMap.onMarkerClick(cb));
            await this.dynamicMap.render(this.lastRenderedMarkers);
            if (this.lastDrawnTour && this.dynamicMap.drawTourOntoMap) {
                await this.dynamicMap.drawTourOntoMap(this.lastDrawnTour, true);
            } else {
                this.dynamicMap.centerMapOnMarkers(this.lastRenderedMarkers);
            }
        });
    }

    render (markers = []) {
        this.lastRenderedMarkers = markers;
        if (this.static && this.staticMap) {
            return this.staticMap.render(markers);
        }
        if (this.dynamicMap) {
            return this.dynamicMap.render(markers);
        }
    }
    centerMapOnMarkers(markers) {
        this.redirectMethodCallToCorrectMapInstance('centerMapOnMarkers', markers);
    }
    setCenter(longitude, latitude) {
        this.redirectMethodCallToCorrectMapInstance('setCenter', longitude, latitude);
        return super.setCenter(longitude, latitude);
    }
    setZoom(zoom) {
        this.redirectMethodCallToCorrectMapInstance('setZoom', zoom);
        return super.setZoom(zoom);
    }
    drawTourOntoMap(tour) {
        this.lastDrawnTour = tour;
        if (this.static && this.staticMap && this.staticMap.drawTourOntoMap) {
            this.staticMap.drawTourOntoMap(tour);
        }
        if (this.dynamicMap && this.dynamicMap.drawTourOntoMap) {
            this.dynamicMap.drawTourOntoMap(tour);
        }
    }

    onMarkerClick(callback) {
        super.onMarkerClick(callback);
        if (this.dynamicMap) {
            this.dynamicMap.onMarkerClick(callback);
        }
    }

    redirectMethodCallToCorrectMapInstance(methodName, ...args) {
        if (this.static) {
            return this.staticMap[methodName](...args);
        } else {
            return this.dynamicMap[methodName](...args);
        }
    }

}
