var requestsGridlayer
var wfd;
var legends = {};
var selectedEntityGroup = null;
var selectedEntityId = null;
var selectedMru = null;


async function get_layer_list() {
  let response = await fetch(BASE_URL + '/src/geoserver/get_layers.php');

  if (response.ok) { // if HTTP-status is 200-299
  // get the response body (the method explained below)
    let json = await response.json();
    return json
  } else {
    alert("HTTP-Error: " + response.status);
  }
}


async function fetchGeoJson(layerCode) {
  console.debug('fetching geojson...');
  const url = BASE_URL + "/interface/geojson/" + layerCode;
  try {
    const response = await fetch(url);
    const data = await response.json();
    console.debug('geojson data: ', data);
    return data;
  } catch (error) {
    console.error(error);
  }
}


function highlightFeature(e) {
  let overLayer = e.target;
  e.target.tempStyle = {
    weight: overLayer.options.weight,
    color: overLayer.options.color,
    dashArray: overLayer.options.dashArray,
    fillOpacity: overLayer.options.fillOpacity
  };
  console.debug("highlighted: ", e.target);
  try {
    overLayer.setStyle({
        weight: 5,
        color: '#666',
        dashArray: '',
        fillOpacity: 0.7
    });

  } catch (err) {
    console.log('could not change style');
  }
}


function resetHighlight(e) {
  try {
    e.target.setStyle(e.target.tempStyle);
    delete e.target.tempStyle;
  } catch {
    console.debug('eee');
  }
}


function onEachFeature(feature, layer) {
  layer.on({
      mouseover: highlightFeature,
      mouseout: resetHighlight,
      click: zoomToFeature
  });
}


function styleLine(feature, layer) {
  return {
    fillColor: getColor(), //feature.properties.name
    weight: 2,
    radius: 8,
    opacity: 1,
    color: '#000',
    dashArray: '3',
    fillOpacity: 0.8
  };
}

function stylePoint(feature, latlng) {
  console.debug(feature);
  return L.circleMarker(latlng, styleRules);
};


function getColor(d=null) {
  if (d != null)
    return intToRGB(hashCode(d));
  else
    return "#ff7800";
}


function intToRGB(i){
    var c = (i & 0x00FFFFFF)
        .toString(16)
        .toUpperCase();

    return "00000".substring(0, 6 - c.length) + c;
}


function hashCode(str) { // java String#hashCode
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
       hash = str.charCodeAt(i) + ((hash << 5) - hash);
    }
    return hash;
}

// zoom to feature (for data sources)
function zoomToFeature(e) {
  let featureId = e.target.feature.properties.id;
  console.debug('feature zoomed: ', e.target);

  try {
    selectedEntityGroup = e.target.feature.id.split('.')[0];
    selectedEntityId = e.target.feature.properties.id;
  } catch (error) {
    selectedEntityId = e.target.feature.properties.id;
  }
  lonlat = {lon: e.latlng.lng, lat: e.latlng.lat};
  console.debug('zoomed feature: ', e.target.feature);
  moreInfoPopup(e.target.feature.properties);

  try {
    mapL.fitBounds(e.target.getBounds());
  } catch (err) {
    console.log('cannot zoom ', err);
  }
}


function boundsToExtent(northEast, southWest, my_crs) {
  let my_proj = my_crs.projection;
  let rt = my_proj.project(northEast);
  let lb = my_proj.project(southWest);

  return {
    left: lb.x,
    bottom: lb.y,
    right: rt.x,
    top: rt.y
  }
}


function getBathymetry() {
  // load contours in JSON
  const url = "https://ows.emodnet-bathymetry.eu/wfs?service=WFS&version=1.1.0&request=GetFeature&typeName=emodnet:contours&outputFormat=application/json";
  const rainbow_url = "https://ows.emodnet-bathymetry.eu/wms";
  let remoteLayer;
  // add rainbow colored bathymetry map
  const rnb = L.tileLayer.wms(rainbow_url, { transparent: true, layers: 'emodnet:mean_rainbowcolour', format: 'image/png'});
  const cnt = L.tileLayer.wms(rainbow_url, { transparent: true, layers: 'emodnet:contours', format: 'image/png'});

  // legends['DPTH'] = L.control.Legend({
  //   position: "bottomright",
  //   title: 'Bathymetry',
  //   symbolWidth: 150,
  //   symbolHeight: 208,
  //   collapsed: false,
  //   legends: [{
  //     type: "image",
  //     label: ' ',
  //     url: "https://tiles.emodnet-bathymetry.eu/legends/legend_rainbow.png"
  //   }]
  // }).addTo(mapL);
  remoteLayer = L.layerGroup([rnb, cnt]);

  return remoteLayer;
}


async function getDepthOnPoint(latlng) {
  await fetch(`https://rest.emodnet-bathymetry.eu/depth_sample?geom=POINT(${latlng.lng}%20${latlng.lat})`, {
    "credentials": "omit",
    "headers": {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.5",
        "Upgrade-Insecure-Requests": "1",
        "Sec-Fetch-Dest": "document",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Site": "same-site",
        "Sec-GPC": "1"
    },
    "method": "GET",
    "mode": "cors"
  }).then(res => {
    return res.json();
  }).then(depthInfo => {
      const depth = depthInfo.avg.toString();
      L.popup()
        .setLatLng(latlng)
        .setContent(`<table class="table"><tr><th>Topography (m)</th></tr><tr><td>${depth}</td></tr></table>`)
        .openOn(mapL);
  });
}


function getHabitat(layerCode) {
  // load contours in JSON
  const url = "https://ows.emodnet-seabedhabitats.eu/geoserver/emodnet_view/wms";
  const lgndUrl = "https://ows.emodnet-seabedhabitats.eu/geoserver/emodnet_view/ows?service=WMS&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=eusm2021_bio_200&style=eusm2019_msfd_200"
  // add rainbow colored bathymetry map
    let habitats = new L.layerGroup();
    const lrs = ['eusm2021_msfd_800', 'eusm2021_msfd_400', 'eusm2021_msfd_200'];
    let l;
    lrs.forEach(layer => {
      l = L.tileLayer.betterWms(url, { transparent: true, layers: layer, format: 'image/png'});

      habitats.addLayer(l)
    });

    // legends[layerCode] = L.control.Legend({
    //   position: "bottomright",
    //   symbolWidth: 400,
    //   symbolHeight: 600,
    //   collapsed: false,
    //   title: 'Habitat Type',
    //   legends: [{
    //     type: "image",
    //     label: ' ',
    //     url: lgndUrl
    //   }]
    // }).addTo(mapL);
    //
    return habitats;
}


function moreInfoPopup(props) {
  let title;

  if (props.hasOwnProperty('code')) {
    title = `${props.code} &mdash; ${props.name}`;
  } else {
    title = `Grid &mdash; ${props.cellcode}`;
  }

  if (typeof props.tspr !== 'undefined') {
    title = `POSEIDON &mdash; ${props.pid}`;
    props.entity_group = 'POSEIDON';
  }

  if (typeof props.ctStationCode !== 'undefined') {
    title = `WFD &mdash; ${props.ctStationCode}`;
    props.category = 'coastal_wfd';
  }

  Alpine.store('entity', props);
  getPagePartial('more-info').then(content => {
    new L.control.window(mapL, {
      title: title,
      content: `${content}`,
      visible: true,
      position: 'left'
    });
  });
}


function mruPopup(props) {
  if (props.hasOwnProperty('nssg')) {
    L.popup()
      .setLatLng([props.y_coord, props.x_coord])
      .setContent(`<table class="table"><tr><th>NSSG Label</th></tr><tr><td>${props.nssg_label}</td></tr></table>`)
      .openOn(mapL);
    return;
  }
  let title;
  Alpine.store('mru', props);
  title = `MRU: ${props.mr_ms_aa}`;

  getPagePartial('mru-info').then(content => {
    content.props = props;
    new L.control.window(mapL, {
      title: title,
      content: `${content}`,
      visible: true,
      position: 'left'
    });
  });
}


// Fetches html from elements folder
async function getPagePartial(partialName, target=null) {
  // const url = BASE_URL + `/src/Views/${partialName}.php`;
  const url = BASE_URL + `/interface/partial/${partialName}`;
  const res = await fetch(url)
      .then((response) => {return response.text();})
      .then((content) => {
        return content
      })
      .catch((err) => {return err;});
  try {
    // fill target element with html
    document.querySelector(target).innerHTML = res;
  } catch(err) {
    return res;
  }
}


function getProduct(layer) {
  let url = layer.endpoint;
  let legendUrl = layer.legend;
  let l;

  l = L.tileLayer.betterWms(url, { transparent: true, layers: layer.code, format: 'image/png'});
  // legends[layer.code] = L.control.Legend({
  //     position: "bottomright",
  //     symbolWidth: 100,
  //     symbolHeight: 200,
  //     collapsed: false,
  //     title: 'Probability of habitat presence',
  //     legends: [{
  //       type: "image",
  //       label: ' ',
  //       url: legendUrl
  //     }]
  //   }).addTo(mapL);
    mapL.on('click', e => {
      let location = e.latlng;
    });

    return l;
}


function initializeLayerTree() {
    pTree = new PickleTree({
    c_target: 'layertree', //'maptab_treeview',
    c_config: {
      // options here
      switchMode: true,
      hasLink: true,
      drag: false,
      contextPos: 'before',
      foldedStatus: true
    },
      switchCallback: layerTreeSwitch,
      c_data: myData
  });
}


function getWFD(layer) {
  var wmsGroup = L.layerGroup();
  const layerCode = layer.code;
  const layerTitle = layer.name;
  const legendName = layerCode.split('_').slice(1,3).join('_');
  const lgndUrl = BASE_URL + "/img/legends/" + legendName + ".png";
  let l;

  l = L.tileLayer.wms(BASE_URL + '/geoserver/wms', { transparent: true, layers: layerCode + layer.minSuffix, format: 'image/png'});
  wmsGroup.addLayer(l);

  layerControls[layerCode] = L.control.slider(value => {
    wmsGroup.removeLayer(l);
    l = L.tileLayer.wms(BASE_URL + '/geoserver/wms', { transparent: true, layers: layerCode + value, format: 'image/png'});
    wmsGroup.addLayer(l);
  },{
    min: layer.minSuffix,
    max: layer.maxSuffix,
    step: 1,
    value: layer.minSuffix,
    logo: 'Year Selector ' + layerTitle,
  }).addTo(mapL);

  // legends[layerCode] = L.control.Legend({
  //   position: "bottomright",
  //   title: layerTitle,
  //   symbolWidth: 90,
  //   symbolHeight: 130,
  //   collapsed: false,
  //   legends: [{
  //     type: "image",
  //     label: '',
  //     url: lgndUrl
  //   }]
  // }).addTo(mapL);
  //
  return wmsGroup;
}


async function searchForRequests() {
  let response = await fetch(BASE_URL + '/actions/requests');

  if (response.ok) { // if HTTP-status is 200-299
  // get the response body (the method explained below)
    let json = await response.json();
    return json;
  } else {
    alert("HTTP-Error: " + response.status);
  }
}


function flattenJson(data, depth = 1) {
  var result = {};
  function recurse(cur, prop) {
    if (Object(cur) !== cur || depth === 0) {
      result[prop] = cur;
    } else if (Array.isArray(cur)) {
         for(var i=0, l=cur.length; i<l; i++)
            recurse(cur[i], prop + "[" + i + "]");
        if (l == 0)
            result[prop] = [];
    } else {
      var isEmpty = true;
      for (var p in cur) {
        isEmpty = false;
        recurse(cur[p], prop ? prop + "." + p : p, depth - 1);
      }
      if (isEmpty && prop)
        result[prop] = {};
    }
  }
  recurse(data, "", depth);
  return result;
}


async function downloadShapefile(layerName, srs) {
  let response = await fetch(BASE_URL + '/geoserver/shapefile/' + layerName + '/' + srs, {
    "credentials": "include",
    "headers": {
        "Accept": "application/zip",
        "Accept-Language": "en-US,en;q=0.5",
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "Pragma": "no-cache",
        "Cache-Control": "no-cache"
    },
    "method": "GET",
    "mode": "cors"
  });

  if (response.ok) { // if HTTP-status is 200-299
  // get the response body (the method explained below)
    let zip = await response.blob();
    var a = document.createElement("a");
    let data = await zip;
    a.href = window.URL.createObjectURL(data);
    a.download = layerName + "_shapefiles";
    a.click();

  } else {
    alert("HTTP-Error: " + response.status);
  }
}


async function getFisheriesProduct(layerCode) {
  // Create timeline slider control
  const group = L.layerGroup();
  // load contours in JSON
  const bgLayer = L.tileLayer.betterWms(BASE_URL + '/geoserver/wms', { layers: 'nssg_areas', transparent: true, format: "image/png"});

  try {
    const data = await fetchGeoJson(layerCode);
    console.debug("fisheries json: ", data);
    let pies;
    // Add the custom control to the map
    pies = createPie(data, 1990).addTo(group);

    layerControls[layerCode] = L.control.slider(value => {
      pies.remove();
      pies = createPie(data, value);
      group.addLayer(pies);
    },{
      min: 1990,
      max: 2019,
      step: 1,
      value: 1990,
      logo: 'Year Selector',
    }).addTo(mapL);

  } catch (error) {
    console.error(error);
  }

  bgLayer.addTo(group);
  return group;
}


function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}