optimize this code
require 'time'

class Api::V1::SchedulesController < ApplicationController
  def index
    departure_station = params[:departure].upcase if params[:departure].present?
    destination_station = params[:destination].upcase if params[:destination].present?
    time_param = params[:time]
    exclude_param = params[:restrict]
    time = time_param.present? ? Time.parse(time_param) : nil
    exclude = exclude_param.present? ? exclude_param.downcase == 'true' : false

    puts departure_station
    if departure_station.present? && destination_station.present?
     
      schedules = Schedule.joins(:stations)
      .where("stations.name LIKE ? OR stations.name LIKE ? OR stations.name = ? OR stations.name = ?", "#{departure_station} %", "#{destination_station} %", "#{departure_station}", "#{destination_station}")
      .group('schedules.id')
      .having('COUNT(DISTINCT stations.name) >= 2')
      .distinct
      .includes(:stations, route: :bus_schedule)
      puts schedules

      trips = []
      schedules.each do |schedule|
        stations = schedule.stations.order(:id)
        station_names = stations.map(&:name)
        puts station_names



        #  check if dep station comes before dest station using index
        departure_index = station_names.index { |name| name =~ /#{departure_station}/i }
        destination_index = station_names.index { |name| name =~ /#{destination_station}/i }
        if departure_index && destination_index && departure_index < destination_index
          departure_station_data = stations[departure_index]
          departure_time = Time.parse(departure_station_data.departure_time)


          # optional time parameter
          next if time && departure_time < time

          trip_data = {
            vehicle_number: schedule.route.bus_schedule.vehicle_number,
            trip: schedule.trip,
            stations: stations.map do |station| 
              {
                station: station.name,
                arrivalTime: station.arrival_time,
                departureTime: station.departure_time
              }
            end
          }

          # Exclude stations before departure and after destination if exclude parameter is true
          if exclude
            trip_data[:stations] = trip_data[:stations][departure_index..destination_index]
          end
  
          trips << trip_data
        end
      end
  
      # sort based on dep time of dep station
      sorted_trips = trips.each do |trip|
        trip[:stations].sort_by! do |station|
          if station[:station] =~ /#{departure_station}/i
            Time.parse(station[:departureTime]) # 12-h am/pm format
          else
            Time.new(9999) # If the station name doesn't match the pattern, set a far future time so it's sorted to the end
          end
        end
      end.sort_by do |trip|
        time_str = trip[:stations].find { |station| station[:station] =~ /#{departure_station}/i }[:departureTime]
        Time.parse(time_str) # 12-h am/pm format
      end
      render json: sorted_trips, status: :ok
  
    else
      render json: { error: 'Departure and destination stations are required. ' }, status: :unprocessable_entity
    end
  end
end