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

from docplex.mp.model import Model

def game_injury_optimization():
    """Optimize game scheduling to minimize injury risk while meeting stadium constraints"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="game_injury_optimization")
    
    # Data from the problem context
    game_ids = [1, 2, 3]
    stadium_ids = [1, 2, 3]
    
    injury_risk = {1: 0.15, 2: 0.1, 3: 0.2}
    stadium_capacity = {1: 0.85, 2: 0.9, 3: 0.8}
    stadium_attendance = {1: 5500, 2: 6000, 3: 5000}
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(game_ids) == len(injury_risk), "Game data length mismatch"
    assert len(stadium_ids) == len(stadium_capacity) == len(stadium_attendance), "Stadium data length mismatch"
    
    # Safe indexing ranges
    game_range = range(len(game_ids))
    stadium_range = range(len(stadium_ids))
    
    # 2. VARIABLES
    # Binary decision variable for game scheduling
    x = {i: mdl.binary_var(name=f"x_{i}") for i in game_range}
    
    # Continuous decision variable for stadium usage percentage
    y = {j: mdl.continuous_var(name=f"y_{j}", lb=0, ub=1) for j in stadium_range}
    
    # 3. OBJECTIVE FUNCTION
    # Minimize total injury risk across all scheduled games
    objective = mdl.sum(injury_risk[game_ids[i]] * x[i] for i in game_range)
    mdl.minimize(objective)
    
    # 4. CONSTRAINTS
    
    # Stadium Capacity Constraint
    for j in stadium_range:
        mdl.add_constraint(
            mdl.sum(x[i] for i in game_range) * stadium_capacity[stadium_ids[j]] <= y[j] * stadium_capacity[stadium_ids[j]],
            ctname=f"stadium_capacity_{j}"
        )
    
    # Minimum Attendance Constraint
    for j in stadium_range:
        mdl.add_constraint(
            mdl.sum(x[i] for i in game_range) * stadium_attendance[stadium_ids[j]] >= stadium_attendance[stadium_ids[j]],
            ctname=f"min_attendance_{j}"
        )
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in game_range:
            value = solution.get_value(x[i])
            if value > 1e-6:
                print(f"Game {game_ids[i]} is scheduled: {value:.3f}")
        for j in stadium_range:
            value = solution.get_value(y[j])
            print(f"Stadium {stadium_ids[j]} usage percentage: {value:.3f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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