## Symbolic Representation

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

- **Variables:**
  - $x_1$ represents the number of Package A
  - $x_2$ represents the number of Package B

- **Objective Function:**
  The objective is to maximize profit. Package A yields a profit of $120, and Package B yields a profit of $200. Therefore, the objective function can be represented as:
  - Maximize $120x_1 + 200x_2$

- **Constraints:**
  - The company only has 1000 bottles of red wine. Since Package A has 2 bottles of red wine and Package B has 2 bottles of red wine, the constraint can be represented as:
  - $2x_1 + 2x_2 \leq 1000$
  - The company only has 800 bottles of white wine. Since Package A has 1 bottle of white wine and Package B has 3 bottles of white wine, the constraint can be represented as:
  - $x_1 + 3x_2 \leq 800$
  - Non-negativity constraints:
  - $x_1 \geq 0, x_2 \geq 0$

## JSON Representation

```json
{
    'sym_variables': [('x1', 'Package A'), ('x2', 'Package B')],
    'objective_function': '120*x1 + 200*x2',
    'constraints': [
        '2*x1 + 2*x2 <= 1000',
        'x1 + 3*x2 <= 800',
        'x1 >= 0',
        'x2 >= 0'
    ]
}
```

## Gurobi Code

```python
import gurobipy as gp

# Create a new model
model = gp.Model("Wine Promotion")

# Define variables
x1 = model.addVar(name="Package_A", lb=0, vtype=gp.GRB.INTEGER)
x2 = model.addVar(name="Package_B", lb=0, vtype=gp.GRB.INTEGER)

# Objective function: maximize profit
model.setObjective(120*x1 + 200*x2, gp.GRB.MAXIMIZE)

# Constraints
model.addConstr(2*x1 + 2*x2 <= 1000, name="Red_Wine_Constraint")
model.addConstr(x1 + 3*x2 <= 800, name="White_Wine_Constraint")

# Solve the model
model.optimize()

# Print the solution
if model.status == gp.GRB.OPTIMAL:
    print("Optimal Solution:")
    print(f"Package A: {x1.varValue}")
    print(f"Package B: {x2.varValue}")
    print(f"Maximum Profit: {model.objVal}")
else:
    print("No optimal solution found.")
```