## Symbolic Representation

The problem can be converted into a symbolic representation as follows:

* Variables: 
  - `x1`: red bean bags
  - `x2`: blue bean bags

* Objective function: `5*x1 + 8*x2`

* Constraints:
  - `x1 >= 3` (at least 3 red bean bags)
  - `x2 >= 2` (at least 2 blue bean bags)
  - `x1 <= 8` (at most 8 red bean bags)
  - `x2 <= 8` (at most 8 blue bean bags)
  - `x1 + x2 = 12` (total of 12 bean bags)

## JSON Representation

```json
{
    'sym_variables': [('x1', 'red bean bags'), ('x2', 'blue bean bags')],
    'objective_function': '5*x1 + 8*x2',
    'constraints': [
        'x1 >= 3',
        'x2 >= 2',
        'x1 <= 8',
        'x2 <= 8',
        'x1 + x2 = 12'
    ]
}
```

## Gurobi Code

```python
import gurobi

def solve_bean_bag_problem():
    # Create a new Gurobi model
    model = gurobi.Model()

    # Define variables
    x1 = model.addVar(lb=0, ub=8, name="red_bean_bags", vtype=gurobi.GRB.INTEGER)
    x2 = model.addVar(lb=0, ub=8, name="blue_bean_bags", vtype=gurobi.GRB.INTEGER)

    # Objective function: maximize 5*x1 + 8*x2
    model.setObjective(5*x1 + 8*x2, gurobi.GRB.MAXIMIZE)

    # Constraints
    model.addConstr(x1 >= 3, name="min_red_bean_bags")
    model.addConstr(x2 >= 2, name="min_blue_bean_bags")
    model.addConstr(x1 <= 8, name="max_red_bean_bags")
    model.addConstr(x2 <= 8, name="max_blue_bean_bags")
    model.addConstr(x1 + x2 == 12, name="total_bean_bags")

    # Optimize
    model.optimize()

    # Print solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution: x1 = {x1.varValue}, x2 = {x2.varValue}")
        print(f"Maximum points: {5*x1.varValue + 8*x2.varValue}")
    else:
        print("No optimal solution found")

solve_bean_bag_problem()
```