To solve this optimization problem, we first need to define our variables and the objective function, followed by the constraints.

Let's denote:
- $x_1$ as the number of bedside tables produced,
- $x_2$ as the number of bookcases produced.

The profit from selling each bedside table is $200, and for each bookcase, it is $500. Thus, our objective function to maximize profit can be written as:
\[ 200x_1 + 500x_2 \]

Now, let's define our constraints based on the given information:
1. Crafting hours: Each bedside table requires 2.5 hours of crafting, and each bookcase requires 5 hours. There are a maximum of 30 crafting hours available per day.
\[ 2.5x_1 + 5x_2 \leq 30 \]
2. Polishing hours: Each bedside table requires 1.5 hours of polishing, and each bookcase requires 3 hours. There are a maximum of 20 polishing hours available per day.
\[ 1.5x_1 + 3x_2 \leq 20 \]
3. Non-negativity constraints: The number of bedside tables and bookcases produced cannot be negative.
\[ x_1 \geq 0, x_2 \geq 0 \]

Given this analysis, the symbolic representation of our problem is:

```json
{
  'sym_variables': [('x1', 'number of bedside tables'), ('x2', 'number of bookcases')],
  'objective_function': '200*x1 + 500*x2',
  'constraints': ['2.5*x1 + 5*x2 <= 30', '1.5*x1 + 3*x2 <= 20', 'x1 >= 0', 'x2 >= 0']
}
```

Now, let's implement this problem in Gurobi using Python:

```python
from gurobipy import *

# Create a new model
model = Model("Furniture_Factory")

# Define variables
x1 = model.addVar(vtype=GRB.CONTINUOUS, name="bedside_tables", lb=0)
x2 = model.addVar(vtype=GRB.CONTINUOUS, name="bookcases", lb=0)

# Set objective function
model.setObjective(200*x1 + 500*x2, GRB.MAXIMIZE)

# Add constraints
model.addConstr(2.5*x1 + 5*x2 <= 30, "crafting_hours")
model.addConstr(1.5*x1 + 3*x2 <= 20, "polishing_hours")

# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Bedside tables: {x1.x}")
    print(f"Bookcases: {x2.x}")
    print(f"Maximum profit: ${model.objVal:.2f}")
else:
    print("No optimal solution found")
```