<script lang="ts">
  import { fetchEntry, query as queryFn } from "../lib/entity";
  import debounce from "lodash/debounce";
  import { Readable, readable } from "svelte/store";
  import type { UpEntry, UpListing, UpObject } from "upend";
  import Spinner from "../components/utils/Spinner.svelte";
  import UpEntryDisplay from "../components/display/UpEntry.svelte";
  import UpObjectDisplay from "../components/display/UpObject.svelte";
  import { useResolve } from "svelte-navigator";
  import UpObjectCard from "../components/display/UpObjectCard.svelte";
  export let query: string;

  let debouncedQuery = "";
  const updateQuery = debounce((query: string) => {
    debouncedQuery = query;
  }, 200);
  $: updateQuery(query);

  let result: Readable<UpListing> = readable();
  let error: Readable<unknown> = readable();
  $: if (debouncedQuery.length) {
    ({ result, error } = queryFn(
      () => `(matches ? ? (contains "${debouncedQuery}"))`
    ));
  }

  $: entries = ($result?.entries || []).sort((a, b) =>
    a.address.localeCompare(b.address)
  );

  async function getObjects(entries: UpEntry[]): Promise<string[]> {
    const labelled = entries
      .filter((e) => e.attribute == "LBL")
      .map((e) => e.entity);
    const aliased = entries
      .filter((e) => e.attribute === "ALIAS")
      .map(async (e) => {
        const entry = await fetchEntry(e.entity);
        return String(entry.value.c);
      });
    return labelled.concat(await Promise.all(aliased));
  }
  $: objects = getObjects($result?.entries || []);

  $: exact = [];
</script>

<div>
  {#if !$error}
    {#if $result}
      <section>
        <h2>Exact</h2>
        {#if exact.length}
          exakt
        {:else}
          Create?
        {/if}
      </section>
      {#await objects}
        <section>
          <h2>Objects</h2>
          <Spinner />
        </section>
      {:then objects}
        <section>
          <h2>Objects</h2>
          <ul>
            {#each objects as address}
              <li><UpObjectCard {address} /></li>
            {/each}
          </ul>
        </section>
      {/await}
      {#if entries.length}
        <section>
          <h2>Raw results</h2>
          <ul>
            {#each entries as entry}
              <li><UpEntryDisplay {entry} /></li>
            {/each}
          </ul>
        </section>
      {:else}
        <div class="global">No results found.</div>
      {/if}
    {:else}
      <div class="global">
        <Spinner />
      </div>
    {/if}
  {:else}
    <div class="error">
      {$error}
    </div>
  {/if}
</div>

<style lang="scss">
  h2 {
    text-align: center;
  }

  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  li {
    margin: 1em auto;
    max-width: 66em;
  }

  .global {
    font-size: 48px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
</style>
