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: 20
    })
  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: 10
    })
  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|
        {
          label: "#{item[:name]} (#{item[:postal_code]})",
          value: item[:code],
          data: item[:postal_code]
        }
      end
    end
  end

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