<!--
@component
Dropdown menu with grid of buttons for quickly selecting a Postgres expression
type. Used by `<ExpressionEditor />`.
-->

<script lang="ts">
  import { type PgExpressionAny, expression_icon } from "./expression.svelte";

  type Props = {
    on_change?(new_value: PgExpressionAny): void;
    value?: PgExpressionAny;
  };

  let { on_change, value = $bindable() }: Props = $props();

  let menu_button_element = $state<HTMLButtonElement | undefined>();
  let popover_element = $state<HTMLDivElement | undefined>();
  // Hacky workaround because as of September 2025 implicit anchor association
  // is still pretty broken, at least in Firefox.
  let anchor_name = $state(`--anchor-${Math.floor(Math.random() * 1000000)}`);

  const expressions: ReadonlyArray<{
    section_label: string;
    expressions: ReadonlyArray<PgExpressionAny>;
  }> = [
    {
      section_label: "Comparisons",
      expressions: [
        {
          t: "Comparison",
          c: {
            t: "Infix",
            c: {
              lhs: { t: "Identifier", c: { parts_raw: [] } },
              operator: "Eq",
              rhs: { t: "Literal", c: { t: "Text", c: "" } },
            },
          },
        },
        {
          t: "Comparison",
          c: {
            t: "Infix",
            c: {
              lhs: { t: "Identifier", c: { parts_raw: [] } },
              operator: "Neq",
              rhs: { t: "Literal", c: { t: "Text", c: "" } },
            },
          },
        },
        {
          t: "Comparison",
          c: {
            t: "Infix",
            c: {
              lhs: { t: "Identifier", c: { parts_raw: [] } },
              operator: "Lt",
              rhs: { t: "Literal", c: { t: "Text", c: "" } },
            },
          },
        },
        {
          t: "Comparison",
          c: {
            t: "Infix",
            c: {
              lhs: { t: "Identifier", c: { parts_raw: [] } },
              operator: "Gt",
              rhs: { t: "Literal", c: { t: "Text", c: "" } },
            },
          },
        },
        {
          t: "Comparison",
          c: {
            t: "IsNull",
            c: {
              lhs: { t: "Identifier", c: { parts_raw: [] } },
            },
          },
        },
        {
          t: "Comparison",
          c: {
            t: "IsNotNull",
            c: {
              lhs: { t: "Identifier", c: { parts_raw: [] } },
            },
          },
        },
      ],
    },
    {
      section_label: "Conjunctions",
      expressions: [
        {
          t: "Comparison",
          c: { t: "Infix", c: { operator: "And" } },
        },
        {
          t: "Comparison",
          c: { t: "Infix", c: { operator: "Or" } },
        },
      ],
    },
    {
      section_label: "Values",
      expressions: [
        {
          t: "Identifier",
          c: { parts_raw: [] },
        },
        {
          t: "Literal",
          c: { t: "Text", c: "" },
        },
      ],
    },
    {
      section_label: "Transformations",
      expressions: [
        {
          t: "ToJson",
          c: { entries: [] },
        },
      ],
    },
  ];

  let iconography_current = $derived(value && expression_icon(value));

  function handle_menu_button_click() {
    popover_element?.togglePopover();
  }

  function handle_expression_button_click(expr: PgExpressionAny) {
    value = expr;
    popover_element?.hidePopover();
    menu_button_element?.focus();
    on_change?.(value);
  }
</script>

<div class="expression-selector">
  <button
    aria-label={`Select expression type (current: ${iconography_current?.label ?? "None"})`}
    bind:this={menu_button_element}
    class="expression-selector__expression-button"
    onclick={handle_menu_button_click}
    style:anchor-name={anchor_name}
    title={iconography_current?.label}
    type="button"
  >
    {#if value}
      {@html iconography_current?.html}
    {:else}
      <i class="ti ti-circle-plus"></i>
    {/if}
  </button>
  <div
    bind:this={popover_element}
    class="popover expression-selector__popover"
    popover="auto"
    style:position-anchor={anchor_name}
  >
    {#each expressions as section}
      <ul class="expression-selector__section">
        {#each section.expressions as expr}
          {@const iconography = expression_icon(expr)}
          <li class="expression-selector__li">
            <button
              class="expression-selector__expression-button"
              onclick={() => handle_expression_button_click(expr)}
              title={iconography.label}
              type="button"
            >
              {@html iconography.html}
            </button>
          </li>
        {/each}
      </ul>
    {/each}
  </div>
</div>
