class DataStyleSanitizer::Processor

def extract_styles

def extract_styles
  @doc.css("[data-style]").each do |node|
    style_string = node.get_attribute("data-style")
    next if style_string.nil? || style_string.strip.empty? # Skip empty attributes
    # Remove CSS comments and normalize spacing
    style_string = style_string.gsub(/\/\*.*?\*\//, "").strip
    style_string = style_string.split(";").map(&:strip).reject(&:empty?).join("; ")
    next if style_string.empty? # Skip if the style becomes empty after cleaning
    class_name = generate_class_name(style_string)
    # Apply class and remove attribute
    node.remove_attribute("data-style")
    node.set_attribute("class", [node.get_attribute("class"), class_name].compact.join(" "))
    # Store unique styles
    @styles[class_name] ||= style_string
  end
end

def generate_class_name(style_string)

def generate_class_name(style_string)
  hash = Digest::SHA256.hexdigest(style_string.downcase)[0..7] # Ensure case-insensitivity
  "ds-#{hash}"
end

def initialize(html, nonce:)

def initialize(html, nonce:)
  @doc = Nokogiri::HTML::DocumentFragment.parse(html)
  @nonce = nonce
  @styles = {}
end

def inject_style_block

def inject_style_block
  return if @styles.empty?
  # Create the <style> tag
  style_tag = Nokogiri::XML::Node.new("style", @doc)
  style_tag["nonce"] = @nonce
  # Generate CSS rules
  css_rules = @styles.map do |class_name, rule|
    rule_lines = rule.split(";").map(&:strip).reject(&:empty?)
    rule_lines.map! { |line| "#{line.strip} !important;" } # Ensure override
    ".#{class_name} { #{rule_lines.join(" ")} }"
  end.join("\n")
  style_tag.content = css_rules
  # Add the <style> tag to the <head> if it exists, otherwise to the <body> or fragment
  head = @doc.at_css("head")
  if head
    head.add_child(style_tag)
  else
    body = @doc.at_css("body")
    if body
      body.add_child(style_tag)
    else
      @doc.add_child(style_tag) # Append directly to the fragment
    end
  end
end

def process

def process
  extract_styles
  inject_style_block
  @doc.to_html
end