# Complete GUROBIPY implementation

import gurobipy as gp
from gurobipy import GRB

def optimize_museum_staff_allocation(total_available_staff):
    """Optimize staff allocation across museums to maximize visitor satisfaction."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("museum_visit")
    
    # Data from the database
    satisfaction_coefficients = [1.3, 1.6, 1.2]
    cost_coefficients = [0.9, 1.1, 0.8]
    minimum_staff_required = [5, 7, 4]
    maximum_staff_capacity = [15, 20, 10]
    
    n_museums = len(satisfaction_coefficients)
    
    # CRITICAL: Validate array lengths before loops
    assert len(cost_coefficients) == len(minimum_staff_required) == len(maximum_staff_capacity) == n_museums, "Array length mismatch"
    
    # 2. VARIABLES
    # Variable dictionaries for staff allocation
    staff_allocation = {i: model.addVar(vtype=GRB.INTEGER, name=f"x_{i}", lb=minimum_staff_required[i], ub=maximum_staff_capacity[i]) 
                        for i in range(n_museums)}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total visitor satisfaction minus total operational cost
    model.setObjective(gp.quicksum((satisfaction_coefficients[i] - cost_coefficients[i]) * staff_allocation[i] for i in range(n_museums)), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Total staff constraint
    model.addConstr(gp.quicksum(staff_allocation[i] for i in range(n_museums)) <= total_available_staff, name="total_staff_limit")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in range(n_museums):
            print(f"Staff allocated to museum {i+1}: {staff_allocation[i].x:.0f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Example usage
total_available_staff = 30  # Example total available staff
optimize_museum_staff_allocation(total_available_staff)