<script lang="ts">
  /**
   * Used to quickly calculate a distance by dragging a map (and selecting start- and endpoints)
   */

  import LocationInput from "./LocationInput.svelte"
  import { UIEventSource, Store } from "../../../Logic/UIEventSource"
  import type { MapProperties } from "../../../Models/MapProperties"
  import ThemeViewState from "../../../Models/ThemeViewState"
  import type { Feature } from "geojson"
  import type { RasterLayerPolygon } from "../../../Models/RasterLayers"
  import { RasterLayerUtils } from "../../../Models/RasterLayers"
  import { eliCategory } from "../../../Models/RasterLayerProperties"
  import { GeoOperations } from "../../../Logic/GeoOperations"
  import OpenBackgroundSelectorButton from "../../BigComponents/OpenBackgroundSelectorButton.svelte"
  import { Map as MlMap } from "maplibre-gl"
  import StaticFeatureSource from "../../../Logic/FeatureSource/Sources/StaticFeatureSource"
  import ShowDataLayer from "../../Map/ShowDataLayer"
  import * as conflation from "../../../../assets/layers/conflation/conflation.json"
  import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
  import Translations from "../../i18n/Translations"
  import Tr from "../../Base/Tr.svelte"

  export let value: UIEventSource<number>
  export let feature: Feature
  export let args: { background?: string; zoom?: number }
  export let state: ThemeViewState = undefined
  export let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)

  let center = GeoOperations.centerpointCoordinates(feature)
  export let initialCoordinate: { lon: number; lat: number } = { lon: center[0], lat: center[1] }
  let mapLocation: UIEventSource<{ lon: number; lat: number }> = new UIEventSource(
    initialCoordinate
  )
  let bg = args?.background
  let rasterLayer = state?.mapProperties.rasterLayer
  if (bg !== undefined) {
    if (eliCategory.indexOf(bg) >= 0) {
      const availableLayers = state.availableLayers.store.data
      const startLayer: RasterLayerPolygon = RasterLayerUtils.SelectBestLayerAccordingTo(
        availableLayers,
        bg
      )
      rasterLayer = new UIEventSource(startLayer)
      state?.mapProperties.rasterLayer.addCallbackD((layer) => rasterLayer.set(layer))
    }
  }
  let mapProperties: Partial<MapProperties> = {
    rasterLayer: rasterLayer,
    location: mapLocation,
    zoom: new UIEventSource(args?.zoom ?? 18),
  }

  let start: UIEventSource<{ lon: number; lat: number }> = new UIEventSource(undefined)

  function selectStart() {
    start.set(mapLocation.data)
  }

  let lengthFeature: Store<Feature[]> = start.map(
    (start) => {
      if (!start) {
        return []
      }
      // A bit of a double task: calculate the actual value _and_ the map rendering
      const end = mapLocation.data
      const distance = GeoOperations.distanceBetween([start.lon, start.lat], [end.lon, end.lat])
      value.set(distance.toFixed(2))

      return <Feature[]>[
        {
          type: "Feature",
          properties: {
            id: "distance_line_" + distance,
            distance: "" + distance,
          },
          geometry: {
            type: "LineString",
            coordinates: [
              [start.lon, start.lat],
              [end.lon, end.lat],
            ],
          },
        },
      ]
    },
    [mapLocation]
  )

  new ShowDataLayer(map, {
    layer: new LayerConfig(conflation),
    features: new StaticFeatureSource(lengthFeature),
  })
</script>

<div class="relative h-64 w-full">
  <LocationInput value={mapLocation} {mapProperties} {map} />
  <div class="absolute bottom-0 left-0 p-4">
    <OpenBackgroundSelectorButton {state} {map} />
  </div>
</div>

<button class="primary" on:click={() => selectStart()}>
  <Tr t={Translations.t.input_helpers.distance.setFirst} />
</button>
