defmodule BerrypodWeb.Admin.Navigation do
  use BerrypodWeb, :live_view

  alias Berrypod.{Pages, Settings}
  alias BerrypodWeb.ThemeHook

  @impl true
  def mount(_params, _session, socket) do
    header_items = load_nav("header_nav", ThemeHook.default_header_nav())
    footer_items = load_nav("footer_nav", ThemeHook.default_footer_nav())
    custom_pages = Pages.list_custom_pages()

    {:ok,
     socket
     |> assign(:page_title, "Navigation")
     |> assign(:header_items, header_items)
     |> assign(:footer_items, footer_items)
     |> assign(:custom_pages, custom_pages)
     |> assign(:dirty, false)}
  end

  # ── Item manipulation ──────────────────────────────────────────

  @impl true
  def handle_event("update_item", params, socket) do
    section = params["section"]
    index = String.to_integer(params["index"])
    field = params["field"]
    value = params["value"]

    items = get_items(socket, section)
    item = Enum.at(items, index)

    if item do
      updated = Map.put(item, field, value)
      items = List.replace_at(items, index, updated)
      {:noreply, put_items(socket, section, items)}
    else
      {:noreply, socket}
    end
  end

  def handle_event("remove_item", %{"section" => section, "index" => index_str}, socket) do
    index = String.to_integer(index_str)
    items = get_items(socket, section) |> List.delete_at(index)
    {:noreply, put_items(socket, section, items)}
  end

  def handle_event(
        "move_item",
        %{"section" => section, "index" => index_str, "dir" => dir},
        socket
      ) do
    index = String.to_integer(index_str)
    items = get_items(socket, section)
    target = if dir == "up", do: index - 1, else: index + 1

    if target >= 0 and target < length(items) do
      item = Enum.at(items, index)
      items = items |> List.delete_at(index) |> List.insert_at(target, item)
      {:noreply, put_items(socket, section, items)}
    else
      {:noreply, socket}
    end
  end

  def handle_event("add_item", %{"section" => section}, socket) do
    items = get_items(socket, section) ++ [%{"label" => "", "href" => ""}]
    {:noreply, put_items(socket, section, items)}
  end

  def handle_event("add_page", %{"section" => section, "slug" => slug}, socket) do
    page = Enum.find(socket.assigns.custom_pages, &(&1.slug == slug))

    if page do
      item = %{"label" => page.title, "href" => "/#{page.slug}", "slug" => page.slug}
      items = get_items(socket, section) ++ [item]
      {:noreply, put_items(socket, section, items)}
    else
      {:noreply, socket}
    end
  end

  # ── Save / reset ───────────────────────────────────────────────

  def handle_event("save", _params, socket) do
    Settings.put_setting("header_nav", socket.assigns.header_items, "json")
    Settings.put_setting("footer_nav", socket.assigns.footer_items, "json")

    {:noreply,
     socket
     |> assign(:dirty, false)
     |> put_flash(:info, "Navigation saved")}
  end

  def handle_event("reset_defaults", _params, socket) do
    {:noreply,
     socket
     |> assign(:header_items, ThemeHook.default_header_nav())
     |> assign(:footer_items, ThemeHook.default_footer_nav())
     |> assign(:dirty, true)}
  end

  # ── Render ─────────────────────────────────────────────────────

  @impl true
  def render(assigns) do
    ~H"""
    <.header>
      Navigation
      <:subtitle>Configure the links in your shop header and footer.</:subtitle>
    </.header>

    <div class="admin-nav-layout">
      <p :if={@dirty} class="admin-badge admin-badge-warning">
        Unsaved changes
      </p>
      <.nav_section
        title="Header navigation"
        section="header"
        items={@header_items}
        custom_pages={@custom_pages}
      />

      <.nav_section
        title="Footer navigation"
        section="footer"
        items={@footer_items}
        custom_pages={@custom_pages}
      />

      <div class="admin-row admin-row-lg">
        <button
          phx-click="save"
          class="admin-btn admin-btn-primary"
          disabled={!@dirty}
        >
          Save
        </button>
        <button
          phx-click="reset_defaults"
          data-confirm="Reset navigation to defaults? Your changes will be lost."
          class="admin-btn admin-btn-ghost"
        >
          Reset to defaults
        </button>
      </div>
    </div>
    """
  end

  defp nav_section(assigns) do
    ~H"""
    <section>
      <h3 class="admin-nav-section-heading">
        {@title}
      </h3>

      <div class="admin-stack admin-stack-sm">
        <div :if={@items != []} class="nav-editor-labels" aria-hidden="true">
          <span>Label</span>
          <span>Path</span>
        </div>
        <div
          :for={{item, idx} <- Enum.with_index(@items)}
          class="nav-editor-item"
        >
          <div class="nav-editor-fields">
            <label class="sr-only" for={"nav-#{@section}-#{idx}-label"}>Label</label>
            <input
              type="text"
              id={"nav-#{@section}-#{idx}-label"}
              value={item["label"]}
              placeholder="Label"
              phx-blur="update_item"
              phx-value-section={@section}
              phx-value-index={idx}
              phx-value-field="label"
              class="admin-input nav-editor-input"
            />
            <label class="sr-only" for={"nav-#{@section}-#{idx}-href"}>Path</label>
            <input
              type="text"
              id={"nav-#{@section}-#{idx}-href"}
              value={item["href"]}
              placeholder="/path"
              phx-blur="update_item"
              phx-value-section={@section}
              phx-value-index={idx}
              phx-value-field="href"
              class="admin-input nav-editor-input"
            />
          </div>
          <div class="nav-editor-actions">
            <button
              phx-click="move_item"
              phx-value-section={@section}
              phx-value-index={idx}
              phx-value-dir="up"
              disabled={idx == 0}
              class="admin-btn admin-btn-xs admin-btn-ghost"
              aria-label="Move up"
            >
              <.icon name="hero-chevron-up" class="size-4" />
            </button>
            <button
              phx-click="move_item"
              phx-value-section={@section}
              phx-value-index={idx}
              phx-value-dir="down"
              disabled={idx == length(@items) - 1}
              class="admin-btn admin-btn-xs admin-btn-ghost"
              aria-label="Move down"
            >
              <.icon name="hero-chevron-down" class="size-4" />
            </button>
            <button
              phx-click="remove_item"
              phx-value-section={@section}
              phx-value-index={idx}
              class="admin-btn admin-btn-xs admin-btn-ghost"
              aria-label="Remove"
            >
              <.icon name="hero-x-mark" class="size-4" />
            </button>
          </div>
        </div>
      </div>

      <div
        :if={@items == []}
        class="admin-nav-empty"
      >
        No items yet.
      </div>

      <div class="admin-nav-actions">
        <button
          phx-click="add_item"
          phx-value-section={@section}
          class="admin-btn admin-btn-sm admin-btn-outline"
        >
          <.icon name="hero-plus" class="size-4" /> Add link
        </button>
        <div :if={@custom_pages != []} class="nav-editor-dropdown-wrap" id={"add-page-#{@section}"}>
          <button
            phx-click={Phoenix.LiveView.JS.toggle(to: "#page-menu-#{@section}")}
            class="admin-btn admin-btn-sm admin-btn-outline"
          >
            <.icon name="hero-document-plus" class="size-4" /> Add page
          </button>
          <div
            id={"page-menu-#{@section}"}
            class="nav-editor-dropdown"
            style="display: none;"
          >
            <button
              :for={page <- @custom_pages}
              phx-click="add_page"
              phx-value-section={@section}
              phx-value-slug={page.slug}
              class="nav-editor-dropdown-item"
            >
              {page.title}
              <span class="nav-editor-dropdown-slug">
                /{page.slug}
              </span>
            </button>
          </div>
        </div>
      </div>
    </section>
    """
  end

  # ── Helpers ────────────────────────────────────────────────────

  defp get_items(socket, "header"), do: socket.assigns.header_items
  defp get_items(socket, "footer"), do: socket.assigns.footer_items

  defp put_items(socket, "header", items),
    do: socket |> assign(:header_items, items) |> assign(:dirty, true)

  defp put_items(socket, "footer", items),
    do: socket |> assign(:footer_items, items) |> assign(:dirty, true)

  defp load_nav(key, default) do
    case Settings.get_setting(key) do
      items when is_list(items) -> items
      _ -> default
    end
  end
end
