#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Museum Ticket Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def museum_ticket_optimization():
    """Optimize ticket sales across museums to maximize revenue."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("museum_ticket_optimization")
    
    # Data from the problem
    museums = [1, 2, 3]
    total_ticket_limit = {1: 1200, 2: 1500, 3: 1000}
    staff_capacity = {1: 600, 2: 750, 3: 500}
    revenue_per_ticket = {1: 5.0, 2: 5.0, 3: 5.0}  # Derived from Total_spent / Num_of_Ticket
    
    # CRITICAL: Validate array lengths before loops
    assert len(museums) == len(total_ticket_limit) == len(staff_capacity) == len(revenue_per_ticket), "Array length mismatch"
    
    # 2. VARIABLES
    x = {i: model.addVar(vtype=GRB.CONTINUOUS, name=f"x_{i}", lb=0) for i in museums}
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(revenue_per_ticket[i] * x[i] for i in museums), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    # Ticket Sales Limit
    for i in museums:
        model.addConstr(x[i] <= total_ticket_limit[i], name=f"ticket_limit_{i}")
    
    # Staff Availability
    for i in museums:
        model.addConstr(x[i] <= staff_capacity[i], name=f"staff_capacity_{i}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in museums:
            if x[i].x > 1e-6:
                print(f"Tickets sold at museum {i}: {x[i].x:.0f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the optimization
museum_ticket_optimization()