defmodule TarakanWeb.CurrentPath do
  @moduledoc """
  Makes the request path available to the layout as `@current_path`.

  The navigation highlight used to be applied by JavaScript after render, which
  had two problems. Every page painted with nothing highlighted and lit up a
  frame later, and dead controller routes like `/pricing` have no LiveSocket at
  all, so the hook never ran there and the tab could never highlight itself.

  Both go away if the server decides. This supplies the path for the two kinds
  of page: a plug for controller-rendered views, and an `on_mount` hook that
  re-reads it on every `handle_params` so live navigation stays correct.
  """

  import Phoenix.Component, only: [assign: 3]
  import Phoenix.LiveView, only: [attach_hook: 4]

  @doc "Plug for controller-rendered pages."
  def init(opts), do: opts

  def call(conn, _opts), do: Plug.Conn.assign(conn, :current_path, conn.request_path)

  @doc "`on_mount` hook for live sessions."
  def on_mount(:default, _params, _session, socket) do
    {:cont,
     socket
     |> assign(:current_path, nil)
     |> attach_hook(:current_path, :handle_params, &put_current_path/3)}
  end

  defp put_current_path(_params, uri, socket) do
    {:cont, assign(socket, :current_path, URI.parse(uri).path)}
  end

  @doc """
  Whether `path` is the section the visitor is currently in.

  A section owns its subtree, so `/jobs` stays lit on `/jobs/12`. The root is
  matched exactly, otherwise it would own every page on the site.
  """
  def active?(nil, _path), do: false
  def active?(_current, nil), do: false
  def active?(current, "/"), do: current == "/"

  def active?(current, path) do
    current == path or String.starts_with?(current, path <> "/")
  end
end
