<svelte:options
  customElement={{
    props: {
      columns: { type: "Array" },
    },
    shadow: "none",
    tag: "field-adder",
  }}
/>

<!--
@component
An interactive UI that sits in the header row of a table and allows the user to
quickly add a new field based on an existing column or configure a field backed
by a new column to be added to the relation in the database.

Note: The form interface is implemented with a literal HTML <form> element with
method="post", meaning that the parent page is reloaded upon field creation. It
is not necessary to update the table DOM dynamically upon successful form
submission.
-->

<!--TODO: disable new column creation if the relation is a Postgres view.-->

<script lang="ts">
  import icon_ellipsis_vertical from "../assets/heroicons/20/solid/ellipsis-vertical.svg?raw";
  import icon_plus from "../assets/heroicons/20/solid/plus.svg?raw";
  import icon_x_mark from "../assets/heroicons/20/solid/x-mark.svg?raw";
  import Combobox from "./combobox.svelte";
  import FieldDetails from "./field-details.svelte";

  type Props = {
    /**
     * An array of all existing column names visible in the current relation,
     * to the current user. This is used to populate the autocomplete combobox.
     */
    columns?: string[];
  };

  let { columns = [] }: Props = $props();

  let expanded = $state(false);
  let name_value = $state("");
  let label_value = $state("");
  let name_customized = $state(false);
  let popover_element = $state<HTMLDivElement | undefined>();
  let search_input_element = $state<HTMLInputElement | undefined>();

  // If the database-friendly column name has not been explicitly set, keep it
  // synchronized with the human-friendly field label as typed in the table
  // header cell.
  $effect(() => {
    if (!name_customized) {
      name_value = label_value;
    }
  });

  function handle_summary_toggle_button_click() {
    expanded = !expanded;
    if (expanded) {
      setTimeout(() => {
        search_input_element?.focus();
      }, 0);
    }
  }

  function handle_field_options_button_click() {
    popover_element?.showPopover();
  }

  function handle_name_input() {
    name_customized = true;
  }
</script>

<form method="post" action="add-field">
  <div class="field-adder__container">
    <div
      class="field-adder__header-lookalike"
      style:display={expanded ? "block" : "none"}
    >
      <Combobox
        bind:search_value={label_value}
        bind:search_input_element
        bind:value={label_value}
        completions={columns.filter((col) =>
          col
            .toLocaleLowerCase("en-US")
            .includes(label_value.toLocaleLowerCase("en-US")),
        )}
        search_input_class="field-adder__label-input"
      />
    </div>

    <div class="field-adder__summary-buttons">
      <button
        aria-label="more field options"
        class="button--clear"
        onclick={handle_field_options_button_click}
        style:display={expanded ? "block" : "none"}
        type="button"
      >
        {@html icon_ellipsis_vertical}
      </button>
      <button
        aria-label="toggle field adder"
        class="button--clear"
        onclick={handle_summary_toggle_button_click}
        type="button"
      >
        {@html expanded ? icon_x_mark : icon_plus}
      </button>
    </div>
  </div>

  <div bind:this={popover_element} class="field-adder__popover" popover="auto">
    <!--
    The "advanced" details for creating a new column or customizing the behavior
    of a field backed by an existing column overlap with the controls exposed when
    editing the configuration of an existing field.
    -->
    <FieldDetails
      bind:name_value
      bind:label_value
      on_name_input={handle_name_input}
    />
    <button class="button--primary" type="submit">Create</button>
  </div>
</form>
