class RoundRobin::ManageService
  pattr_initialize [:inbox!]

  # called on inbox delete
  def clear_queue
    ::Redis::Alfred.delete(round_robin_key)
  end

  # called on inbox member create
  def add_agent_to_queue(user_id)
    ::Redis::Alfred.lpush(round_robin_key, user_id)
  end

  # called on inbox member delete
  def remove_agent_from_queue(user_id)
    ::Redis::Alfred.lrem(round_robin_key, user_id)
  end

  def available_agent(priority_list: [])
    reset_queue unless validate_queue?
    user_id = get_agent_via_priority_list(priority_list)
    # incase priority list was empty or inbox members weren't present
    user_id ||= ::Redis::Alfred.rpoplpush(round_robin_key, round_robin_key)
    inbox.inbox_members.find_by(user_id: user_id)&.user if user_id.present?
  end

  def reset_queue
    clear_queue
    add_agent_to_queue(inbox.inbox_members.map(&:user_id))
  end

  private

  def get_agent_via_priority_list(priority_list)
    return if priority_list.blank?

    user_id = queue.intersection(priority_list.map(&:to_s)).pop
    if user_id.present?
      remove_agent_from_queue(user_id)
      add_agent_to_queue(user_id)
    end
    user_id
  end

  def validate_queue?
    return true if inbox.inbox_members.map(&:user_id).sort == queue.map(&:to_i).sort
  end

  def queue
    ::Redis::Alfred.lrange(round_robin_key)
  end

  def round_robin_key
    format(::Redis::Alfred::ROUND_ROBIN_AGENTS, inbox_id: inbox.id)
  end
end
