defmodule BerrypodWeb.Shop.Pages.CustomPage do
  @moduledoc """
  Custom (CMS) page handler for the unified Shop.Page LiveView.
  """

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

  alias Berrypod.Pages

  def init(socket, _params, _uri) do
    # Custom pages load in handle_params based on slug
    {:noreply, socket}
  end

  def handle_params(%{"slug" => slug} = params, uri, socket) do
    page = Pages.get_page(slug)

    cond do
      is_nil(page) ->
        record_broken_url("/#{slug}")
        raise BerrypodWeb.NotFoundError

      page.type != "custom" ->
        raise BerrypodWeb.NotFoundError

      page.published != true and not socket.assigns.is_admin ->
        raise BerrypodWeb.NotFoundError

      true ->
        handle_page(page_to_map(page), params, uri, socket)
    end
  end

  defp handle_page(page, _params, _uri, socket) do
    extra = Pages.load_block_data(page.blocks, socket.assigns)
    base = BerrypodWeb.Endpoint.url()

    socket =
      socket
      |> assign(:page_title, page.title)
      |> assign(:page, page)
      |> maybe_assign_meta(page, base)
      |> assign(extra)

    {:noreply, socket}
  end

  # Convert Page struct to map for consistent handling
  defp page_to_map(%Berrypod.Pages.Page{} = page) do
    %{
      id: page.id,
      slug: page.slug,
      title: page.title,
      blocks: page.blocks,
      type: page.type,
      published: page.published,
      meta_description: page.meta_description,
      url_slug: page.url_slug,
      show_in_nav: page.show_in_nav,
      nav_label: page.nav_label,
      nav_position: page.nav_position
    }
  end

  defp page_to_map(page) when is_map(page), do: page

  def handle_event(_event, _params, _socket), do: :cont

  defp record_broken_url(path) do
    # Skip static asset paths - these are expected 404s
    unless static_path?(path) do
      prior_hits = Berrypod.Analytics.count_pageviews_for_path(path)
      Berrypod.Redirects.record_broken_url(path, prior_hits)

      if prior_hits > 0 do
        Berrypod.Redirects.attempt_auto_resolve(path)
      end
    end
  rescue
    _ -> :ok
  end

  defp static_path?(path) do
    String.starts_with?(path, "/assets/") or
      String.starts_with?(path, "/images/") or
      String.starts_with?(path, "/image_cache/") or
      String.starts_with?(path, "/mockups/") or
      String.starts_with?(path, "/favicon")
  end

  defp maybe_assign_meta(socket, page, base) do
    socket
    |> assign(:og_url, base <> "/#{page.slug}")
    |> then(fn s ->
      if page.meta_description do
        assign(s, :page_description, page.meta_description)
      else
        s
      end
    end)
  end
end
