import { MapContainer, GeoJSON, TileLayer } from "react-leaflet";
import Parser from "./parser/parser";
import { createRef, useEffect, useState } from "react";
import hash from "object-hash";
import Leaflet from "leaflet";
import L from "leaflet";

const parser = await Parser.instance();

const terminals = [10394, 10395, 10475, 10480, 10482, 10485, 10653];

function App() {
  const [selectedTerminal, setSelectedTerminal] = useState(terminals[0]);
  const [procedure, setProcedure] = useState<string>();

  const mapRef = createRef<Leaflet.Map>();
  const layerRef = createRef<Leaflet.GeoJSON>();

  useEffect(() => {
    (async () => {
      setProcedure(await parser.parse(selectedTerminal));
    })();
  }, [selectedTerminal]);

  useEffect(() => {
    if (layerRef.current && mapRef.current) {
      mapRef.current.flyToBounds(layerRef.current.getBounds(), {
        animate: false,
        padding: [50, 50],
      });
    }
  });

  return (
    <div style={{ display: "flex", height: "100vh", width: "100vw" }}>
      <MapContainer
        center={[51.505, -0.09]}
        zoom={13}
        zoomSnap={0}
        zoomDelta={0.1}
        wheelPxPerZoomLevel={1000}
        style={{ height: "100%", width: "100%" }}
        ref={mapRef}
      >
        <TileLayer
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <GeoJSON
          key={hash(procedure ?? "") + "lines"}
          data={procedure}
          style={{
            color: "#00ffff",
            stroke: true,
            weight: 5,
            opacity: 1,
          }}
          filter={(feature) => feature.geometry.type !== "Point"}
          ref={layerRef}
        />
        <GeoJSON
          key={hash(procedure ?? "") + "points"}
          data={procedure}
          style={(feature) => ({
            color: feature.properties["marker-color"],
            stroke: false,
            fill: true,
            fillOpacity: 1,
          })}
          pointToLayer={(_, latlng) => {
            return L.circleMarker(latlng, { radius: 5 });
          }}
          onEachFeature={({ geometry, properties }, layer) => {
            if (geometry.type === "Point") {
              layer.bindPopup(
                `${properties.name}<br>
                ${properties.altitude} ft<br>
                ${properties.speed} kts<br>
                CNSTR: 
                ${properties.altitudeConstraint ?? ""}
                ${properties.speedConstraint ?? ""}<br>`
              );
            }
          }}
          filter={(feature) => feature.geometry.type === "Point"}
        />
      </MapContainer>
      <div
        style={{
          padding: "5px",
          display: "flex",
          flexDirection: "column",
          gap: "10px",
        }}
      >
        {terminals.map((terminal) => (
          <div
            key={terminal}
            style={{
              display: "flex",
              gap: "10px",
              background: selectedTerminal === terminal ? "#eeeeee" : undefined,
            }}
          >
            <pre>ID {terminal}</pre>
            <button onClick={() => setSelectedTerminal(terminal)}>
              Select
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;
