defmodule BerrypodWeb.NavigationController do
  @moduledoc """
  No-JS fallback for navigation form submission.

  With JS enabled, the LiveView handles everything. Without JS,
  the form POSTs here and we redirect back to the LiveView page.
  """
  use BerrypodWeb, :controller

  alias Berrypod.Settings

  def save(conn, %{"header_nav" => header_json, "footer_nav" => footer_json}) do
    with {:ok, header_items} <- Jason.decode(header_json),
         {:ok, footer_items} <- Jason.decode(footer_json) do
      all_items = header_items ++ footer_items
      errors = validate_nav_items(all_items)

      if errors == [] do
        Settings.put_setting("header_nav", header_items, "json")
        Settings.put_setting("footer_nav", footer_items, "json")

        conn
        |> put_flash(:info, "Navigation saved")
        |> redirect(to: ~p"/admin/navigation")
      else
        conn
        |> put_flash(:error, Enum.join(errors, ". "))
        |> redirect(to: ~p"/admin/navigation")
      end
    else
      {:error, _} ->
        conn
        |> put_flash(:error, "Invalid navigation data")
        |> redirect(to: ~p"/admin/navigation")
    end
  end

  defp validate_nav_items(items) do
    items
    |> Enum.flat_map(fn item ->
      cond do
        item["label"] == "" || item["label"] == nil ->
          ["All links need a label"]

        item["href"] == "" || item["href"] == nil ->
          ["\"#{item["label"]}\" needs a destination"]

        item["external"] == true || is_external_url?(item["href"]) ->
          if valid_url?(item["href"]) do
            []
          else
            ["\"#{item["label"]}\" has an invalid URL"]
          end

        true ->
          []
      end
    end)
    |> Enum.uniq()
  end

  defp valid_url?(url) when is_binary(url) do
    case URI.parse(url) do
      %URI{scheme: scheme, host: host}
      when scheme in ["http", "https"] and is_binary(host) and host != "" ->
        true

      _ ->
        false
    end
  end

  defp valid_url?(_), do: false

  defp is_external_url?(nil), do: false
  defp is_external_url?(""), do: false

  defp is_external_url?(href) do
    String.starts_with?(href, "http://") || String.starts_with?(href, "https://")
  end
end
