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

from docplex.mp.model import Model

def optimize_medicine_selection():
    """Optimize medicine selection for clinical trial"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="medicine_enzyme_interaction")
    
    # Data from the problem statement
    medicine_ids = [1, 2, 3]
    effectiveness_scores = [0.85, 0.75, 0.9]
    adverse_interaction_scores = [0.15, 0.25, 0.1]
    fda_approved = [True, False, True]
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(medicine_ids) == len(effectiveness_scores) == len(adverse_interaction_scores) == len(fda_approved), "Array length mismatch"
    safe_range = range(min(len(medicine_ids), len(effectiveness_scores), len(adverse_interaction_scores), len(fda_approved)))  # Safe indexing
    
    # 2. VARIABLES
    # Binary decision variables for medicine selection
    x = {i: mdl.binary_var(name=f"x_{medicine_ids[i]}") for i in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total effectiveness score
    objective = mdl.sum(effectiveness_scores[i] * x[i] for i in safe_range)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Constraint 1: Adverse Interaction Limit
    adverse_interaction_limit = mdl.sum(adverse_interaction_scores[i] * x[i] for i in safe_range)
    mdl.add_constraint(adverse_interaction_limit <= 0.5, ctname="adverse_interaction_limit")
    
    # Constraint 2: Medicine Count Limit
    medicine_count_limit = mdl.sum(x[i] for i in safe_range)
    mdl.add_constraint(medicine_count_limit <= 3, ctname="medicine_count_limit")
    
    # Constraint 3: FDA Approval Requirement
    for i in safe_range:
        if not fda_approved[i]:
            mdl.add_constraint(x[i] == 0, ctname=f"fda_approval_{medicine_ids[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(x[i])
            if value > 1e-6:
                print(f"Medicine {medicine_ids[i]} selected: {value:.0f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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