defmodule SimpleshopTheme.Theme.Presets do
  @moduledoc """
  Defines the 8 curated theme presets for SimpleShop.
  """

  @presets %{
    gallery: %{
      mood: "warm",
      typography: "editorial",
      shape: "soft",
      density: "spacious",
      grid_columns: "3",
      header_layout: "centered",
      accent_color: "#e85d04",
      layout_width: "wide",
      card_shadow: "sm",
      announcement_bar: true
    },
    studio: %{
      mood: "neutral",
      typography: "clean",
      shape: "soft",
      density: "balanced",
      grid_columns: "4",
      header_layout: "standard",
      accent_color: "#2563eb",
      layout_width: "wide",
      card_shadow: "sm",
      announcement_bar: true
    },
    boutique: %{
      mood: "warm",
      typography: "classic",
      shape: "soft",
      density: "balanced",
      grid_columns: "3",
      header_layout: "left",
      accent_color: "#b45309",
      layout_width: "contained",
      card_shadow: "md",
      announcement_bar: true
    },
    bold: %{
      mood: "neutral",
      typography: "modern",
      shape: "sharp",
      density: "compact",
      grid_columns: "4",
      header_layout: "standard",
      accent_color: "#dc2626",
      layout_width: "full",
      card_shadow: "none",
      announcement_bar: true
    },
    playful: %{
      mood: "neutral",
      typography: "friendly",
      shape: "pill",
      density: "balanced",
      grid_columns: "4",
      header_layout: "standard",
      accent_color: "#8b5cf6",
      layout_width: "wide",
      card_shadow: "md",
      announcement_bar: true
    },
    minimal: %{
      mood: "neutral",
      typography: "impulse",
      shape: "sharp",
      density: "spacious",
      grid_columns: "2",
      header_layout: "standard",
      accent_color: "#171717",
      layout_width: "full",
      card_shadow: "none",
      announcement_bar: false
    },
    night: %{
      mood: "dark",
      typography: "modern",
      shape: "soft",
      density: "balanced",
      grid_columns: "4",
      header_layout: "standard",
      accent_color: "#f97316",
      layout_width: "wide",
      card_shadow: "lg",
      announcement_bar: true
    },
    classic: %{
      mood: "warm",
      typography: "classic",
      shape: "soft",
      density: "spacious",
      grid_columns: "3",
      header_layout: "standard",
      accent_color: "#166534",
      layout_width: "contained",
      card_shadow: "sm",
      announcement_bar: true
    }
  }

  @descriptions %{
    gallery: "Editorial serif headlines",
    studio: "Clean modern sans-serif",
    boutique: "Elegant classic serif",
    bold: "Tech-forward geometric",
    playful: "Quirky variable font",
    minimal: "Light refined pairing",
    night: "Dark tech aesthetic",
    classic: "Traditional luxury serif"
  }

  # Core keys used to match presets (excludes branding-specific settings)
  @core_keys ~w(mood typography shape density grid_columns header_layout accent_color layout_width card_shadow announcement_bar)a

  @doc """
  Returns all available presets.

  ## Examples

      iex> all()
      %{gallery: %{...}, studio: %{...}, ...}

  """
  def all, do: @presets

  @doc """
  Gets a preset by name.

  ## Examples

      iex> get(:gallery)
      %{mood: "warm", typography: "editorial", ...}

      iex> get(:nonexistent)
      nil

  """
  def get(preset_name) when is_atom(preset_name) do
    Map.get(@presets, preset_name)
  end

  @doc """
  Lists all preset names.

  ## Examples

      iex> list_names()
      [:gallery, :studio, :boutique, :bold, :playful, :minimal, :night, :classic]

  """
  def list_names do
    Map.keys(@presets)
  end

  @doc """
  Gets the description for a preset.

  ## Examples

      iex> get_description(:gallery)
      "Elegant & editorial"

  """
  def get_description(preset_name) when is_atom(preset_name) do
    Map.get(@descriptions, preset_name, "")
  end

  @doc """
  Returns all presets with their descriptions.

  ## Examples

      iex> all_with_descriptions()
      [{:bold, "High contrast, strong"}, ...]

  """
  def all_with_descriptions do
    @presets
    |> Map.keys()
    |> Enum.sort()
    |> Enum.map(fn name -> {name, Map.get(@descriptions, name, "")} end)
  end

  @doc """
  Detects which preset matches the current theme settings, if any.
  Only compares core theme keys, ignoring branding-specific settings.

  ## Examples

      iex> detect_preset(%ThemeSettings{mood: "warm", typography: "editorial", ...})
      :gallery

      iex> detect_preset(%ThemeSettings{...customized...})
      nil

  """
  def detect_preset(theme_settings) do
    current_core = extract_core_values(theme_settings)

    Enum.find_value(@presets, fn {name, preset} ->
      preset_core = Map.take(preset, @core_keys)

      if maps_match?(current_core, preset_core) do
        name
      else
        nil
      end
    end)
  end

  defp extract_core_values(theme_settings) do
    theme_settings
    |> Map.from_struct()
    |> Map.take(@core_keys)
  end

  defp maps_match?(map1, map2) do
    Enum.all?(@core_keys, fn key ->
      Map.get(map1, key) == Map.get(map2, key)
    end)
  end
end
