# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def sports_competition_optimization():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="sports_competition_optimization")
    
    # Data from the database schema
    clubs = [1, 2, 3]
    players = [1, 2, 3]
    
    # Club constraints
    club_constraints = {
        1: {'max_players': 25, 'min_players': 18, 'budget': 1500000},
        2: {'max_players': 30, 'min_players': 20, 'budget': 2000000},
        3: {'max_players': 22, 'min_players': 15, 'budget': 1000000}
    }
    
    # Player salaries
    player_salaries = {
        1: 75000,
        2: 100000,
        3: 50000
    }
    
    # Player points
    player_points = {
        (1, 1): 15,
        (2, 2): 20,
        (3, 3): 10
    }
    
    # Validate array lengths
    assert len(player_points) == len(players) * len(clubs), "Player points length mismatch"
    
    # 2. VARIABLES
    # Binary decision variable indicating whether player p is assigned to club c
    x = {(p, c): mdl.binary_var(name=f"x_{p}_{c}") for p in players for c in clubs}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total points scored across all clubs
    objective = mdl.sum(player_points[(p, c)] * x[(p, c)] for p in players for c in clubs)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Maximum Players per Club
    for c in clubs:
        mdl.add_constraint(mdl.sum(x[(p, c)] for p in players) <= club_constraints[c]['max_players'], ctname=f"max_players_{c}")
    
    # Minimum Players per Club
    for c in clubs:
        mdl.add_constraint(mdl.sum(x[(p, c)] for p in players) >= club_constraints[c]['min_players'], ctname=f"min_players_{c}")
    
    # Budget Limit
    for c in clubs:
        mdl.add_constraint(mdl.sum(player_salaries[p] * x[(p, c)] for p in players) <= club_constraints[c]['budget'], ctname=f"budget_{c}")
    
    # Player Assignment
    for p in players:
        mdl.add_constraint(mdl.sum(x[(p, c)] for c in clubs) <= 1, ctname=f"player_assignment_{p}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for p in players:
            for c in clubs:
                if solution.get_value(x[(p, c)]) > 0.5:
                    print(f"Player {p} is assigned to Club {c}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the optimization
sports_competition_optimization()