#!/usr/bin/env python3
"""
DOCplex implementation for concert_singer optimization problem
"""

from docplex.mp.model import Model

def optimize_concert_singer():
    """Optimize singer assignments to concerts in stadiums to maximize audience capacity."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="concert_singer")
    
    # Data from the database
    stadium_capacities = [10000, 20000, 30000]
    singer_assignments = [0, 1, 0, 1, 0]
    
    # Business configuration parameter
    L = 2  # Maximum number of concerts a singer can participate in
    
    # Validate array lengths
    n_stadiums = len(stadium_capacities)
    n_assignments = len(singer_assignments)
    assert n_stadiums > 0 and n_assignments > 0, "Empty data arrays"
    
    # Safe range for indexing
    safe_range = range(min(n_stadiums, n_assignments))
    
    # 2. VARIABLES
    # Decision variables: x_ij = 1 if singer i is assigned to concert in stadium j, 0 otherwise
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in safe_range for j in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total audience capacity
    objective = mdl.sum(stadium_capacities[j] * x[(i, j)] for i in safe_range for j in safe_range)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Singer Assignment Limit: Each singer can participate in at most L concerts
    for i in safe_range:
        mdl.add_constraint(mdl.sum(x[(i, j)] for j in safe_range) <= L, ctname=f"singer_limit_{i}")
    
    # Stadium Capacity Limit: Each concert in stadium j cannot exceed the stadium's capacity
    for j in safe_range:
        mdl.add_constraint(mdl.sum(x[(i, j)] for i in safe_range) <= stadium_capacities[j], ctname=f"stadium_capacity_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            for j in safe_range:
                value = solution.get_value(x[(i, j)])
                if value > 1e-6:
                    print(f"Singer {i} assigned to stadium {j}: {value:.0f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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