# frozen_string_literal: true class Api::V1::LocationsController < ApiController before_action :validate_search_params, only: [:index] before_action :validate_suggestion_params, only: [:suggestions] def index if search_query.present? || coordinate_search? search_results = LocationSearch::PointFinder.new(current_api_user, search_params).call render json: LocationSearchResultSerializer.new(search_results).call else render json: { error: 'Search query parameter (q) or coordinates (lat, lon) are required' }, status: :bad_request end rescue StandardError => e Rails.logger.error "Location search error: #{e.message}" Rails.logger.error e.backtrace.join("\n") render json: { error: 'Search failed. Please try again.' }, status: :internal_server_error end def suggestions if search_query.present? && search_query.length >= 2 suggestions = LocationSearch::GeocodingService.new.search(search_query) # Format suggestions for the frontend formatted_suggestions = suggestions.map do |suggestion| { name: suggestion[:name], address: suggestion[:address], coordinates: [suggestion[:lat], suggestion[:lon]], type: suggestion[:type] } end render json: { suggestions: formatted_suggestions } else render json: { suggestions: [] } end rescue StandardError => e Rails.logger.error "Suggestions error: #{e.message}" render json: { suggestions: [] } end private def search_query params[:q]&.strip end def search_params { query: search_query, latitude: params[:lat]&.to_f, longitude: params[:lon]&.to_f, name: params[:name], address: params[:address], limit: params[:limit]&.to_i || 50, date_from: parse_date(params[:date_from]), date_to: parse_date(params[:date_to]), radius_override: params[:radius_override]&.to_i } end def coordinate_search? params[:lat].present? && params[:lon].present? end def validate_search_params if search_query.blank? && !coordinate_search? render json: { error: 'Search query parameter (q) or coordinates (lat, lon) are required' }, status: :bad_request return false end if search_query.present? && search_query.length > 200 render json: { error: 'Search query too long (max 200 characters)' }, status: :bad_request return false end if coordinate_search? lat = params[:lat]&.to_f lon = params[:lon]&.to_f if lat.abs > 90 || lon.abs > 180 render json: { error: 'Invalid coordinates: latitude must be between -90 and 90, longitude between -180 and 180' }, status: :bad_request return false end end true end def validate_suggestion_params if search_query.present? && search_query.length > 200 render json: { error: 'Search query too long (max 200 characters)' }, status: :bad_request return false end true end def parse_date(date_string) return nil if date_string.blank? Date.parse(date_string) rescue ArgumentError nil end end