defmodule Moon.Components.Table do
  @moduledoc false

  use Moon.StatelessComponent

  alias Moon.Components.Table.Paging
  alias Moon.Icon

  # import Moon.Helpers.MergeClass

  @doc "Params from LiveView mount(params, session, socket) that must be passed on"
  prop(limit, :integer, default: 10)
  prop(offset, :integer, default: 0)
  prop(selected, :string)
  prop(sort_key, :any)
  prop(sort_dir, :any, default: "ASC")

  @doc "The list of items to be rendered"
  prop(items, :generator, required: true)

  @doc "Data-testid attribute for a table tag"
  prop(testid, :string)

  @doc "Additional attributes for tbody tag"
  prop(body_attrs, :map, default: %{})

  prop(row_click, :event)
  prop(paging_click, :event)
  prop(sorting_click, :event)
  prop(paging_info, :any)

  prop(class, :css_class)
  prop(row_class, :css_class)
  prop(id, :string)
  prop(even_row_class, :css_class, default: "bg-goku")

  prop(has_no_cell_borders, :boolean, default: false)

  @doc "The list of columns defining the Grid"
  slot(cols, generator_prop: :items)

  def render(assigns) do
    ~F"""
    <div class="w-full grid gap-4" {=@id}>
      {#if @paging_info}
        <Paging paging_info={@paging_info} paging_click={@paging_click} limit={@limit} offset={@offset} />
      {/if}
      <div class={merge(["w-full overflow-x-scroll", @class])}>
        <table class="border-collapse text-sm min-w-full" data-testid={@testid}>
          <thead data-testid={"#{@testid}-head"}>
            <tr class="text-trunks">
              {#for col <- @cols}
                <th
                  class={merge([
                    "py-2 px-4 text-left font-normal",
                    ["cursor-pointer": col.name && col.sortable],
                    col.width
                  ])}
                  :on-click={(col.sortable && @sorting_click) || nil}
                  :values={"sort-key": col.name, "sort-dir": toggle_sort_dir(@sort_dir)}
                  data-testid={"sort-column-#{col.name}"}
                >
                  {col.label}
                  {#if col.sortable && "#{@sort_key}" == "#{col.name}"}
                    <Icon class="text-[1.5em]" name="arrows_up" :if={"#{@sort_dir}" == "ASC"} />
                    <Icon class="text-[1.5em]" name="arrows_down" :if={"#{@sort_dir}" == "DESC"} />
                  {/if}
                </th>
              {/for}
            </tr>
          </thead>
          <tbody {...@body_attrs}>
            {#for {item, row_index} <- Enum.with_index(@items)}
              <tr
                class={merge(
                  "#{@even_row_class}": @selected != "#{item.id}" && rem(row_index, 2) == 0,
                  "bg-gohan-120": @selected == "#{item.id}",
                  "#{@row_class}": true
                )}
                :on-click={@row_click}
                :values={selected: item.id}
                data-testid={"row-#{row_index}"}
              >
                {#for {col, col_index} <- Enum.with_index(@cols)}
                  <td
                    class={merge([
                      "p-4",
                      ["#{inter_cell_border()}": !@has_no_cell_borders && col_index < Enum.count(@cols) - 1],
                      col.width
                    ])}
                    data-testid={if is_function(col[:testid]),
                      do: col[:testid].(row_index, col),
                      else: "row-#{row_index}-col-#{col_index}"}
                  >
                    <#slot {col} generator_value={item} />
                  </td>
                {/for}
              </tr>
            {/for}
          </tbody>
        </table>
      </div>
    </div>
    """
  end

  defp toggle_sort_dir(sort_dir) do
    sort_dir = "#{sort_dir}"

    if sort_dir == "ASC" do
      "DESC"
    else
      "ASC"
    end
  end

  defp inter_cell_border() do
    "after:content-[\"\"] after:absolute after:w-px after:bg-beerus " <>
      "after:h-2/5 after:bottom-[30%] after:right-0 after:translate-x-[-50%] relative"
  end
end
