#!/usr/bin/env python3
"""
DOCPLEX implementation for poker player selection optimization problem
"""

from docplex.mp.model import Model

def poker_player_selection():
    """Optimize poker player selection to maximize earnings with constraints"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="poker_player_selection")
    
    # Data from poker_player table
    earnings = [1200.0, 1500.0, 2000.0, 1000.0, 1800.0]
    money_ranks = [45, 55, 60, 50, 58]
    nationalities = ['USA', 'Canada', 'UK', 'Australia', 'Germany']
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(earnings) == len(money_ranks) == len(nationalities), "Array length mismatch"
    safe_range = range(min(len(earnings), len(money_ranks), len(nationalities)))  # Safe indexing
    
    # 2. VARIABLES
    # Decision variables for player selection
    x = {i: mdl.binary_var(name=f"x_{i}") for i in safe_range}
    
    # Auxiliary variables for nationality diversity
    y = {j: mdl.binary_var(name=f"y_{j}") for j in set(nationalities)}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total earnings of selected players
    objective = mdl.sum(earnings[i] * x[i] for i in safe_range)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Nationality Diversity Constraint
    # Ensure at least three different nationalities are represented
    for i in safe_range:
        mdl.add_constraint(y[nationalities[i]] <= x[i], ctname=f"nationality_{i}")
    mdl.add_constraint(mdl.sum(y[j] for j in set(nationalities)) >= 3, ctname="min_nationalities")
    
    # Money Rank Constraint
    # No more than 20% of selected players can have a money rank below 50
    S = mdl.sum(x[i] for i in safe_range)
    L = mdl.sum(x[i] for i in safe_range if money_ranks[i] < 50)
    mdl.add_constraint(L <= 0.2 * S, ctname="money_rank_limit")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            if solution.get_value(x[i]) > 0.5:
                print(f"Player {i+1} selected: Earnings={earnings[i]}, Money Rank={money_ranks[i]}, Nationality={nationalities[i]}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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