# Complete GUROBIPY implementation

import gurobipy as gp
from gurobipy import GRB

def entertainment_awards_optimization():
    """Optimize artwork nominations for maximum audience impact."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("entertainment_awards")
    
    # Data from the database
    num_of_audience = [1200, 4500, 9000]  # Audience sizes for each festival
    max_nominations = [3, 5, 7]  # Max nominations per artwork
    max_capacity = [50, 100, 150]  # Max capacity per festival
    
    num_artworks = len(max_nominations)
    num_festivals = len(num_of_audience)
    
    # CRITICAL: Validate array lengths before loops
    assert len(max_capacity) == num_festivals, "Array length mismatch for festivals"
    
    # 2. VARIABLES
    # Binary decision variables for nominations
    x = model.addVars(num_artworks, num_festivals, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total audience impact
    model.setObjective(
        gp.quicksum(num_of_audience[j] * x[i, j] for i in range(num_artworks) for j in range(num_festivals)),
        GRB.MAXIMIZE
    )
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Maximum nominations per artwork
    model.addConstrs(
        (gp.quicksum(x[i, j] for j in range(num_festivals)) <= max_nominations[i] for i in range(num_artworks)),
        name="max_nominations_per_artwork"
    )
    
    # Maximum capacity per festival
    model.addConstrs(
        (gp.quicksum(x[i, j] for i in range(num_artworks)) <= max_capacity[j] for j in range(num_festivals)),
        name="max_capacity_per_festival"
    )
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in range(num_artworks):
            for j in range(num_festivals):
                if x[i, j].x > 1e-6:
                    print(f"x[{i},{j}] = {x[i, j].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
entertainment_awards_optimization()