#!/usr/bin/env python3
"""
Gurobipy Implementation for Theme Gallery Optimization Problem
"""

import gurobipy as gp
from gurobipy import GRB

def theme_gallery_optimization():
    # 1. MODEL & DATA SETUP
    model = gp.Model("theme_gallery_optimization")
    
    # Data from the provided SQL schema
    artist_ids = [1, 2, 3]
    exhibition_ids = [1, 2, 3]
    
    # Artist exhibition limits
    max_exhibitions = {1: 5, 2: 6, 3: 4}
    
    # Exhibition artist requirements
    min_artists = {1: 3, 2: 4, 3: 3}
    
    # Ticket prices
    ticket_prices = {1: 50, 2: 70, 3: 60}
    
    # Attendance data
    attendance = {
        (1, 1): 100,
        (2, 2): 200,
        (3, 3): 150
    }
    
    # CRITICAL: Validate array lengths before loops
    assert len(artist_ids) == len(max_exhibitions), "Artist data length mismatch"
    assert len(exhibition_ids) == len(min_artists) == len(ticket_prices), "Exhibition data length mismatch"
    
    # 2. VARIABLES
    x = model.addVars(artist_ids, exhibition_ids, vtype=GRB.INTEGER, name="x", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    revenue = gp.quicksum(ticket_prices[j] * attendance[(i, j)] * x[i, j] 
                          for i in artist_ids for j in exhibition_ids if (i, j) in attendance)
    model.setObjective(revenue, GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    
    # Artist Availability Constraint
    for i in artist_ids:
        model.addConstr(gp.quicksum(x[i, j] for j in exhibition_ids) <= max_exhibitions[i], 
                        name=f"artist_availability_{i}")
    
    # Exhibition Requirement Constraint
    for j in exhibition_ids:
        model.addConstr(gp.quicksum(x[i, j] for i in artist_ids) >= min_artists[j], 
                        name=f"exhibition_requirement_{j}")
    
    # Non-Negativity Constraint is already handled by lb=0 in addVars
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in artist_ids:
            for j in exhibition_ids:
                if x[i, j].x > 1e-6:
                    print(f"Artist {i} participates in Exhibition {j}: {x[i, j].x:.0f} times")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the optimization
if __name__ == "__main__":
    theme_gallery_optimization()