<script lang="ts">
  import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
  import { GeocodingUtils } from "../../Logic/Search/GeocodingProvider"
  import { GeoOperations } from "../../Logic/GeoOperations"
  import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
  import { UIEventSource } from "../../Logic/UIEventSource"
  import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
  import Icon from "../Map/Icon.svelte"
  import TagRenderingAnswer from "../Popup/TagRendering/TagRenderingAnswer.svelte"
  import DefaultIcon from "../Map/DefaultIcon.svelte"
  import type { MapProperties } from "../../Models/MapProperties"
  import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig"
  import FeaturePropertiesStore from "../../Logic/FeatureSource/Actors/FeaturePropertiesStore"
  import SearchState from "../../Logic/State/SearchState"
  import ArrowUp from "@babeard/svelte-heroicons/mini/ArrowUp"
  import { createEventDispatcher } from "svelte"

  export let entry: GeocodeResult
  export let state: {
    mapProperties: MapProperties
    theme?: ThemeConfig
    featureProperties?: FeaturePropertiesStore
    searchState: Partial<SearchState>
  }

  let layer: LayerConfig
  let tags: UIEventSource<Record<string, string>>
  let descriptionTr: TagRenderingConfig = undefined
  if (entry.feature?.properties?.id) {
    layer = state.theme.getMatchingLayer(entry.feature.properties)
    tags = state.featureProperties?.getStore(entry.feature.properties.id)
    descriptionTr = layer?.tagRenderings?.find((tr) => tr.labels.indexOf("description") >= 0)
  }

  let distance = state.mapProperties.location.mapD((l) =>
    GeoOperations.distanceBetween([l.lon, l.lat], [entry.lon, entry.lat])
  )
  let bearing = state.mapProperties.location.mapD((l) =>
    GeoOperations.bearing([l.lon, l.lat], [entry.lon, entry.lat])
  )
  let mapRotation = state.mapProperties.rotation
  let inView = state.mapProperties.bounds.mapD((bounds) => bounds.contains([entry.lon, entry.lat]))

  let dispatch = createEventDispatcher<{ select: GeocodeResult }>()
  function select() {
    dispatch("select", entry)
  }
</script>

<button class="unstyled link-no-underline searchresult w-full" on:click={() => select()}>
  <div class="flex w-full items-center gap-y-2 p-2">
    {#if layer}
      <div class="h-6 w-6">
        <DefaultIcon {layer} properties={entry.feature.properties} />
      </div>
    {:else if entry.category}
      <Icon
        icon={GeocodingUtils.categoryToIcon[entry.category]}
        clss="w-6 h-6 shrink-0"
        color="#aaa"
      />
    {/if}
    <div class="flex w-full flex-col items-start pl-2">
      <div class="flex w-full flex-wrap justify-between gap-x-2">
        <b class="nowrap">
          {#if layer && $tags?.id}
            <TagRenderingAnswer
              config={layer.title}
              selectedElement={entry.feature}
              {state}
              {tags}
              {layer}
            />
          {:else}
            {entry.display_name ?? entry.osm_id}
          {/if}
        </b>
        {#if $distance > 50}
          <div class="flex items-center gap-x-1">
            {#if $bearing && !$inView}
              <ArrowUp
                class="h-4 w-4 shrink-0"
                style={`transform: rotate(${$bearing - $mapRotation}deg)`}
              />
            {/if}
            {#if $distance}
              {GeoOperations.distanceToHuman($distance)}
            {/if}
          </div>
        {/if}
      </div>
      <div class="flex flex-wrap gap-x-2">
        {#if descriptionTr && tags}
          <TagRenderingAnswer
            defaultSize="subtle"
            noIcons={true}
            config={descriptionTr}
            {tags}
            {state}
            selectedElement={entry.feature}
            {layer}
          />
        {/if}
        {#if descriptionTr && tags && entry.description}
          –
        {/if}
        {#if entry.description}
          <div class="subtle flex w-full justify-between">
            {entry.description}
          </div>
        {/if}
      </div>
    </div>
  </div>
</button>
