module GameHelper
  def frontend_javascript_importmap_tags(only_use = %w[application])
    only_use = Array(only_use)
    importmap_json = JSON.parse(Rails.application.importmap.to_json(resolver: self))["imports"].select { |k, v| only_use.include?(k) }
    safe_join [
          javascript_inline_importmap_tag(JSON.pretty_generate({ "imports" => importmap_json })),
          javascript_module_preload_tag(*importmap_json.map { |v| v[1] }),
          javascript_import_module_tag(only_use[0])
        ], "\n"
  end


  def node_title(node)
    parts = [ node.page_title.blank? ? node.title : node.page_title ]
    parts << t(:client_name)
    parts.uniq.join(" - ")
  rescue
    t(:client_name)
  end


  def render_responsive_picture(asset = nil, alt: "", lazy: false, fetchpriority: nil)
    return unless asset

    widths   = [ 800, 1600, 2400 ]
    metadata = asset.file.metadata

    image_tag(rails_storage_proxy_path(asset.file.variant(resize_to_limit: [ 1600, nil ], format: "webp")),
              alt: alt,
              srcset: responsive_srcset(asset, widths),
              sizes: "100vw",
              width: metadata[:width],
              height: metadata[:height],
              loading: ("lazy" if lazy),
              fetchpriority: fetchpriority,
              decoding: "async")
  end


  def responsive_srcset(asset, widths)
    widths.map { |w|
      "#{rails_storage_proxy_path(asset.file.variant(resize_to_limit: [ w, nil ], format: "webp"))} #{w}w"
    }.join(", ")
  end


  RESULT_BANDS = [ [ 8, :best ], [ 5, :balanced ], [ 0, :worst ] ].freeze

  def result_state(player)
    if (answer_id = player.last_save_answer_id)
      return last_save_result_state(answer_id)
    end

    overall = player.score.to_i
    RESULT_BANDS.find { |threshold, _| overall >= threshold }.last
  end


  def result_headline(player)
    t("game.results.#{result_state(player)}.headline").html_safe
  end


  def result_description(player)
    t("game.results.#{result_state(player)}.description").html_safe
  end


  IMPACT_TONE_BANDS = {
    default: [ [ 3, :positive ], [ 1, :neutral ], [ -Float::INFINITY, :negative ] ],
    income:  [ [ 2, :positive ], [ 0, :neutral ], [ -Float::INFINITY, :negative ] ]
  }.freeze

  def impact_tone(player, category)
    score = player.score_for(category)
    bands = IMPACT_TONE_BANDS[category] || IMPACT_TONE_BANDS[:default]
    bands.find { |threshold, _| score >= threshold }.last
  end


  def impact_label(category)
    t("game.results.#{category}.label")
  end


  def impact_message(player, category)
    if category == :income && player.last_save_answer_id.present?
      return t("game.results.income.early_exit")
    end

    t("game.results.#{category}.#{impact_tone(player, category)}")
  end


  def impact_learn_more(category)
    t("game.results.#{category}.learn_more")
  end


  private

  def last_save_result_state(answer_id)
    answer = Node.find_by(id: answer_id)
    config  = JSON.parse(Rails.root.join("config", "question_scores.json").read)
    type    = config.dig("last_save", "answers", answer.position - 1, "result_type") if answer
    type&.to_sym || :compost
  end
end
