# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def sports_competition_optimization():
    # 1. MODEL & DATA SETUP
    model = gp.Model("sports_competition")

    # 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 before loops
    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 = model.addVars(players, clubs, vtype=GRB.BINARY, name="x")

    # 3. OBJECTIVE FUNCTION
    # Maximize the total points scored across all clubs
    model.setObjective(gp.quicksum(player_points[p, c] * x[p, c] for p in players for c in clubs), GRB.MAXIMIZE)

    # 4. CONSTRAINTS

    # Maximum Players per Club
    for c in clubs:
        model.addConstr(gp.quicksum(x[p, c] for p in players) <= club_constraints[c]['max_players'], name=f"max_players_{c}")

    # Minimum Players per Club
    for c in clubs:
        model.addConstr(gp.quicksum(x[p, c] for p in players) >= club_constraints[c]['min_players'], name=f"min_players_{c}")

    # Budget Limit
    for c in clubs:
        model.addConstr(gp.quicksum(player_salaries[p] * x[p, c] for p in players) <= club_constraints[c]['budget'], name=f"budget_{c}")

    # Player Assignment
    for p in players:
        model.addConstr(gp.quicksum(x[p, c] for c in clubs) <= 1, name=f"player_assignment_{p}")

    # 5. SOLVING & RESULTS
    model.optimize()

    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for p in players:
            for c in clubs:
                if x[p, c].x > 1e-6:
                    print(f"Player {p} assigned to Club {c}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

    return model

# Execute the optimization
sports_competition_optimization()