defmodule MicrowavepropWeb.Layouts do
  @moduledoc """
  This module holds layouts and related functionality
  used by your application.
  """
  use MicrowavepropWeb, :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://hexdocs.pm/phoenix/scopes.html)"

  attr :max_width, :string, default: "max-w-2xl", doc: "max width class for the content container"
  slot :inner_block, required: true

  def app(assigns) do
    ~H"""
    <header class="navbar px-4 sm:px-6 lg:px-8 border-b border-base-200">
      <div class="flex-1 gap-4">
        <a href="/" class="font-semibold tracking-tight">Microwave Propagation</a>
        <nav class="flex gap-1">
          <.link navigate="/map" class="btn btn-ghost btn-sm">Map</.link>
          <.link navigate="/path" class="btn btn-ghost btn-sm">Path</.link>
          <.link navigate="/beacons" class="btn btn-ghost btn-sm">Beacons</.link>
          <.link navigate="/submit" class="btn btn-ghost btn-sm">Submit</.link>
          <.link navigate="/contacts" class="btn btn-ghost btn-sm">Contacts</.link>
          <.link navigate="/contacts/map" class="btn btn-ghost btn-sm">Contact Map</.link>
          <.link navigate="/about" class="btn btn-ghost btn-sm">About</.link>
          <div
            :if={@current_scope && @current_scope.user && @current_scope.user.is_admin}
            class="dropdown dropdown-end"
          >
            <div tabindex="0" role="button" class="btn btn-ghost btn-sm">
              Admin <.icon name="hero-chevron-down-micro" class="size-3" />
            </div>
            <ul
              tabindex="0"
              class="dropdown-content menu bg-base-100 rounded-box z-[1] w-44 p-2 shadow-lg"
            >
              <li><.link navigate="/users">Users</.link></li>
              <li><.link navigate="/admin/contact-edits">Contact edits</.link></li>
              <li><.link href="/admin/oban">Oban</.link></li>
            </ul>
          </div>
          <%= if @current_scope && @current_scope.user do %>
            <.link
              navigate={~p"/u/#{@current_scope.user.callsign}"}
              class="btn btn-ghost btn-sm"
            >
              {@current_scope.user.callsign}
            </.link>
            <.link href={~p"/users/settings"} class="btn btn-ghost btn-sm">Settings</.link>
            <.link href={~p"/users/log-out"} method="delete" class="btn btn-ghost btn-sm">
              Log out
            </.link>
          <% else %>
            <.link href={~p"/users/register"} class="btn btn-ghost btn-sm">Register</.link>
            <.link href={~p"/users/log-in"} class="btn btn-ghost btn-sm">Log in</.link>
          <% end %>
        </nav>
      </div>
      <div class="flex-none flex items-center gap-3">
        <.deploy_stamp />
        <.theme_toggle />
      </div>
    </header>

    <main class="px-4 py-20 sm:px-6 lg:px-8">
      <div class={["mx-auto space-y-4", @max_width]}>
        {render_slot(@inner_block)}
      </div>
    </main>

    <footer class="px-4 sm:px-6 lg:px-8 pb-6">
      <div class={["mx-auto text-center text-xs opacity-60 space-y-1", @max_width]}>
        <div>
          Built by and for the
          <a href="https://ntms.org" target="_blank" class="link link-hover">
            North Texas Microwave Society
          </a>
        </div>
        <div>
          <.link navigate="/privacy" class="link link-hover">Privacy</.link>
        </div>
      </div>
    </footer>

    <.flash_group flash={@flash} />
    """
  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")}
        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!")}
        hidden
      >
        {gettext("Attempting to reconnect")}
        <.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" />
      </.flash>
    </div>
    """
  end

  @doc """
  Shows when the running release was deployed, as a compact relative timestamp
  with the full UTC time in the tooltip.
  """
  def deploy_stamp(assigns) do
    ts = Microwaveprop.Application.build_timestamp()
    iso = Calendar.strftime(ts, "%Y-%m-%d %H:%M UTC")
    assigns = assign(assigns, build_time: ts, iso: iso, ago: format_time_ago(ts))

    ~H"""
    <span
      class="hidden md:inline text-xs opacity-60"
      title={"Last deployed #{@iso}"}
    >
      Deployed {@ago}
    </span>
    """
  end

  defp format_time_ago(%DateTime{} = dt) do
    diff = max(DateTime.diff(DateTime.utc_now(), dt, :second), 0)

    cond do
      diff < 60 -> "just now"
      diff < 3600 -> "#{div(diff, 60)}m ago"
      diff < 86_400 -> "#{div(diff, 3600)}h ago"
      diff < 2_592_000 -> "#{div(diff, 86_400)}d ago"
      diff < 31_536_000 -> "#{div(diff, 2_592_000)}mo ago"
      true -> "#{div(diff, 31_536_000)}y ago"
    end
  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 transition-[left]" />

      <button
        class="flex p-2 cursor-pointer w-1/3"
        phx-click={JS.dispatch("phx:set-theme")}
        data-phx-theme="system"
      >
        <.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"
      >
        <.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"
      >
        <.icon name="hero-moon-micro" class="size-4 opacity-75 hover:opacity-100" />
      </button>
    </div>
    """
  end
end
