<!--
@component
UI for inspecting and altering field configuration when creating or editing a
field. This is typically rendered within a popover component, and within an HTML
<form> element defining the appropriate action for form submission.
-->

<script lang="ts">
  import {
    type Presentation,
    RFC_3339_S,
    all_presentation_tags,
    all_text_input_modes,
  } from "./presentation.svelte";

  const COLORS: string[] = [
    "Red",
    "Orange",
    "Yellow",
    "Green",
    "Blue",
    "Indigo",
    "Violet",
  ] as const;

  type Assert<_T extends true> = void;

  type Props = {
    label_value: string;
    name_input_disabled?: boolean;
    name_value: string;
    on_name_input?(
      ev: Event & { currentTarget: EventTarget & HTMLInputElement },
    ): void;
    on_presentation_input?(presentation: Presentation): void;
    presentation?: Presentation;
  };

  let {
    presentation = $bindable(get_empty_presentation("Text")),
    name_input_disabled = false,
    name_value = $bindable(),
    label_value = $bindable(),
    on_name_input,
    on_presentation_input,
  }: Props = $props();

  function handle_presentation_tag_change(
    ev: Event & { currentTarget: EventTarget & HTMLSelectElement },
  ) {
    const tag = ev.currentTarget
      .value as (typeof all_presentation_tags)[number];
    presentation = get_empty_presentation(tag);
    on_presentation_input?.(presentation);
  }

  function get_empty_presentation(
    tag: (typeof all_presentation_tags)[number],
  ): Presentation {
    if (tag === "Dropdown") {
      return { t: "Dropdown", c: { allow_custom: false, options: [] } };
    }
    if (tag === "Numeric") {
      return { t: "Numeric", c: {} };
    }
    if (tag === "Text") {
      return { t: "Text", c: { input_mode: { t: "SingleLine", c: {} } } };
    }
    if (tag === "Timestamp") {
      return { t: "Timestamp", c: { format: RFC_3339_S } };
    }
    if (tag === "Uuid") {
      return { t: "Uuid", c: {} };
    }
    type _ = Assert<typeof tag extends never ? true : false>;
    throw new Error("this should be unreachable");
  }

  function handle_text_input_mode_change(
    ev: Event & { currentTarget: EventTarget & HTMLSelectElement },
  ) {
    if (presentation.t === "Text") {
      const tag = ev.currentTarget
        .value as (typeof all_text_input_modes)[number];
      if (tag === "SingleLine") {
        presentation.c.input_mode = {
          t: "SingleLine",
          c: {},
        };
      } else if (tag === "MultiLine") {
        presentation.c.input_mode = {
          t: "MultiLine",
          c: {},
        };
      } else {
        type _ = Assert<typeof tag extends never ? true : false>;
        throw new Error("this should be unreachable");
      }
      on_presentation_input?.(presentation);
    }
  }
</script>

<h2>Field Details</h2>
<label class="form__section">
  <div class="form__label">SQL-friendly Name</div>
  <input
    bind:value={name_value}
    class="form__input"
    disabled={name_input_disabled}
    name="name"
    type="text"
  />
</label>
<label class="form__section">
  <div class="form__label">Human-friendly Label</div>
  <input
    bind:value={label_value}
    class="form__input"
    name="table_label"
    oninput={on_name_input}
    type="text"
  />
</label>
<label class="form__section">
  <div class="form__label">Present As</div>
  <select
    class="form__input"
    name="presentation_tag"
    onchange={handle_presentation_tag_change}
    value={presentation?.t}
  >
    {#each all_presentation_tags as presentation_tag}
      <option value={presentation_tag}>
        {presentation_tag}
      </option>
    {/each}
  </select>
</label>
{#if presentation?.t === "Dropdown"}
  <div class="form__section">
    <ul class="field-details__dropdown-options-list">
      {#each presentation.c.options as option, i}
        <li class="field-details__dropdown-option">
          <select
            class="field-details__dropdown-option-color"
            name="dropdown_option_colors"
            value={option.color}
          >
            {#each COLORS as color}
              <option value={color}>{color}</option>
            {/each}
          </select>
          <input
            type="text"
            name="dropdown_option_values"
            class="form__input--text"
            value={option.value}
          />
          <button
            aria-label="Remove option"
            class="button button--clear"
            onclick={() => {
              if (presentation?.t !== "Dropdown") {
                console.warn(
                  "remove dropdown option onclick() preconditions not met",
                );
                return;
              }
              presentation.c.options = presentation.c.options.filter(
                (_, j) => j !== i,
              );
            }}
            type="button"
          >
            <i class="ti ti-trash"></i>
          </button>
        </li>
      {/each}
    </ul>
    <button
      class="button button--secondary"
      onclick={() => {
        if (presentation?.t !== "Dropdown") {
          console.warn(
            "remove dropdown option onclick() preconditions not met",
          );
          return;
        }
        presentation.c.options = [
          ...presentation.c.options,
          { color: COLORS[0], value: "" },
        ];
      }}
      type="button"
    >
      Add option
    </button>
  </div>
{:else if presentation?.t === "Text"}
  <label class="form__section">
    <div class="form__label">Input Mode</div>
    <select
      class="form__input"
      name="text_input_mode"
      onchange={handle_text_input_mode_change}
      value={presentation.c.input_mode.t}
    >
      {#each all_text_input_modes as input_mode}
        <option value={input_mode}>
          {input_mode}
        </option>
      {/each}
    </select>
  </label>
{/if}
