defmodule WhoNeedHelpWeb.Layouts do
  @moduledoc """
  This module holds layouts and related functionality
  used by your application.
  """
  use WhoNeedHelpWeb, :html

  # Embed all files in layouts/* within this module.
  # The default root.html.heex file contains the HTML
  # skeleton of your application, namely HTML headers
  # and other static content.
  embed_templates "layouts/*"

  @doc """
  Renders your app layout.

  This function is typically invoked from every template,
  and it often contains your application menu, sidebar,
  or similar.

  ## Examples

      <Layouts.app flash={@flash}>
        <h1>Content</h1>
      </Layouts.app>

  """
  attr :flash, :map, required: true, doc: "the map of flash messages"

  attr :current_scope, :map,
    default: nil,
    doc: "the current [scope](https://phoenix.hexdocs.pm/scopes.html)"

  slot :inner_block, required: true

  def app(assigns) do
    ~H"""
    <header class="sticky top-0 z-30 border-b border-base-300 bg-base-100 px-4 py-2 sm:px-6 lg:px-8">
      <div class="mx-auto flex min-h-12 w-full max-w-7xl items-center justify-between gap-3">
        <a
          href="/"
          class="flex min-w-0 items-center gap-3"
          aria-label={gettext("Who Need Help home")}
        >
          <img
            src={~p"/images/logo.svg"}
            width="36"
            height="36"
            alt=""
            class="size-9 shrink-0"
          />
          <span class="truncate font-black tracking-tight">Who Need Help</span>
        </a>

        <nav class="min-w-0 flex-none" aria-label={gettext("Primary navigation")}>
          <div class="hidden items-center gap-1 xl:flex">
            <ul class="flex items-center gap-0.5">
              <.primary_navigation_links current_scope={@current_scope} />
            </ul>

            <div
              class="ml-1 flex items-center gap-1 border-l border-base-300 pl-2"
              aria-label={gettext("Account and language")}
            >
              <.locale_switcher />
              <.theme_toggle />

              <%= if @current_scope do %>
                <.link navigate={~p"/requests/new"} class="btn btn-primary btn-sm whitespace-nowrap">
                  {gettext("Ask for help")}
                </.link>
                <.account_menu current_scope={@current_scope} />
              <% else %>
                <.link navigate={~p"/users/register"} class="btn btn-ghost btn-sm">
                  {gettext("Register")}
                </.link>
                <.link navigate={~p"/users/log-in"} class="btn btn-primary btn-sm">
                  {gettext("Log in")}
                </.link>
              <% end %>
            </div>
          </div>

          <details class="dropdown dropdown-end xl:hidden">
            <summary
              class="btn btn-ghost btn-square"
              aria-label={gettext("Primary navigation")}
            >
              <.icon name="hero-bars-3" class="size-6" />
            </summary>

            <div class="dropdown-content mt-3 w-[min(20rem,calc(100vw-2rem))] overflow-hidden rounded-box border border-base-300 bg-base-100 shadow-xl">
              <ul class="menu w-full p-2">
                <.primary_navigation_links
                  current_scope={@current_scope}
                  link_class="justify-start"
                />
              </ul>

              <div class="flex flex-wrap items-center justify-between gap-3 border-t border-base-300 px-4 py-3">
                <.locale_switcher />
                <.theme_toggle />
              </div>

              <%= if @current_scope do %>
                <ul class="menu w-full border-t border-base-300 p-2">
                  <li>
                    <.link navigate={~p"/profile"}>{gettext("Profile")}</.link>
                  </li>
                  <li>
                    <.link href={~p"/users/settings"}>{gettext("Account settings")}</.link>
                  </li>
                  <li>
                    <.link href={~p"/users/log-out"} method="delete">{gettext("Log out")}</.link>
                  </li>
                </ul>
                <div class="border-t border-base-300 p-3">
                  <.link navigate={~p"/requests/new"} class="btn btn-primary btn-block">
                    {gettext("Ask for help")}
                  </.link>
                </div>
              <% else %>
                <div class="grid grid-cols-2 gap-2 border-t border-base-300 p-3">
                  <.link navigate={~p"/users/register"} class="btn btn-outline">
                    {gettext("Register")}
                  </.link>
                  <.link navigate={~p"/users/log-in"} class="btn btn-primary">
                    {gettext("Log in")}
                  </.link>
                </div>
              <% end %>
            </div>
          </details>
        </nav>
      </div>
    </header>

    <main id="main-content" tabindex="-1" class="px-4 py-8 outline-none sm:px-6 lg:px-8">
      <div class="mx-auto max-w-7xl space-y-4">
        {render_slot(@inner_block)}
      </div>
    </main>

    <footer class="border-t border-base-300 px-4 py-6 text-center text-xs text-base-content/70">
      <.link href={~p"/safety"} class="link">{gettext("Safety rules")}</.link>
      <span class="mx-2">·</span>
      <.link href={~p"/privacy"} class="link">{gettext("Privacy")}</.link>
      <span class="mx-2">·</span>
      <.link href={~p"/terms"} class="link">{gettext("Terms")}</.link>
      <span class="mx-2">·</span>
      <.link href={~p"/support"} class="link">{gettext("Support")}</.link>
      <span class="mx-2">·</span>
      <.link href={~p"/legal/content-removal"} class="link">{gettext("Report content")}</.link>
      <span class="mx-2">·</span>
      <.link href={~p"/feedback"} class="link">{gettext("Build Week feedback")}</.link>
    </footer>

    <.flash_group flash={@flash} />
    """
  end

  attr :current_scope, :map, default: nil
  attr :link_class, :string, default: "btn btn-ghost btn-sm"

  defp primary_navigation_links(assigns) do
    ~H"""
    <li>
      <.link navigate={~p"/requests"} class={@link_class}>
        {gettext("Requests")}
      </.link>
    </li>
    <li>
      <.link navigate={~p"/activities"} class={@link_class}>
        {gettext("Activities")}
      </.link>
    </li>
    <li>
      <.link navigate={~p"/categories/proposals"} class={@link_class}>
        {gettext("Categories")}
      </.link>
    </li>
    <li>
      <.link navigate={~p"/leaderboard"} class={@link_class}>
        {gettext("Helpers")}
      </.link>
    </li>
    <li :if={@current_scope && @current_scope.user.role in [:moderator, :admin]}>
      <.link navigate={~p"/moderation"} class={["btn-warning", @link_class]}>
        {gettext("Moderation")}
      </.link>
    </li>
    <li :if={@current_scope && @current_scope.user.role in [:moderator, :admin]}>
      <.link navigate={~p"/support/operations"} class={["btn-warning", @link_class]}>
        {gettext("Support queue")}
      </.link>
    </li>
    """
  end

  defp locale_switcher(assigns) do
    ~H"""
    <div
      class="join"
      role="group"
      aria-label={gettext("Account and language")}
    >
      <a
        href="?locale=en"
        class={[
          "btn btn-ghost btn-xs join-item",
          Gettext.get_locale(WhoNeedHelpWeb.Gettext) == "en" && "btn-active locale-active"
        ]}
        aria-label="English"
        aria-current={Gettext.get_locale(WhoNeedHelpWeb.Gettext) == "en" && "page"}
      >
        EN
      </a>
      <a
        href="?locale=uk"
        class={[
          "btn btn-ghost btn-xs join-item",
          Gettext.get_locale(WhoNeedHelpWeb.Gettext) == "uk" && "btn-active locale-active"
        ]}
        aria-label="Українська"
        aria-current={Gettext.get_locale(WhoNeedHelpWeb.Gettext) == "uk" && "page"}
      >
        UK
      </a>
      <a
        href="?locale=ru"
        class={[
          "btn btn-ghost btn-xs join-item",
          Gettext.get_locale(WhoNeedHelpWeb.Gettext) == "ru" && "btn-active locale-active"
        ]}
        aria-label="Русский"
        aria-current={Gettext.get_locale(WhoNeedHelpWeb.Gettext) == "ru" && "page"}
      >
        RU
      </a>
    </div>
    """
  end

  attr :current_scope, :map, required: true

  defp account_menu(assigns) do
    ~H"""
    <details class="dropdown dropdown-end">
      <summary class="btn btn-ghost btn-sm gap-1">
        <.icon name="hero-user-circle" class="size-5" />
        <span class="flex max-w-36 flex-col items-start overflow-hidden leading-tight">
          <span class="max-w-full truncate">
            {@current_scope.user.display_name || @current_scope.user.email}
          </span>
          <span
            :if={@current_scope.user.display_name}
            class="max-w-full truncate text-[0.65rem] font-normal opacity-60"
          >
            {@current_scope.user.email}
          </span>
        </span>
        <.icon name="hero-chevron-down-micro" class="size-4 opacity-60" />
      </summary>
      <div class="dropdown-content mt-3 w-64 overflow-hidden rounded-box border border-base-300 bg-base-100 shadow-xl">
        <ul class="menu w-full p-2">
          <li>
            <.link navigate={~p"/profile"}>{gettext("Profile")}</.link>
          </li>
          <li>
            <.link href={~p"/users/settings"}>{gettext("Account settings")}</.link>
          </li>
          <li>
            <.link href={~p"/users/log-out"} method="delete">{gettext("Log out")}</.link>
          </li>
        </ul>
      </div>
    </details>
    """
  end

  @doc """
  Shows the flash group with standard titles and content.

  ## Examples

      <.flash_group flash={@flash} />
  """
  attr :flash, :map, required: true, doc: "the map of flash messages"
  attr :id, :string, default: "flash-group", doc: "the optional id of flash container"

  def flash_group(assigns) do
    ~H"""
    <div id={@id} aria-live="polite">
      <.flash kind={:info} flash={@flash} />
      <.flash kind={:error} flash={@flash} />

      <.flash
        id="client-error"
        kind={:error}
        title={gettext("We can't find the internet")}
        phx-disconnected={
          show(".phx-client-error #client-error")
          |> JS.remove_attribute("hidden", to: ".phx-client-error #client-error")
        }
        phx-connected={hide("#client-error") |> JS.set_attribute({"hidden", ""})}
        hidden
      >
        {gettext("Attempting to reconnect")}
        <.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" />
      </.flash>

      <.flash
        id="server-error"
        kind={:error}
        title={gettext("Something went wrong!")}
        phx-disconnected={
          show(".phx-server-error #server-error")
          |> JS.remove_attribute("hidden", to: ".phx-server-error #server-error")
        }
        phx-connected={hide("#server-error") |> JS.set_attribute({"hidden", ""})}
        hidden
      >
        {gettext("Attempting to reconnect")}
        <.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" />
      </.flash>
    </div>
    """
  end

  @doc """
  Provides dark vs light theme toggle based on themes defined in app.css.

  See <head> in root.html.heex which applies the theme before page load.
  """
  def theme_toggle(assigns) do
    ~H"""
    <div class="card relative flex flex-row items-center border-2 border-base-300 bg-base-300 rounded-full">
      <div class="absolute w-1/3 h-full rounded-full border-1 border-base-200 bg-base-100 brightness-200 left-0 [[data-theme=light]_&]:left-1/3 [[data-theme=dark]_&]:left-2/3 [[data-theme-source=system]_&]:!left-0 transition-[left]" />

      <button
        class="flex p-2 cursor-pointer w-1/3"
        phx-click={JS.dispatch("phx:set-theme")}
        data-phx-theme="system"
        aria-label={gettext("Use system theme")}
      >
        <.icon name="hero-computer-desktop-micro" class="size-4 opacity-75 hover:opacity-100" />
      </button>

      <button
        class="flex p-2 cursor-pointer w-1/3"
        phx-click={JS.dispatch("phx:set-theme")}
        data-phx-theme="light"
        aria-label={gettext("Use light theme")}
      >
        <.icon name="hero-sun-micro" class="size-4 opacity-75 hover:opacity-100" />
      </button>

      <button
        class="flex p-2 cursor-pointer w-1/3"
        phx-click={JS.dispatch("phx:set-theme")}
        data-phx-theme="dark"
        aria-label={gettext("Use dark theme")}
      >
        <.icon name="hero-moon-micro" class="size-4 opacity-75 hover:opacity-100" />
      </button>
    </div>
    """
  end
end
