# frozen_string_literal: true

require "application_system_test_case"
require "capybara_screenshot_diff/minitest"

class BootstrapTest < ApplicationSystemTestCase
  setup do
    screenshot_section :bootstrap
    Rails.application.config.bootstrap_form.group_around_collections = true
  end

  teardown do
    Rails.application.config.bootstrap_form.group_around_collections = false
  end

  test "visiting the index" do
    screenshot_group :index
    visit root_url

    all(".toggle").each { |btn| execute_script "arguments[0].remove()", btn }

    all("h3").each do |header|
      example = header.first(:xpath, "./following-sibling::div")
      scroll_to example
      sleep 0.5
      screenshot header.text.downcase.tr(" ", "_"), crop: bounds(example), color_distance_limit: 2
    end

    self.assertions += 1 # To avoid a warning message.
  end

  HEADERS = ["Generated HTML", "This generates", "Which outputs", "will be rendered as"].join("|").freeze
  REGEXP =
    /(?:!\[[^\]]*\]\([^)]+\)\s*)?```erb\n(.*?)\n```\s*((?:#{HEADERS}).*?$)?\s*(```html\n(?:.*?)\n```\s*)?/mi

  test "readme examples" do
    screenshot_group :readme

    readme = File.read(File.expand_path("../../../README.md", __dir__))
    screenshot_index = 0
    augmented_readme = readme.gsub(REGEXP) do |_|
      erb = Regexp.last_match(1)
      header = Regexp.last_match(2)
      unless /\A<%= bootstrap[^>]*>\n\s*...\s*<% end %>\z/.match? erb
        wrapped_erb = erb.starts_with?("<%= bootstrap") ? erb : <<~ERB
          <%= bootstrap_form_with model: @user do |f| %>
            #{erb}
          <% end %>
        ERB

        visit fragment_path erb: wrapped_erb
        wrapper = find(".fragment")
        screenshot :example, crop: bounds(wrapper)
        wrapper = wrapper.find("form") if wrapped_erb != erb
        html = wrapper["innerHTML"].strip.gsub("><", ">\n<")
        assert html.present?, erb
        doc = Nokogiri::HTML.fragment(html)
        doc.traverse do |node|
          if node.is_a?(Nokogiri::XML::Element)
            node.attributes.sort_by(&:first).each do |name, value|
              node.delete(name)
              node[name] = value
            end
          end
        end
        html = doc.to_html
        image = <<~MD
          ![Example #{screenshot_index}](demo/doc/screenshots/bootstrap/readme/#{format('%02i', screenshot_index)}_example.png "Example #{screenshot_index}")
        MD
        screenshot_index += 1
        html = <<~MD

          #{header || 'Generated HTML:'}

          ```html
          #{HtmlBeautifier.beautify(html)}
          ```
        MD
      end
      <<~MD
        #{image}```erb
        #{erb}
        ```
        #{html}
      MD
    end
    augmented_readme.gsub!(/(127.0.0.1:\d+|web:3001)/, "test.host")
    File.write(File.expand_path("../../../README.md", __dir__), augmented_readme)
  end

  private

  def bounds(node)
    client_rect = evaluate_script("arguments[0].getBoundingClientRect()", node.native)
    [client_rect["left"].floor, client_rect["top"].floor, client_rect["right"].ceil, client_rect["bottom"].ceil]
  end
end
