/* eslint-disable no-undef */

let retryConnection = false;

var markers = L.markerClusterGroup({
  chunkedLoading: true,
  removeOutsideVisibleBounds: true,
});

// Prepare everything we need for the map
let theMarker = L.Marker.extend({
  options: {
    id: "-1",
  },
});
// Icons
const defaultIcon = L.icon({
  iconUrl: "/img/marker-icon.png",
  shadowUrl: "",
  iconSize: [25, 41], // size of the icon
  shadowSize: [41, 41], // size of the shadow
  iconAnchor: [12, 41], // point of the icon which will correspond to marker's location
  popupAnchor: [1, -34], // point from which the popup should open relative to the iconAnchor
});

const signalIcon = L.icon({
  iconUrl: "/img/signal.png",
  shadowUrl: "",

  iconSize: [30, 30], // size of the icon
  shadowSize: [0, 0], // size of the shadow
  iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
  shadowAnchor: [0, 0], // the same for the shadow
  popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
});

const temperatureIcon = L.icon({
  iconUrl: "/img/temperature.png",
  shadowUrl: "",

  iconSize: [30, 30], // size of the icon
  shadowSize: [0, 0], // size of the shadow
  iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
  shadowAnchor: [0, 0], // the same for the shadow
  popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
});

const cctvIcon = L.icon({
  iconUrl: "/img/cctv.png",
  shadowUrl: "",

  iconSize: [30, 30], // size of the icon
  shadowSize: [0, 0], // size of the shadow
  iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
  shadowAnchor: [0, 0], // the same for the shadow
  popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
});

const wifiIcon = L.icon({
  iconUrl: "/img/wifi.png",
  shadowUrl: "",

  iconSize: [30, 30], // size of the icon
  shadowSize: [0, 0], // size of the shadow
  iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
  shadowAnchor: [0, 0], // the same for the shadow
  popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
});

function showPosition(position) {
  mymap.setView(
    new L.LatLng(position.coords.latitude, position.coords.longitude),
    10
  );
}
// Share a point
function sharePOI(id) {
  const url = "https://pointsight.project-name-here.de/#" + id;
  sidebar.prevContent = sidebar._contentContainer.innerHTML;
  navigator.clipboard.writeText(url);
  makeToastNotification(
    "Copy successful",
    "The link to this point has been copied to your clipboard"
  );
}

function prepareSidebar(point_id, panTo = false) {
  const rawData = httpGet(
    "/api/retrieve?uid=" +
      point_id +
      "&key=b03f8aaf-1f32-4d9e-914a-9a50f904833d"
  );
  if (rawData.length > 0 && !rawData.includes("502 Bad Gateway")) {
    retryConnection = false;
    try {
      toggleModal("popup-modal-no-conn", false);
      retryConnection = false;
    } catch (error) {
      error;
    }
    const moreData = JSON.parse(rawData)[0][0];
    // Inject toolbar
    let inspector =
      '<i class="fas fa-flag reportBtn" style="padding: 4px;" onclick="reportPOI(\'' +
      point_id +
      "')\"></i>";
    inspector +=
      '<i class="fas fa-share-alt reportBtn" style="padding: 4px;" onclick="sharePOI(\'' +
      point_id +
      "')\"></i>";
    console.warn(moreData);
    if (moreData.type == "webcam-iframe") {
      // Prepare the template
      inspector += httpGet("/templates/inspectorContentIframe.html");
      inspector = inspector.replaceAll("#TITLE", moreData.titel);
      inspector = inspector.replaceAll("#URL", moreData.url);
      inspector = inspector.replaceAll("#URL", moreData.url);
    } else if (moreData.type == "webcam-image") {
      // Prepare the template
      inspector += httpGet("/templates/inspectorContentImage.html");
      inspector = inspector.replaceAll("#TITLE", moreData.titel);
      inspector = inspector.replaceAll("#URL", moreData.url);
    } else if (moreData.type == "iframe") {
      // Prepare the template
      inspector += httpGet("/templates/inspectorContentIframe.html");
      inspector = inspector.replaceAll("#TITLE", moreData.titel);
      inspector = inspector.replaceAll("#URL", moreData.url);
      inspector = inspector.replaceAll("#URL", moreData.url);
    } else if (moreData.type == "request-info") {
      // Prepare the template
      inspector += httpGet("/templates/inspectorGeneral.html");
      inspector = inspector.replaceAll("#TITLE", moreData.object.titel);
      inspector = inspector.replaceAll("#description", httpGet(moreData.url));
    } else {
      inspector += httpGet("/templates/inspectorGeneral.html");
      inspector = inspector.replaceAll("#TITLE", moreData.titel);
      inspector = inspector.replaceAll("#description", moreData.description);
    }
    // document.getElementById("inspector").innerHTML = inspector;

    sidebar.setContent(inspector);
    sidebar.show();
    if (panTo) {
      mymap.panTo([moreData.location.x, moreData.location.y]);
    }
  } else {
    try {
      if (!retryConnection) {
        toggleModal("popup-modal-no-conn", true);
      }

      retryConnection = true;
    } catch (error) {
      error;
    }
  }
}

// Handles click actions for markers
function onClick(e) {
  prepareSidebar(this.options.object.uid);
}

const form = document.getElementById("reportForm");
form.addEventListener("submit", (event) => {
  // submit event detected
  event.preventDefault();
  console.log("Report done by users");
  // Change the UI
  document.getElementById("reportBtnText").style.display = "none";
  document.getElementById("loadingSpinner").style.display = "block";
  document.getElementById("submitBtn").disabled = true;
  // Get all values
  const formy = new FormData(form);
  const reason = formy.get("reason");
  const email = formy.get("email");
  const pointId = document.getElementById("pointId").innerHTML;
  const baseUrl =
    "/api/internal/report?key=b03f8aaf-1f32-4d9e-914a-9a50f904833d&";
  let reqUrl =
    baseUrl + "reason=" + reason + "&mail=" + email + "&point_id=" + pointId;
  const response = httpGet(reqUrl);
  const reponseParsed = JSON.parse(response);
  if (reponseParsed.status == "success") {
    setTimeout(() => {
      document.getElementById("loadingDone").style.display = "block";
      document.getElementById("loadingSpinner").style.display = "none";
    }, 1000);
    setTimeout(() => {
      document.getElementById("reportBtnText").style.display = "block";
      document.getElementById("loadingSpinner").style.display = "none";
      document.getElementById("submitBtn").disabled = false;
      document.getElementById("loadingDone").style.display = "none";
      toggleModal("report-modal", false);
      form.reset();
      makeToastNotification("Report successful", "Thank you for your report.");
    }, 2000);
  } else {
    if (reponseParsed.message == "Invalid mail") {
      setTimeout(() => {
        document.getElementById("reportBtnText").style.display = "block";
        document.getElementById("loadingSpinner").style.display = "none";
        document.getElementById("loadingDone").style.display = "none";
        document.getElementById("submitBtn").disabled = false;
        toggleModal("report-modal", false);
        form.reset();

        document.getElementById("Geomodal-content").innerHTML =
          "It seemed like you provided an invalid mail address. Please try again.";
        toggleModal("popup-modal", true);
      }, 1000);
    } else {
      setTimeout(() => {
        document.getElementById("reportBtnText").style.display = "block";
        document.getElementById("loadingSpinner").style.display = "none";
        document.getElementById("loadingDone").style.display = "none";
        document.getElementById("submitBtn").disabled = false;
        toggleModal("report-modal", false);
        form.reset();

        document.getElementById("Geomodal-content").innerHTML =
          "Something went wrong, please try again later";
        toggleModal("popup-modal", true);
      }, 1000);
    }
  }
});

function reportPOI(poi_id) {
  document.getElementById("pointId").innerHTML = poi_id;
  toggleModal("report-modal", true);
  /*const url = "/api/internal/report&key=b03f8aaf-1f32-4d9e-914a-9a50f904833d&"
  console.log(poi_id)*/
}
function httpGet(theUrl) {
  var xmlHttp = new XMLHttpRequest();
  xmlHttp.open("GET", theUrl, false); // false for synchronous request
  xmlHttp.send(null);
  return xmlHttp.responseText;
}

function httpGetTriggerForMapData(theUrl) {
  var xmlHttp = new XMLHttpRequest();
  xmlHttp.open("GET", theUrl, true); // Doing it asynchronous
  xmlHttp.send(null);
  xmlHttp.onerror = function (e) {
    console.log(e);
  };
  xmlHttp.onloadend = function (e) {
    setTimeout(function () {
      if (
        xmlHttp.responseText.length > 0 &&
        !xmlHttp.responseText.includes("502 Bad Gateway")
      ) {
        retryConnection = false;
        try {
          toggleModal("popup-modal-no-conn", false);
          retryConnection = false;
        } catch (error) {
          error;
        }
        response = xmlHttp.responseText;
        allMarks = 0;
        response = JSON.parse(response);
        allMarks = response;

        markerList = [];
        for (h in response) {
          item = response[h];
          let mIcon = defaultIcon;
          if (item.icon == "signalIcon") {
            mIcon = signalIcon;
          } else if (item.icon == "cctvIcon") {
            mIcon = cctvIcon;
          } else if (item.icon == "wifiIcon") {
            mIcon = wifiIcon;
          } else if (item.icon == "temperatureIcon") {
            mIcon = temperatureIcon;
          }

          var marker = new theMarker([item.location.x, item.location.y], {
            icon: mIcon,
            object: item,
          }).on("click", onClick);
          markerList.push(marker);
        }
        // response.forEach(addPin);
        markers.clearLayers();
        markers.addLayers(markerList);
        mymap.addLayer(markers);
        syncBtn.state("default"); // Make sure the button is back to default
      } else {
        try {
          if (!retryConnection) {
            toggleModal("popup-modal-no-conn", true);
          }

          retryConnection = true;
        } catch (error) {
          error;
        }
      }
    }, 50);
  };
}

// Try to find where to user is
function home() {
  if (navigator.geolocation) {
    setTimeout(function () {
      navigator.geolocation.getCurrentPosition(showPosition);
    }, 200);
  } else {
    console.warn("Geolocation of user could not be fetched");
  }
}

home();

let allMarks = [];
var layerGroup = L.layerGroup().addTo(mymap);
var scale = L.control.scale().addTo(mymap);
var locator = L.control
  .locate({
    onLocationError: function (err) {
      console.log(err);
      let tip = err.message;
      if (err.message.indexOf("User denied Geolocation") > -1) {
        tip =
          "You have denied the location request. Please allow it in your browser settings.";
      }
      document.getElementById("Geomodal-content").innerHTML = tip;
      toggleModal("popup-modal", true);
    },
  })
  .addTo(mymap);

/*mymap.addControl(
  new L.Control.Fullscreen({
    title: {
      false: "View Fullscreen",
      true: "Exit Fullscreen",
    },
  })
);*/

var sidebar = L.control.sidebar("sidebar", {
  closeButton: true,
  position: "right",
});
mymap.addControl(sidebar);

var sidebar2 = L.control.sidebar("sidebar-left", {
  // Filter one
  closeButton: true,
  position: "left",
});
mymap.addControl(sidebar2);
// sidebar2.setContent(httpGet("/templates/filterPage.html"));

L.easyButton("fa-filter", function (btn, map) {
  if (sidebar2.isVisible()) {
    sidebar2.hide();
  } else {
    sidebar2.show();
  }
}).addTo(mymap);

syncBtn = L.easyButton({
  states: [
    {
      stateName: "default", // name the state
      icon: "fa-sync", // and define its properties
      title: "Reload POIs", // like its title
      onClick: function (btn, map) {
        // and its callback
        updatePois(); // Update all da fancy POIs
        btn.state("loading"); // change state on click!
      },
    },
    {
      stateName: "loading",
      icon: "fa-sync fa-spin",
      title: "Reloading...",
    },
  ],
});
syncBtn.addTo(mymap);

searchBtn = L.easyButton({
  states: [
    {
      stateName: "default", // name the state
      icon: "fa-search", // and define its properties
      title: "Search", // like its title
      onClick: function (btn, map) {
        // and its callback
        sear.toggle();
        btn.state("search"); // change state on click!
      },
    },
    {
      stateName: "search",
      icon: "fa-search fa-spin",
      title: "Hide search",
      onClick: function (btn, map) {
        // and its callback
        sear.toggle();
        btn.state("default"); // change state on click!
      },
    },
  ],
});
searchBtn.addTo(mymap);

// Start getting the pois
setTimeout(updatePois, 500);
var additionalFilters = "";
function updatePois() {
  // Create a filter string
  const enabledFilters = [];
  try {
    for (fi in tagsAvail) {
      const tag = tagsAvail[fi];
      if (document.getElementById("tag_" + tag).checked ) {
        enabledFilters.push(tag);
      }
    }
    additionalFilters =
      '{"conjunction": "OR", "filters": [["tag","' + enabledFilters.join('"],["tag","') + '"]]}';
  } catch (error) {
    console.log("Filter sidebar seems not ready yet");
  }

  console.log(additionalFilters);
  const bounds = mymap.getBounds();
  httpGetTriggerForMapData(
    "/api/getPOI?boundingEast=" +
      bounds.getNorthEast().lat +
      ";" +
      bounds.getNorthEast().lng +
      "&boundingWest=" +
      bounds.getSouthWest().lat +
      ";" +
      bounds.getSouthWest().lng +
      "&key=b03f8aaf-1f32-4d9e-914a-9a50f904833d&filter=" +
      additionalFilters
  );
}

let prevZoom = mymap.getZoom();
let prevCenter = mymap.getCenter();
let hasCenterChanged = false;
let maxZoomReached = mymap.getZoom();

setTimeout(function () {
  prevCenter = mymap.getCenter();
  prevZoom = mymap.getZoom();
}, 200);

function getDistanceBetweenCoordinates(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2 - lat1); // deg2rad below
  var dLon = deg2rad(lon2 - lon1);
  var a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(deg2rad(lat1)) *
      Math.cos(deg2rad(lat2)) *
      Math.sin(dLon / 2) *
      Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI / 180);
}

mymap.on("dragend", function () {
  console.info(
    getDistanceBetweenCoordinates(
      prevCenter.lat,
      prevCenter.lng,
      mymap.getCenter().lat,
      mymap.getCenter().lng
    )
  );
  if (
    getDistanceBetweenCoordinates(
      prevCenter.lat,
      prevCenter.lng,
      mymap.getCenter().lat,
      mymap.getCenter().lng
    ) >= 20
  ) {
    setTimeout(updatePois, 2);
    console.info("Updating POIs");
  }
  prevCenter = mymap.getCenter();
  maxZoomReached = mymap.getZoom();
  hasCenterChanged = true;
});

mymap.on("zoomend", function () {
  console.info(mymap.getZoom() - prevZoom);
  prevZoom = mymap.getZoom();

  if (mymap.getZoom() <= maxZoomReached) {
    maxZoomReached = mymap.getZoom();
    console.info("Updating POIs");
    setTimeout(updatePois, 2);
  } else {
    if (hasCenterChanged == false) {
      veryLongIntegerVariableWhichNoOneWillEverUseHopefully = 42;
    } else {
      console.info("Updating POIs");
      setTimeout(updatePois, 2);
    }
  }
  hasCenterChanged = false;
});

function applyFilter() {
  const val = document.getElementById("filter").value;
  console.log(val);
  additionalFilters =
    '{"filters": [["tag", "' + val + '"]], "conjunction": "OR"}'; // {"filters": [["tag", "webcam"]], "conjunction": "OR"}
  updatePois();
}

setTimeout(function () {
  let lat = -1;
  let lng = -1;
  let zoom = 5;
  let shouldThings = 0;
  let point_id = "";
  if (window.location.href.indexOf("#") > -1) {
    point_id = window.location.href.split("#")[1];
    prepareSidebar(point_id, true);
    setTimeout(updatePois, 500);
  } else {
    window.location.search
      .substr(1)
      .split("&")
      .forEach(function (item) {
        const param = item.split("=");
        if (param[0] === "lat" && _.isFinite(param[1])) {
          lat = param[1];
          shouldThings++;
        } else if (param[0] === "lng" && _.isFinite(param[1])) {
          lng = param[1];
          shouldThings++;
        } else if (param[0] === "zoom" && _.isFinite(param[1])) {
          zoom = param[1];
          shouldThings++;
        }
        if (shouldThings >= 2) {
          mymap.flyTo([lat, lng], zoom);
          console.log(lat, lng, zoom);
        }
      });
  }
}, 500);

setInterval(function () {
  if (retryConnection) {
    updatePois();
  }
}, 5000);

mymap.on("contextmenu.show", (e) => {
  mymap.contextmenu.removeItem(0);
  mymap.contextmenu.insertItem(
    {
      text:
        "<b class='background-color=\"red\"'>" +
        e.latlng.lat.toFixed(4) +
        ", " +
        e.latlng.lng.toFixed(4) +
        "</b>",
      callback: copyLocation,
    },
    0
  );
});
sear = L.control.search({ position: "topleft" });

mymap.addControl(sear);
