To solve this optimization problem, we need to define variables and constraints based on the given information. Let's denote:

- $x$ as the number of desk lamps produced,
- $y$ as the number of chandeliers produced.

The objective is to maximize profit. The profit per desk lamp is $200, and the profit per chandelier is $500. Therefore, the total profit $P$ can be represented as:

\[ P = 200x + 500y \]

We have two main constraints based on the resources available:

1. **Manufacturing Time Constraint**: Each desk lamp takes 20 minutes of manufacturing time, and each chandelier takes 60 minutes. The company has 1500 minutes of manufacturing time available. Therefore, the constraint can be written as:

\[ 20x + 60y \leq 1500 \]

2. **Light Bulb Constraint**: Each desk lamp requires 1 light bulb, and each chandelier requires 15 light bulbs. The company has 300 light bulbs available. Thus, the constraint is:

\[ x + 15y \leq 300 \]

Additionally, we have a requirement that the company must make at least 40 desk lamps, which gives us another constraint:

\[ x \geq 40 \]

Since the number of items produced cannot be negative, we also have non-negativity constraints:

\[ x \geq 0, y \geq 0 \]

Now, let's write the Gurobi code to solve this linear programming problem.

```python
from gurobipy import *

# Create a new model
m = Model("Lighting_Company_Profit")

# Define variables
x = m.addVar(lb=40, vtype=GRB.INTEGER, name="desk_lamps")  # Number of desk lamps
y = m.addVar(vtype=GRB.INTEGER, name="chandeliers")  # Number of chandeliers

# Set the objective function: Maximize profit
m.setObjective(200*x + 500*y, GRB.MAXIMIZE)

# Add constraints
m.addConstr(20*x + 60*y <= 1500, "manufacturing_time")
m.addConstr(x + 15*y <= 300, "light_bulbs")

# Optimize model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution: {x.varName} = {int(x.x)}, {y.varName} = {int(y.x)}")
    print(f"Maximum Profit: ${200*int(x.x) + 500*int(y.x)}")
else:
    print("No optimal solution found.")
```