defmodule MvWeb.Layouts.Sidebar do
  @moduledoc """
  Sidebar navigation component used in the drawer layout
  """
  use MvWeb, :html

  alias MvWeb.PagePaths

  attr :current_user, :map, default: nil, doc: "The current user"
  attr :club_name, :string, required: true, doc: "The name of the club"
  attr :mobile, :boolean, default: false, doc: "Whether this is mobile view"

  def sidebar(assigns) do
    ~H"""
    <label
      for="mobile-drawer"
      aria-label={gettext("Close sidebar")}
      class="drawer-overlay lg:hidden focus:outline-none focus:ring-2 focus:ring-primary"
      tabindex="-1"
    >
    </label>
    <aside id="main-sidebar" class="sidebar" aria-label={gettext("Main navigation")}>
      {sidebar_header(assigns)}
      <%= if @current_user do %>
        {sidebar_menu(assigns)}
      <% end %>
      <%= if @current_user do %>
        <.sidebar_footer current_user={@current_user} />
      <% end %>
    </aside>
    """
  end

  defp sidebar_header(assigns) do
    ~H"""
    <div class="flex items-center gap-3 p-4 border-b border-base-300">
      <!-- Logo -->
      <img src={~p"/images/mila.svg"} alt="Mila Logo" class="size-8 shrink-0" />
      <!-- Club Name -->
      <span class="menu-label text-lg font-bold truncate">
        {@club_name}
      </span>
      <!-- Toggle Button (Desktop only) -->
      <%= unless @mobile do %>
        <button
          type="button"
          id="sidebar-toggle"
          class="hidden lg:flex ml-auto btn btn-ghost btn-sm btn-square"
          aria-label={gettext("Toggle sidebar")}
          aria-controls="main-sidebar"
          aria-expanded="true"
          onclick="toggleSidebar()"
        >
          <!-- Expanded Icon (Chevron Left) -->
          <.icon
            name="hero-chevron-left"
            class="size-5 sidebar-expanded-icon"
            aria-hidden="true"
          />
          <!-- Collapsed Icon (Chevron Right) -->
          <.icon
            name="hero-chevron-right"
            class="size-5 sidebar-collapsed-icon"
            aria-hidden="true"
          />
        </button>
      <% end %>
    </div>
    """
  end

  defp sidebar_menu(assigns) do
    ~H"""
    <ul class="menu flex-1 w-full p-2" role="menubar">
      <%= if can_access_page?(@current_user, PagePaths.members()) do %>
        <.menu_item
          href={~p"/members"}
          icon="hero-users"
          label={gettext("Members")}
        />
      <% end %>

      <%= if can_access_page?(@current_user, PagePaths.groups()) do %>
        <.menu_item
          href={~p"/groups"}
          icon="hero-user-group"
          label={gettext("Groups")}
        />
      <% end %>

      <%= if can_access_page?(@current_user, PagePaths.statistics()) do %>
        <.menu_item
          href={~p"/statistics"}
          icon="hero-chart-bar"
          label={gettext("Statistics")}
        />
      <% end %>

      <%= if admin_menu_visible?(@current_user) do %>
        <.menu_group
          icon="hero-cog-6-tooth"
          label={gettext("Administration")}
          testid="sidebar-administration"
        >
          <%= if can_access_page?(@current_user, PagePaths.settings()) do %>
            <.menu_subitem href={~p"/settings"} label={gettext("Basic settings")} />
          <% end %>
          <%= if can_access_page?(@current_user, PagePaths.admin_datafields()) do %>
            <.menu_subitem href={~p"/admin/datafields"} label={gettext("Datafields")} />
          <% end %>
          <%= if can_access_page?(@current_user, PagePaths.membership_fee_settings()) do %>
            <.menu_subitem
              href={~p"/membership_fee_settings"}
              label={gettext("Membership fee settings")}
            />
          <% end %>
          <%= if can_access_page?(@current_user, PagePaths.admin_import()) do %>
            <.menu_subitem href={~p"/admin/import"} label={gettext("Import")} />
          <% end %>
          <%= if can_access_page?(@current_user, PagePaths.users()) do %>
            <.menu_subitem href={~p"/users"} label={gettext("Users")} />
          <% end %>
          <%= if can_access_page?(@current_user, PagePaths.admin_roles()) do %>
            <.menu_subitem href={~p"/admin/roles"} label={gettext("Roles")} />
          <% end %>
        </.menu_group>
      <% end %>
    </ul>
    """
  end

  defp admin_menu_visible?(user) do
    Enum.any?(PagePaths.admin_menu_paths(), &can_access_page?(user, &1))
  end

  attr :href, :string, required: true, doc: "Navigation path"
  attr :icon, :string, required: true, doc: "Heroicon name"
  attr :label, :string, required: true, doc: "Menu item label"

  defp menu_item(assigns) do
    ~H"""
    <li role="none">
      <.link
        navigate={@href}
        class="flex items-center gap-3 tooltip tooltip-right focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
        data-tip={@label}
        role="menuitem"
      >
        <.icon name={@icon} class="size-5 shrink-0" aria-hidden="true" />
        <span class="menu-label">{@label}</span>
      </.link>
    </li>
    """
  end

  attr :icon, :string, required: true, doc: "Heroicon name for the menu group"
  attr :label, :string, required: true, doc: "Menu group label"
  attr :testid, :string, default: nil, doc: "data-testid for stable test selectors"
  slot :inner_block, required: true, doc: "Submenu items"

  defp menu_group(assigns) do
    ~H"""
    <!-- Expanded Mode: Always open div structure -->
    <li role="none" class="expanded-menu-group" data-testid={@testid}>
      <div
        class="flex items-center gap-3"
        role="group"
        aria-label={@label}
      >
        <.icon name={@icon} class="size-5 shrink-0" aria-hidden="true" />
        <span class="menu-label">{@label}</span>
      </div>
      <ul role="menu" class="ml-4">
        {render_slot(@inner_block)}
      </ul>
    </li>
    <!-- Collapsed Mode: Dropdown -->
    <div class="collapsed-menu-group dropdown dropdown-right" data-testid={@testid}>
      <button
        type="button"
        tabindex="0"
        class="flex items-center gap-3  px-2 py-1.5  rounded-selector hover:bg-base-300 tooltip tooltip-right focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 cursor-pointer"
        role="menuitem"
        data-tip={@label}
        aria-haspopup="menu"
        aria-label={@label}
      >
        <.icon name={@icon} class="size-5 shrink-0" aria-hidden="true" />
      </button>
      <ul
        class="dropdown-content menu bg-base-100 rounded-box shadow-lg z-50 min-w-48 p-2 focus:outline-none"
        role="menu"
      >
        <li class="menu-title">{@label}</li>
        {render_slot(@inner_block)}
      </ul>
    </div>
    """
  end

  attr :href, :string, required: true, doc: "Navigation path for submenu item"
  attr :label, :string, required: true, doc: "Submenu item label"

  defp menu_subitem(assigns) do
    ~H"""
    <li role="none">
      <.link
        navigate={@href}
        role="menuitem"
        class="focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
      >
        {@label}
      </.link>
    </li>
    """
  end

  attr :current_user, :map, default: nil, doc: "The current user"

  defp sidebar_footer(assigns) do
    ~H"""
    <div class="mt-auto p-4 border-t border-base-300 space-y-4">
      <!-- Language Selector (nur expanded) -->
      <form method="post" action={~p"/set_locale"} class="expanded-only">
        <input type="hidden" name="_csrf_token" value={get_csrf_token()} />
        <select
          name="locale"
          onchange="this.form.submit()"
          class="select select-sm w-full focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
          aria-label={gettext("Select language")}
        >
          <option value="de" selected={Gettext.get_locale() == "de"}>Deutsch</option>
          <option value="en" selected={Gettext.get_locale() == "en"}>English</option>
        </select>
      </form>
      <!-- Theme Toggle (immer sichtbar) -->
      <.theme_toggle />
      <!-- User Menu (nur wenn current_user existiert) -->
      <%= if @current_user do %>
        <.user_menu current_user={@current_user} />
      <% end %>
    </div>
    """
  end

  defp theme_toggle(assigns) do
    ~H"""
    <label
      class="flex items-center gap-2 cursor-pointer justify-center focus-within:outline-none focus-within:ring-2 focus-within:ring-primary focus-within:ring-offset-2"
      aria-label={gettext("Toggle dark mode")}
    >
      <.icon name="hero-sun" class="size-5" aria-hidden="true" />
      <div id="theme-toggle" phx-update="ignore">
        <input
          id="theme-toggle-input"
          type="checkbox"
          class="toggle toggle-sm focus:outline-none"
          data-theme-toggle
          onchange="window.dispatchEvent(new CustomEvent('phx:set-theme',{detail:{theme:this.checked?'dark':'light'}}))"
          aria-label={gettext("Toggle dark mode")}
        />
      </div>

      <.icon name="hero-moon" class="size-5" aria-hidden="true" />
    </label>
    """
  end

  attr :current_user, :map, default: nil, doc: "The current user"

  defp user_menu(assigns) do
    # Defensive check: ensure current_user and email exist
    # current_user might be a struct, so we need to handle both maps and structs
    # email might be an Ash.CiString, so we use to_string/1 (not String.to_string/1)
    email =
      case assigns.current_user do
        nil -> ""
        %{email: email_val} when not is_nil(email_val) -> to_string(email_val)
        _ -> ""
      end

    first_letter =
      if email != "" do
        String.first(email) |> String.upcase()
      else
        "?"
      end

    user_id =
      case assigns.current_user do
        nil -> nil
        %{id: id_val} when not is_nil(id_val) -> id_val
        _ -> nil
      end

    # Store computed values in assigns to avoid HEEx warnings
    assigns = assign(assigns, :email, email)
    assigns = assign(assigns, :first_letter, first_letter)
    assigns = assign(assigns, :user_id, user_id)

    ~H"""
    <div class="dropdown dropdown-top dropdown-end w-full">
      <button
        type="button"
        tabindex="0"
        class="user-menu-button flex items-center w-full justify-start gap-3 px-4 h-12 min-h-12 rounded-lg cursor-pointer focus:outline-none"
        aria-label={gettext("User menu")}
        aria-haspopup="menu"
      >
        <!-- Avatar: Placeholder with first letter -->
        <div class="avatar placeholder shrink-0">
          <div class="w-8 h-8 rounded-full bg-neutral text-neutral-content">
            <span class="text-sm font-semibold">
              {@first_letter}
            </span>
          </div>
        </div>
        <span class="menu-label truncate flex-1 text-left">{@email}</span>
      </button>
      <ul
        tabindex="0"
        class="dropdown-content menu bg-base-100 rounded-box shadow-lg w-52 p-2 focus:outline-none absolute z-[100]"
        role="menu"
      >
        <li role="none">
          <%= if @user_id do %>
            <.link
              navigate={~p"/users/#{@user_id}"}
              role="menuitem"
              class="focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
            >
              {gettext("Profile")}
            </.link>
          <% else %>
            <span class="opacity-50">{gettext("Profile")}</span>
          <% end %>
        </li>
        <li role="none">
          <.link
            href={~p"/sign-out"}
            role="menuitem"
            class="focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
          >
            {gettext("Logout")}
          </.link>
        </li>
      </ul>
    </div>
    """
  end
end
