'use strict';

import UI from "./ui.js";

// Global leaflet
/**
 * @namespace GIS
 */
const GIS = {};

GIS.CENTER_COORDS = [40.5492, 14.2317];
GIS.INIT_ZOOM = 14.5;
const optionsVincoli = {
    color: '#222',
    opacity: 0.8,
    weight: 1,
    fillColor: '#987db7',
    fillOpacity: 0.8
};
const optionsSiti = {
    color: '#800040',
    opacity: 1,
    weight: 2.5,
    fillColor: '#800040',
    fillOpacity: 0.8
};
const optionsPaesistici = {
    color: '#222',
    opacity: 1,
    weight: 1.5,
    fillColor: '#ff8000',
    fillOpacity: 0.8
};

const BASE_URL = location.href;
/**
 * Capitalize a text string
 * @todo Move to utils
 * @param {?string} text 
 * @returns {?string} The capitalized string or null
 */
function capitalize(text) {
    let capital = text;
    if (text) {
        let words = text.split(' ');
        capital = '';

        for (let w of words) {
            w = w[0].toUpperCase() + w.slice(1);
            capital += w + ' ';
        }
        capital.trimEnd();
    }

    return capital;
}
/**
 * @param {string} mapId
 * @param {number} zoomLevel
 * @returns {{map: Map, sites: Layer}}
 */
GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
    L.LayerGroup.include({
        customGetLayer : function (id) {
            for (let l in this._layers) {
                if (this._layers[l].id === id) {
                    return this._layers[l];
                }
            }
        }
    });
    
    let map = L.map(mapId, {
        attributionControl: false,
        minZoom: 11,
    }).setView(this.CENTER_COORDS, zoomLevel);

    map.crs = L.CRS.EPSG4326;

    const {baseMap, archeo, sitesGroup} = await this.initLayers(map);

    L.control.layers(
            baseMap,
            archeo,
            {collapsed: false}
        )
        .addTo(map);

    // TODO Horrible?
    return {map: map, sites: sitesGroup};
}
GIS.initLayers = async function(map) {
    let layerMater = await this.loadLayer('matermania.geojson', optionsSiti, false);
    let layerArsenale = await this.loadLayer('arsenale_planim.geojson', optionsSiti, false);
    let layerGradola = await this.loadLayer('gradola.geojson', optionsSiti, false);

    layerMater.id = 'matermania';
    layerGradola.id = 'gradola';
    layerArsenale.id = 'arsenale_planim';
    let layerVincoli = await this.loadLayer('vincoli.geojson', optionsVincoli);
    // TODO named parameters??
    let layerPaesistici = await this.loadLayer('paesistici.geojson', optionsPaesistici);
    let osmap = new L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxNativeZoom : 22,
        maxZoom: 22,
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    });

    const sitesGroup = new L.LayerGroup([layerMater, layerGradola, layerArsenale]);
    const baseGroup = new L.LayerGroup([osmap, layerVincoli, layerPaesistici]);
    baseGroup.addTo(map);
    sitesGroup.addTo(map);
    const baseMap = {
        "Mappa di base (OpenStreetMap)" : osmap
    };
    const archeo = {
        "Villa di Gradola" : layerGradola,
        "Grotta di Matermania" : layerMater,
        "Grotta dell'Arsenale" : layerArsenale,
        "Vincoli archeologici" : layerVincoli,
        "Vincoli paesistici" : layerPaesistici,
    };

    return {baseMap, archeo, sitesGroup};
}
/**
 * @todo Distinguere tipo di geojson per contenuto popup 
 * @param {string} geoJSON 
 * @param {{color, opacity, weight, fillColor, fillOpacity}} options Style options for features
 * @param {boolean} popup Should the features have a popup? 
 */
GIS.loadLayer = async function (geoJSON, options, popup = true) {
    const data = await fetch(`${BASE_URL}/geojson/${geoJSON}`)
        .then(res => res.json())
        .catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));

    // Show data from feature in popUp?
    const layer = new L.geoJson(data, {
        style: function (feature) {
            let style = options;
            return style;
        },
        onEachFeature: function (feature, layer) {
            if (popup) {
                layer.bindPopup(GIS.featurePopup(geoJSON, feature));
            }
            else {
                layer.on("click", async () => {
                    const data = await GIS._fetchData(geoJSON.replace('.geojson', ''));
                    UI.openModal(data);
                });
            }
        }
    });

    return layer;
}
/**
 * Generate proper content for features popup
 * @todo Hard-coded names!!
 * 
 * @param {string} layerName
 * @param {object} feature
 * @returns {string} The popup's content
 */
GIS.featurePopup = function (layerName, feature) {
    const html = `
        <table class="table m-2">
            <tr><td class="text-bold">Oggetto</td><td>${feature.properties.OGGETTO}</td></tr>
            <tr><td class="text-bold">Anno</td><td>${feature.properties.ANNO}</td></tr>
            <tr><td class="text-bold">Comune</td><td>${capitalize(feature.properties.COMUNE)}</td></tr>
            <tr><td class="text-bold">Località</td><td>${capitalize(feature.properties.LOCALITA)}</td></tr>
            <tr><td class="text-bold">Proprietà</td><td>${capitalize(feature.properties.PROPRIETA)}</td></tr>
        </table>
    `;
    const content = {
        'vincoli.geojson' : html,
        'paesistici.geojson' : html,
    };

    return content[layerName];
}
/**
 * Fetch data from DB using API
 * @todo Actually implement it...
 * @param {string} recordId
 */
GIS._fetchData = async function (recordId) {
    //const data = await fetch()
    return recordId;
}

export default GIS;