class DataSources::CommuneController < ApplicationController
  def search
    if params[:q].present? && params[:q].length > 1
      response = fetch_results

      if response.success?
        results = JSON.parse(response.body, symbolize_names: true)

        render json: format_results(results)
      else
        render json: []
      end
    else
      render json: []
    end
  end

  private

  def fetch_results
    if postal_code?(params[:q])
      fetch_by_postal_code(params[:q])
    else
      fetch_by_name(params[:q])
    end
  end

  def fetch_by_name(name)
    Typhoeus.get("#{API_GEO_URL}/communes", params: {
      type: 'commune-actuelle,arrondissement-municipal',
      nom: name,
      boost: 'population',
      limit: 100
    }, timeout: 3)
  end

  def fetch_by_postal_code(postal_code)
    Typhoeus.get("#{API_GEO_URL}/communes", params: {
      type: 'commune-actuelle,arrondissement-municipal',
      codePostal: postal_code,
      boost: 'population',
      limit: 50
    }, timeout: 3)
  end

  def postal_code?(string)
    string.match?(/\A[-+]?\d+\z/) ? true : false
  end

  def format_results(results)
    results.reject(&method(:code_metropole?)).flat_map do |result|
      item = {
        name: result[:nom].tr("'", '’'),
        code: result[:code],
        epci_code: result[:codeEpci],
        departement_code: result[:codeDepartement]
      }.compact

      if result[:codesPostaux].present?
        result[:codesPostaux].map { item.merge(postal_code: _1) }
      else
        [item]
      end.map do |item|
        if params[:with_combined_code].present?
          {
            label: "#{item[:name]} (#{item[:postal_code]})",
            value: "#{item[:code]}-#{item[:postal_code]}"
          }
        else
          {
            label: "#{item[:name]} (#{item[:postal_code]})",
            value: item[:code],
            data: item[:postal_code]
          }
        end
      end
    end
  end

  def code_metropole?(result)
    result[:code].in?(['75056', '13055', '69123'])
  end
end