# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_candidate_poll():
    """Optimize the allocation of resources to maximize the overall support rate for a candidate."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="candidate_poll_optimization")
    
    # Data from the database
    poll_source_ids = [1, 2, 3]
    support_rates = [0.3, 0.4, 0.5]
    conversion_rates = [0.05, 0.07, 0.1]
    
    # Business configuration parameters
    total_budget = 100000
    min_investment = 1000
    max_support_rate = 0.8
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(poll_source_ids) == len(support_rates) == len(conversion_rates), "Array length mismatch"
    safe_range = range(min(len(poll_source_ids), len(support_rates), len(conversion_rates)))  # Safe indexing
    
    # 2. VARIABLES
    # Decision variables: amount of money invested in each poll source
    investments = {i: mdl.continuous_var(name=f"x_{i}", lb=min_investment) for i in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total support rate across all poll sources
    objective = mdl.sum(support_rates[i] + conversion_rates[i] * investments[i] for i in safe_range)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Budget Constraint: Total investment must not exceed the campaign’s budget
    total_investment = mdl.sum(investments[i] for i in safe_range)
    mdl.add_constraint(total_investment <= total_budget, ctname="budget_constraint")
    
    # Maximum Support Rate Constraint: Combined effect must not exceed 80% for each poll source
    for i in safe_range:
        mdl.add_constraint(support_rates[i] + conversion_rates[i] * investments[i] <= max_support_rate, ctname=f"max_support_rate_{i}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            value = solution.get_value(investments[i])
            print(f"Investment in poll source {poll_source_ids[i]}: ${value:.2f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
        if mdl.solve_details.status == "infeasible":
            print("The problem is infeasible. Please check the constraints.")
        elif mdl.solve_details.status == "unbounded":
            print("The problem is unbounded. Please check the objective function.")
    
    return mdl

# Execute the optimization
optimize_candidate_poll()