defmodule ToweropsWeb.Layouts do
  @moduledoc """
  This module holds layouts and related functionality
  used by your application.
  """
  use ToweropsWeb, :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)"

  slot :inner_block, required: true

  def app(assigns) do
    ~H"""
    <div class="flex min-h-screen flex-col bg-zinc-50 dark:bg-zinc-950">
      <header class="border-b border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
        <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
          <nav class="flex h-16 items-center justify-between">
            <div class="flex items-center">
              <.link navigate={~p"/"} class="text-xl font-bold text-zinc-900 dark:text-zinc-100">
                Towerops
              </.link>
            </div>
            <div class="flex items-center gap-x-4">
              <.link
                navigate={~p"/users/log-in"}
                class="text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-zinc-100"
              >
                Log in
              </.link>
              <.link
                navigate={~p"/users/register"}
                class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-500"
              >
                Sign up
              </.link>
            </div>
          </nav>
        </div>
      </header>

      <main class="flex-1 px-4 py-12 sm:px-6 lg:px-8">
        <div class="mx-auto max-w-2xl">
          {render_slot(@inner_block)}
        </div>
      </main>

      <.footer />
    </div>

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

  @doc """
  Renders the authenticated app layout with navigation.

  Use this for pages that require organization context.

  ## Examples

      <Layouts.authenticated flash={@flash} current_organization={@current_organization} active_page="dashboard">
        <h1>Content</h1>
      </Layouts.authenticated>

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

  attr :current_scope, :map,
    default: nil,
    doc: "the current scope (contains user and impersonation state)"

  attr :current_organization, :any,
    default: nil,
    doc: "the current organization (can be nil for pages without org context)"

  attr :active_page, :string,
    default: nil,
    doc: "the currently active page (dashboard, sites, device, or alerts)"

  slot :inner_block, required: true

  def authenticated(assigns) do
    ~H"""
    <div class="flex min-h-screen flex-col bg-zinc-50 dark:bg-zinc-950">
      <!-- Impersonation Banner -->
      <%= if @current_scope && @current_scope.impersonating? do %>
        <div class="bg-yellow-400 border-b-2 border-yellow-600">
          <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-2">
            <div class="flex items-center justify-between">
              <div class="flex items-center gap-2">
                <.icon name="hero-exclamation-triangle" class="w-5 h-5" />
                <span class="font-medium">
                  Impersonating: {@current_scope.user.email}
                </span>
              </div>
              <.link
                href={~p"/admin/impersonate"}
                method="delete"
                class="px-3 py-1 bg-white text-yellow-900 hover:bg-yellow-50 rounded font-medium text-sm"
              >
                Exit Impersonation
              </.link>
            </div>
          </div>
        </div>
      <% end %>

      <nav class="border-b border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
        <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
          <div class="flex h-16 justify-between">
            <div class="flex">
              <div class="flex flex-shrink-0 items-center">
                <.link navigate={~p"/orgs"} class="text-xl font-bold text-zinc-900 dark:text-zinc-100">
                  Towerops
                </.link>
              </div>
              <div :if={@current_organization} class="ml-10 flex space-x-8">
                <.nav_link
                  navigate={~p"/orgs/#{@current_organization.slug}"}
                  active={@active_page == "dashboard"}
                >
                  Dashboard
                </.nav_link>
                <.nav_link
                  navigate={~p"/orgs/#{@current_organization.slug}/sites"}
                  active={@active_page == "sites"}
                >
                  Sites
                </.nav_link>
                <.nav_link
                  navigate={~p"/orgs/#{@current_organization.slug}/devices"}
                  active={@active_page == "devices"}
                >
                  Devices
                </.nav_link>
                <.nav_link
                  navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
                  active={@active_page == "alerts"}
                >
                  Alerts
                </.nav_link>
                <.nav_link
                  navigate={~p"/orgs/#{@current_organization.slug}/agents"}
                  active={@active_page == "agents"}
                >
                  Agents
                </.nav_link>
              </div>
            </div>
            <div class="relative flex items-center">
              <button
                type="button"
                id="org-menu-button"
                phx-click={JS.toggle(to: "#org-menu")}
                class="inline-flex items-center justify-center gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs inset-ring-1 inset-ring-gray-300 hover:bg-gray-50 dark:bg-white/10 dark:text-white dark:shadow-none dark:inset-ring-white/5 dark:hover:bg-white/20"
              >
                {if @current_organization, do: @current_organization.name, else: "Menu"}
                <svg
                  viewBox="0 0 20 20"
                  fill="currentColor"
                  data-slot="icon"
                  aria-hidden="true"
                  class="-mr-1 size-5 text-gray-400"
                >
                  <path
                    d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z"
                    clip-rule="evenodd"
                    fill-rule="evenodd"
                  />
                </svg>
              </button>

              <div
                id="org-menu"
                class="hidden absolute top-full right-0 mt-2 w-56 origin-top-right rounded-md bg-white shadow-lg outline-1 outline-black/5 z-50 dark:bg-gray-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10"
                phx-click-away={JS.hide(to: "#org-menu")}
              >
                <div class="py-1">
                  <.link
                    :if={@current_organization}
                    navigate={~p"/orgs"}
                    class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-hidden dark:text-gray-300 dark:hover:bg-white/5 dark:hover:text-white"
                    phx-click={JS.hide(to: "#org-menu")}
                  >
                    Switch Org
                  </.link>
                  <.link
                    :if={@current_organization}
                    navigate={~p"/orgs/#{@current_organization.slug}/settings"}
                    class="flex items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-hidden dark:text-gray-300 dark:hover:bg-white/5 dark:hover:text-white"
                    phx-click={JS.hide(to: "#org-menu")}
                  >
                    <.icon name="hero-cog-6-tooth" class="w-4 h-4" /> Organization Settings
                  </.link>
                  <%= if @current_scope && @current_scope.user && @current_scope.user.is_superuser do %>
                    <.link
                      navigate={~p"/admin"}
                      class="flex items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-hidden dark:text-gray-300 dark:hover:bg-white/5 dark:hover:text-white"
                      phx-click={JS.hide(to: "#org-menu")}
                    >
                      <.icon name="hero-shield-check" class="w-4 h-4" /> Admin Panel
                    </.link>
                  <% end %>
                  <.link
                    navigate={~p"/users/settings"}
                    class="flex items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-hidden dark:text-gray-300 dark:hover:bg-white/5 dark:hover:text-white"
                    phx-click={JS.hide(to: "#org-menu")}
                  >
                    <.icon name="hero-user-circle" class="w-4 h-4" /> User Settings
                  </.link>
                  <.link
                    href={~p"/users/log-out"}
                    method="delete"
                    class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-hidden dark:text-gray-300 dark:hover:bg-white/5 dark:hover:text-white"
                  >
                    Log out
                  </.link>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>

      <main class="flex-1 py-10">
        <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
          {render_slot(@inner_block)}
        </div>
      </main>

      <.footer />
    </div>

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

  attr :navigate, :string, required: true
  attr :active, :boolean, default: false
  slot :inner_block, required: true

  defp nav_link(assigns) do
    ~H"""
    <.link
      navigate={@navigate}
      class={[
        "inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium",
        if(@active,
          do: "border-zinc-900 text-zinc-900 dark:border-zinc-100 dark:text-zinc-100",
          else:
            "border-transparent text-zinc-700 hover:border-zinc-300 hover:text-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-700 dark:hover:text-zinc-100"
        )
      ]}
    >
      {render_slot(@inner_block)}
    </.link>
    """
  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")}
        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")}
        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 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

  @doc """
  Renders the admin layout.

  Use this for admin pages that require superuser access.

  ## Examples

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

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

  slot :inner_block, required: true

  def admin(assigns) do
    ~H"""
    <div class="flex min-h-screen flex-col bg-zinc-50 dark:bg-zinc-950">
      <nav class="bg-white border-b border-zinc-200 dark:border-zinc-800 dark:bg-zinc-900">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div class="flex justify-between h-16">
            <div class="flex">
              <.link
                navigate={~p"/admin"}
                class="flex items-center text-xl font-bold text-zinc-900 dark:text-zinc-100"
              >
                Towerops Admin
              </.link>
              <div class="hidden sm:ml-6 sm:flex sm:space-x-8">
                <.link
                  navigate={~p"/admin/users"}
                  class="inline-flex items-center px-1 pt-1 text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-zinc-100"
                >
                  Users
                </.link>
                <.link
                  navigate={~p"/admin/organizations"}
                  class="inline-flex items-center px-1 pt-1 text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-zinc-100"
                >
                  Organizations
                </.link>
              </div>
            </div>
            <div class="flex items-center">
              <.link
                navigate={~p"/orgs"}
                class="text-sm text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
              >
                Back to App
              </.link>
            </div>
          </div>
        </div>
      </nav>

      <main class="flex-1">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
          {render_slot(@inner_block)}
        </div>
      </main>

      <.footer />
    </div>

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

  @doc """
  Renders the application footer with copyright notice and deploy timestamp.
  """
  def footer(assigns) do
    alias ToweropsWeb.TimeHelpers

    build_time = Towerops.Application.build_timestamp()

    assigns =
      assigns
      |> assign(:build_time, build_time)
      |> assign(:time_ago, TimeHelpers.format_time_ago(build_time))
      |> assign(:formatted_time, TimeHelpers.format_iso8601(build_time))

    ~H"""
    <footer class="border-t border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
      <div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
        <div class="flex flex-col items-center gap-2 text-sm text-zinc-600 dark:text-zinc-400">
          <p>Copyright © {Date.utc_today().year} Towerops</p>
          <p class="text-xs">
            Last deploy {@time_ago} · {@formatted_time}
          </p>
        </div>
      </div>
    </footer>
    """
  end
end
