<script lang="ts">
  import { debounce } from "lodash";

  import type { IValue } from "upend/types";
  import Input from "./Input.svelte";

  export let attribute: string | undefined = undefined;
  export let value: IValue | undefined = undefined;
  export let type: "entity" | "attribute" | "value";

  interface SelectorOption {
    attribute?: string;
    value?: IValue;
  }

  let options: SelectorOption[] = [];
  const updateOptions = debounce(async (query: string) => {
    switch (type) {
      case "entity":
        throw new Error("unimplemented");
      case "attribute":
        const req = await fetch("/api/all/attributes");
        const allAttributes: string[] = await req.json();
        options = allAttributes
          .filter((attr) => attr.toLowerCase().includes(query.toLowerCase()))
          .map((attribute) => {
            return {
              attribute,
            };
          });
        break;
      case "value":
        break;
    }
  }, 200);
  $: updateOptions(inputValue);

  function set(option: SelectorOption) {
    if (type == "attribute") {
      attribute = option.attribute;
      inputValue = option.attribute;
    } else {
      value = option.value;
      inputValue = String(option.value.c); // todo;
    }
    visible = false;
  }

  let inputValue = "";
  if (type == "attribute") {
    inputValue = attribute || "";
  } else {
    inputValue = String(value?.c || "");
  }

  function onInput(ev: CustomEvent<string>) {
    if (type == "attribute") {
      attribute = ev.detail;
    } else {
      value = {
        t: "Value",
        c: ev.detail,
      };
    }
  }

  let inputFocused = false;
  let hover = false;
  $: visible = (inputFocused || hover) && Boolean(options.length);
</script>

<div class="selector">
  <Input
    value={inputValue}
    on:input={onInput}
    on:focusChange={(ev) => (inputFocused = ev.detail)}
  />
  <ul
    class="options"
    class:visible
    on:mouseenter={() => (hover = true)}
    on:mouseleave={() => (hover = false)}
  >
    {#each options as option}
      <li on:click={() => set(option)}>
        {#if option.attribute}
          {option.attribute}
        {:else if option.value}
          RESOLVING LOGIC
        {/if}
      </li>
    {/each}
  </ul>
</div>

<style lang="scss">
  .selector {
    position: relative;
  }

  .options {
    position: absolute;
    list-style: none;
    margin: 0;
    padding: 0;
    border: 1px solid var(--foreground-lighter);
    width: 100%;
    border-radius: 4px;
    margin-top: 2px;
    background: var(--background);
    font-size: smaller;

    visibility: hidden;
    opacity: 0;

    transition: opacity 0.2s;

    z-index: 99;

    &.visible {
      visibility: visible;
      opacity: 1;
    }

    li {
      cursor: pointer;
      padding: 0.5em;

      transition: background-color 0.2s;
      &:hover {
        background-color: var(--background-lighter);
      }
    }
  }
</style>
