defmodule MicrowavepropWeb.LiveTableFooter do
  @moduledoc false
  use Phoenix.Component

  def render(assigns) do
    options = assigns.options
    table_options = assigns.table_options
    paginate? = get_in(options, ["pagination", "paginate?"])
    mode = get_in(table_options, [:pagination, :mode])
    page = parse_page(get_in(options, ["pagination", "page"]))
    has_next? = get_in(options, ["pagination", :has_next_page]) || false

    assigns =
      assigns
      |> assign(:show_pagination?, paginate? && mode != :infinite_scroll)
      |> assign(:page, page)
      |> assign(:has_next_page?, has_next?)
      |> assign(:page_items, page_items(page, has_next?))

    ~H"""
    <nav
      :if={@show_pagination?}
      class="flex items-center justify-between px-4 py-3 sm:px-6"
      aria-label="Pagination"
    >
      <p class="hidden sm:block text-sm opacity-60">
        Page <span class="font-medium text-base-content">{@page}</span>
      </p>

      <div class="join">
        <button
          type="button"
          class="btn btn-sm join-item"
          phx-click="sort"
          phx-value-page={@page - 1}
          disabled={@page == 1}
          aria-label="Previous page"
        >
          «
        </button>
        <%= for item <- @page_items do %>
          <%= if item == :ellipsis do %>
            <button type="button" class="btn btn-sm join-item btn-disabled pointer-events-none">
              …
            </button>
          <% else %>
            <button
              type="button"
              class={[
                "btn btn-sm join-item",
                item == @page && "btn-active pointer-events-none"
              ]}
              phx-click="sort"
              phx-value-page={item}
              aria-label={"Page #{item}"}
              aria-current={item == @page && "page"}
            >
              {item}
            </button>
          <% end %>
        <% end %>
        <button
          type="button"
          class="btn btn-sm join-item"
          phx-click="sort"
          phx-value-page={@page + 1}
          disabled={!@has_next_page?}
          aria-label="Next page"
        >
          »
        </button>
      </div>
    </nav>
    """
  end

  # Without a total count from live_table we can only show pages we know exist:
  # everything up to and including `page` (we got here), plus `page + 1` when
  # `has_next?` is true. Collapses a gap to "…" once we're past page 4.
  @doc false
  @spec page_items(pos_integer(), boolean()) :: [pos_integer() | :ellipsis]
  def page_items(page, has_next?) when page >= 1 do
    window_start = max(1, page - 2)
    window_end = if has_next?, do: page + 1, else: page
    window = Enum.to_list(window_start..window_end)

    cond do
      window_start == 1 -> window
      window_start == 2 -> [1 | window]
      true -> [1, :ellipsis | window]
    end
  end

  defp parse_page(page) when is_integer(page), do: page
  defp parse_page(page) when is_binary(page), do: String.to_integer(page)
  defp parse_page(_), do: 1
end
