defmodule AppWeb.TypeaheadLiveComponent do
  use AppWeb, :live_component

  slot :item, required: true

  @impl true
  def mount(socket) do
    {:ok, assign(socket, :items, [])}
  end

  @impl true
  def update(%{items: items} = _assigns, socket) do
    {:ok, assign(socket, items: items)}
  end

  @impl true
  def update(assigns, socket) do
    {:ok,
     socket
     |> assign(assigns)
     |> assign_new(:form, fn ->
       to_form(%{})
     end)
     |> assign_new(:value, fn ->
       nil
     end)}
  end

  @impl true
  def handle_event("validate", %{"value" => value}, socket) do
    send(self(), {socket.assigns.on_search, value})

    {:noreply, assign(socket, :value, value)}
  end

  @impl true
  def handle_event("select", %{"id" => id}, socket) do
    send(self(), {socket.assigns.on_select, id})

    {:noreply, socket}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <div>
      <.header>
        {@title}

        <:subtitle>{@subtitle}</:subtitle>
      </.header>

      <.simple_form for={@form} phx-target={@myself} phx-change="validate" autocomplete="off">
        <div class="space-y-6">
          <.input field={@form[:value]} type="text" placeholder={@placeholder} phx-debounce={120} />

          <ul>
            <li
              :for={item <- @items}
              tabindex="0"
              class="border-b py-1 last:border-none dark:border-zinc-700 cursor-pointer focus:outline-none focus:ring focus:ring-blue-300 focus:border-blue-500"
              phx-click="select"
              phx-value-id={item.id}
              phx-target={@myself}
            >
              <div class="py-2 rounded hover:bg-zinc-100 dark:hover:bg-zinc-700">
                {render_slot(@item, item)}
              </div>
            </li>
          </ul>

          <div :if={@value && Enum.empty?(@items)}>
            {gettext("No results")}
          </div>
        </div>
      </.simple_form>
    </div>
    """
  end
end
