defmodule SimpleshopTheme.Theme.CSSGenerator do
  @moduledoc """
  Generates CSS custom properties (Layer 2: Theme Tokens) from theme settings.

  This module converts ThemeSettings into CSS variables that bridge the gap
  between fixed primitives (Layer 1) and semantic aliases (Layer 3).

  For the shop (public pages), this generates ALL theme tokens inline, so the
  shop doesn't need the attribute-based selectors in theme-layer2-attributes.css.
  The theme editor still uses those selectors for live preview switching.
  """

  alias SimpleshopTheme.Settings.ThemeSettings

  @doc """
  Generates CSS for theme settings.

  Returns a string of CSS custom properties that can be injected into a <style> tag.
  This includes ALL theme tokens (mood, typography, shape, density) so the shop
  pages don't need the attribute-based CSS selectors.
  """
  def generate(%ThemeSettings{} = settings) do
    """
    /* Theme Tokens - Layer 2 (dynamically generated) */
    .themed {
      /* Mood colors */
      #{generate_mood(settings.mood)}

      /* Typography */
      #{generate_typography(settings.typography)}

      /* Shape (border radii) */
      #{generate_shape(settings.shape)}

      /* Density */
      #{generate_density(settings.density)}

      /* Slider-controlled values */
      #{generate_accent(settings.accent_color)}
      #{generate_secondary_colors(settings)}
      #{generate_font_size(settings.font_size)}
      #{generate_heading_weight(settings.heading_weight)}
      #{generate_layout_width(settings.layout_width)}
      #{generate_button_style(settings.button_style)}
      #{generate_product_text_align(settings.product_text_align)}
      #{generate_image_aspect_ratio(settings.image_aspect_ratio)}
    }
    """
    |> String.trim()
  end

  # Mood colors - surface, text, and border colors
  defp generate_mood("neutral") do
    """
    --t-surface-base: #ffffff;
      --t-surface-raised: #ffffff;
      --t-surface-sunken: #f5f5f5;
      --t-surface-overlay: rgba(255, 255, 255, 0.95);
      --t-text-primary: #171717;
      --t-text-secondary: #525252;
      --t-text-tertiary: #a3a3a3;
      --t-text-inverse: #ffffff;
      --t-border-default: #e5e5e5;
      --t-border-subtle: #f0f0f0;
    """
  end

  defp generate_mood("warm") do
    """
    --t-surface-base: #fdf8f3;
      --t-surface-raised: #fffcf8;
      --t-surface-sunken: #f5ebe0;
      --t-surface-overlay: rgba(253, 248, 243, 0.95);
      --t-text-primary: #1c1917;
      --t-text-secondary: #57534e;
      --t-text-tertiary: #a8a29e;
      --t-text-inverse: #ffffff;
      --t-border-default: #e7e0d8;
      --t-border-subtle: #f0ebe4;
    """
  end

  defp generate_mood("cool") do
    """
    --t-surface-base: #f4f7fb;
      --t-surface-raised: #f8fafc;
      --t-surface-sunken: #e8eff7;
      --t-surface-overlay: rgba(244, 247, 251, 0.95);
      --t-text-primary: #0f172a;
      --t-text-secondary: #475569;
      --t-text-tertiary: #94a3b8;
      --t-text-inverse: #ffffff;
      --t-border-default: #d4dce8;
      --t-border-subtle: #e8eff5;
    """
  end

  defp generate_mood("dark") do
    """
    --t-surface-base: #0a0a0a;
      --t-surface-raised: #171717;
      --t-surface-sunken: #000000;
      --t-surface-overlay: rgba(23, 23, 23, 0.95);
      --t-text-primary: #fafafa;
      --t-text-secondary: #a3a3a3;
      --t-text-tertiary: #737373;
      --t-text-inverse: #171717;
      --t-border-default: #262626;
      --t-border-subtle: #1c1c1c;
    """
  end

  # Fallback for any other mood value
  defp generate_mood(_), do: generate_mood("neutral")

  # Typography - font families, weights, and tracking
  defp generate_typography("clean") do
    """
    --t-font-heading: 'Manrope', system-ui, sans-serif;
      --t-font-body: 'Inter', system-ui, sans-serif;
      --t-heading-weight: 600;
      --t-heading-tracking: -0.02em;
    """
  end

  defp generate_typography("editorial") do
    """
    --t-font-heading: 'Playfair Display', Georgia, serif;
      --t-font-body: 'Raleway', system-ui, sans-serif;
      --t-heading-weight: 500;
      --t-heading-tracking: -0.01em;
    """
  end

  defp generate_typography("modern") do
    """
    --t-font-heading: 'Space Grotesk', system-ui, sans-serif;
      --t-font-body: 'Inter', system-ui, sans-serif;
      --t-heading-weight: 500;
      --t-heading-tracking: -0.03em;
    """
  end

  defp generate_typography("classic") do
    """
    --t-font-heading: 'Cormorant Garamond', Georgia, serif;
      --t-font-body: 'Source Serif 4', Georgia, serif;
      --t-heading-weight: 500;
      --t-heading-tracking: 0;
    """
  end

  defp generate_typography("friendly") do
    """
    --t-font-heading: 'Fraunces', Georgia, serif;
      --t-font-body: 'Work Sans', system-ui, sans-serif;
      --t-heading-weight: 600;
      --t-heading-tracking: -0.01em;
    """
  end

  defp generate_typography("minimal") do
    """
    --t-font-heading: 'DM Sans', system-ui, sans-serif;
      --t-font-body: 'Source Serif 4', Georgia, serif;
      --t-heading-weight: 500;
      --t-heading-tracking: 0;
    """
  end

  defp generate_typography("impulse") do
    """
    --t-font-heading: 'Raleway', system-ui, sans-serif;
      --t-font-body: 'Inter', system-ui, sans-serif;
      --t-heading-weight: 300;
      --t-heading-tracking: 0.02em;
    """
  end

  # Fallback for any other typography value
  defp generate_typography(_), do: generate_typography("clean")

  # Shape - border radii
  defp generate_shape("soft") do
    """
    --t-radius-sm: 0.25rem;
      --t-radius-md: 0.5rem;
      --t-radius-lg: 0.75rem;
      --t-radius-button: 0.5rem;
      --t-radius-card: 0.75rem;
      --t-radius-input: 0.5rem;
      --t-radius-image: 0.5rem;
    """
  end

  defp generate_shape("sharp") do
    """
    --t-radius-sm: 0;
      --t-radius-md: 0;
      --t-radius-lg: 0;
      --t-radius-button: 0;
      --t-radius-card: 0;
      --t-radius-input: 0;
      --t-radius-image: 0;
    """
  end

  defp generate_shape("round") do
    """
    --t-radius-sm: 0.5rem;
      --t-radius-md: 0.75rem;
      --t-radius-lg: 1rem;
      --t-radius-button: 0.75rem;
      --t-radius-card: 1rem;
      --t-radius-input: 0.75rem;
      --t-radius-image: 0.75rem;
    """
  end

  defp generate_shape("pill") do
    """
    --t-radius-sm: 9999px;
      --t-radius-md: 9999px;
      --t-radius-lg: 1rem;
      --t-radius-button: 9999px;
      --t-radius-card: 1rem;
      --t-radius-input: 9999px;
      --t-radius-image: 0.75rem;
    """
  end

  # Fallback for any other shape value
  defp generate_shape(_), do: generate_shape("soft")

  # Density - spacing multiplier
  defp generate_density("balanced") do
    """
    --t-density: 1;
      --space-xs: 0.5rem;
      --space-sm: 0.75rem;
      --space-md: 1rem;
      --space-lg: 1.5rem;
      --space-xl: 2rem;
      --space-2xl: 3rem;
    """
  end

  defp generate_density("spacious") do
    """
    --t-density: 1.25;
      --space-xs: 0.625rem;
      --space-sm: 0.9375rem;
      --space-md: 1.25rem;
      --space-lg: 1.875rem;
      --space-xl: 2.5rem;
      --space-2xl: 3.75rem;
    """
  end

  defp generate_density("compact") do
    """
    --t-density: 0.85;
      --space-xs: 0.425rem;
      --space-sm: 0.6375rem;
      --space-md: 0.85rem;
      --space-lg: 1.275rem;
      --space-xl: 1.7rem;
      --space-2xl: 2.55rem;
    """
  end

  # Fallback for any other density value
  defp generate_density(_), do: generate_density("balanced")

  # Accent color with HSL breakdown
  defp generate_accent(hex_color) do
    {h, s, l} = hex_to_hsl(hex_color)

    """
      --t-accent-h: #{h};
      --t-accent-s: #{s}%;
      --t-accent-l: #{l}%;
    """
  end

  # Secondary colors
  defp generate_secondary_colors(settings) do
    """
      --t-secondary-accent: #{settings.secondary_accent_color};
      --t-sale-color: #{settings.sale_color};
    """
  end

  # Font size variations
  # Using 18px as base for better accessibility (WCAG recommends 18px+)
  # Small: 18px, Medium: 19px, Large: 20px
  defp generate_font_size("small") do
    "--t-font-size-scale: 1.125;"
  end

  defp generate_font_size("medium") do
    "--t-font-size-scale: 1.1875;"
  end

  defp generate_font_size("large") do
    "--t-font-size-scale: 1.25;"
  end

  # Heading weight (override typography default)
  defp generate_heading_weight("regular") do
    "--t-heading-weight-override: 400;"
  end

  defp generate_heading_weight("medium") do
    "--t-heading-weight-override: 500;"
  end

  defp generate_heading_weight("bold") do
    "--t-heading-weight-override: 700;"
  end

  # Layout width
  defp generate_layout_width("contained") do
    "--t-layout-max-width: 1100px;"
  end

  defp generate_layout_width("wide") do
    "--t-layout-max-width: 1400px;"
  end

  defp generate_layout_width("full") do
    "--t-layout-max-width: 100%;"
  end

  # Button style
  defp generate_button_style("filled") do
    "--t-button-style: filled;"
  end

  defp generate_button_style("outline") do
    "--t-button-style: outline;"
  end

  defp generate_button_style("soft") do
    "--t-button-style: soft;"
  end

  # Product text alignment
  defp generate_product_text_align("left") do
    "--t-product-text-align: left;"
  end

  defp generate_product_text_align("center") do
    "--t-product-text-align: center;"
  end

  # Image aspect ratio
  defp generate_image_aspect_ratio("square") do
    "--t-image-aspect-ratio: 1 / 1;"
  end

  defp generate_image_aspect_ratio("portrait") do
    "--t-image-aspect-ratio: 3 / 4;"
  end

  defp generate_image_aspect_ratio("landscape") do
    "--t-image-aspect-ratio: 4 / 3;"
  end

  # Convert hex color to HSL
  defp hex_to_hsl("#" <> hex), do: hex_to_hsl(hex)

  defp hex_to_hsl(hex) when byte_size(hex) == 6 do
    {r, ""} = Integer.parse(String.slice(hex, 0..1), 16)
    {g, ""} = Integer.parse(String.slice(hex, 2..3), 16)
    {b, ""} = Integer.parse(String.slice(hex, 4..5), 16)

    # Normalize RGB values to 0-1
    r = r / 255
    g = g / 255
    b = b / 255

    max = Enum.max([r, g, b])
    min = Enum.min([r, g, b])
    delta = max - min

    # Calculate lightness
    l = (max + min) / 2

    # Calculate saturation and hue
    {h, s} =
      if delta == 0 do
        {0, 0}
      else
        s = if l > 0.5, do: delta / (2 - max - min), else: delta / (max + min)

        h =
          cond do
            max == r -> (g - b) / delta + if(g < b, do: 6, else: 0)
            max == g -> (b - r) / delta + 2
            max == b -> (r - g) / delta + 4
          end

        {h * 60, s}
      end

    {round(h), round(s * 100), round(l * 100)}
  end

  # Handle invalid hex values
  defp hex_to_hsl(_), do: {0, 0, 50}
end
