class Dsfr::ComboboxComponent < ApplicationComponent
  def initialize(form: nil, options: nil, url: nil, selected: nil, allows_custom_value: false, limit: nil, input_html_options: {}, hidden_html_options: {})
    @form, @options, @url, @selected, @allows_custom_value, @limit, @input_html_options, @hidden_html_options = form, options, url, selected, allows_custom_value, limit, input_html_options, hidden_html_options
  end

  attr_reader :form, :options, :url, :selected, :allows_custom_value, :limit

  private

  def name
    @input_html_options[:name]
  end

  def form_id
    @input_html_options[:form_id]
  end

  def html_input_options
    {
      type: 'text',
      autocomplete: 'off',
      spellcheck: 'false',
      id: input_id,
      class: input_class,
      role: 'combobox',
      'aria-expanded': 'false',
      'aria-describedby': @input_html_options[:describedby]
    }.compact
  end

  def input_id
    @input_html_options[:id]
  end

  def input_class
    class_names(
      "#{@input_html_options[:class]}": @input_html_options[:class].presence,
      'fr-select': true,
      'fr-autocomplete': @url.presence
    )
  end

  def selected_option_label_input_value
    if selected.is_a?(Array) && selected.size == 2
      selected.first
    elsif options.present?
      selected.present? ? options_with_values.find { _1.last == selected }&.first : nil
    else
      selected
    end
  end

  def selected_option_value_input_value
    if selected.is_a?(Array) && selected.size == 2
      selected.last
    else
      selected
    end
  end

  def list_id
    input_id.present? ? "#{input_id}-list" : nil
  end

  def options_with_values
    return [] if url.present?
    options.map { _1.is_a?(Array) ? _1 : [_1, _1] }
  end

  def options_json
    return nil if url.present?
    options_with_values.map { |(label, value)| { label:, value: } }.to_json
  end

  def hints_json
    {
      empty: t(".sr.results", count: 0),
      one: t(".sr.results", count: 1),
      many: t(".sr.results", count: 2),
      oneWithLabel: t(".sr.results_with_label", count: 1),
      manyWithLabel: t(".sr.results_with_label", count: 2),
      selected: t(".sr.selected", count: 2)
    }.to_json
  end
end