defmodule BerrypodWeb.ThemeHook do
  @moduledoc """
  LiveView on_mount hook for theme settings, CSS, and media assigns.

  Mounted in the public_shop live_session alongside CartHook.
  Eliminates the identical theme-loading boilerplate from every shop LiveView.

  ## Actions

  - `:mount_theme` — loads theme settings, CSS, and media assigns
  - `:require_site_live` — redirects unauthenticated visitors to /coming-soon
    when the shop is not live
  """

  import Phoenix.Component, only: [assign: 3]

  alias Berrypod.{Products, Settings, Media}
  alias Berrypod.Theme.{CSSCache, CSSGenerator}

  @default_header_nav [
    %{"label" => "Home", "href" => "/", "slug" => "home"},
    %{
      "label" => "Shop",
      "href" => "/collections/all",
      "slug" => "collection",
      "active_slugs" => ["collection", "pdp"]
    },
    %{"label" => "About", "href" => "/about", "slug" => "about"},
    %{"label" => "Contact", "href" => "/contact", "slug" => "contact"}
  ]

  @default_footer_nav [
    %{"label" => "Delivery & returns", "href" => "/delivery", "slug" => "delivery"},
    %{"label" => "Privacy policy", "href" => "/privacy", "slug" => "privacy"},
    %{"label" => "Terms of service", "href" => "/terms", "slug" => "terms"},
    %{"label" => "Contact", "href" => "/contact", "slug" => "contact"}
  ]

  def default_header_nav, do: @default_header_nav
  def default_footer_nav, do: @default_footer_nav

  def on_mount(:mount_theme, _params, _session, socket) do
    theme_settings = Settings.get_theme_settings()

    generated_css =
      case CSSCache.get() do
        {:ok, css} ->
          css

        :miss ->
          css = CSSGenerator.generate(theme_settings, &BerrypodWeb.Endpoint.static_path/1)
          CSSCache.put(css)
          css
      end

    socket =
      socket
      |> assign(:theme_settings, theme_settings)
      |> assign(:site_name, Settings.site_name())
      |> assign(:site_description, Settings.site_description())
      |> assign(:generated_css, generated_css)
      |> assign(:logo_image, Media.get_logo())
      |> assign(:header_image, Media.get_header())
      |> assign(:categories, Products.list_categories())
      |> assign(:mode, :shop)
      |> assign(
        :is_admin,
        !!(socket.assigns[:current_scope] && socket.assigns.current_scope.user)
      )
      |> assign(:header_nav_items, load_nav("header_nav", @default_header_nav))
      |> assign(:footer_nav_items, load_nav("footer_nav", @default_footer_nav))

    {:cont, socket}
  end

  def on_mount(:require_site_live, _params, _session, socket) do
    cond do
      Settings.site_live?() ->
        {:cont, socket}

      # mount_current_scope runs first, so current_scope is already validated
      socket.assigns[:current_scope] && socket.assigns.current_scope.user ->
        {:cont, socket}

      true ->
        {:halt, Phoenix.LiveView.redirect(socket, to: "/coming-soon")}
    end
  end

  defp load_nav(key, default) do
    case Settings.get_setting(key) do
      items when is_list(items) -> items
      _ -> default
    end
  end
end
