# Complete DOCPLEX implementation

from docplex.mp.model import Model

def singer_promotion_optimization():
    """Optimization model for selecting singers to maximize song sales."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="singer_promotion")
    
    # Data from the problem
    singers = [1, 2, 3]
    sales = {1: 1500, 2: 2500, 3: 1000}
    net_worth = {1: 200000, 2: 300000, 3: 150000}  # Placeholder values
    total_budget = 500000
    max_singers = 3
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(singers) == len(sales) == len(net_worth), "Array length mismatch"
    safe_range = range(min(len(singers), len(sales), len(net_worth)))  # Safe indexing
    
    # 2. VARIABLES
    x = {i: mdl.binary_var(name=f"x_{i}") for i in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(sales[i+1] * x[i] for i in safe_range)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Budget Constraint
    budget_constraint = mdl.sum(net_worth[i+1] * x[i] for i in safe_range)
    mdl.add_constraint(budget_constraint <= total_budget, ctname="budget_limit")
    
    # Promotional Capacity Constraint
    promotional_capacity = mdl.sum(x[i] for i in safe_range)
    mdl.add_constraint(promotional_capacity <= max_singers, ctname="promo_capacity")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            value = solution.get_value(x[i])
            if value > 1e-6:
                print(f"Singer {singers[i]} selected: {value:.0f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the optimization model
singer_promotion_optimization()