#!/usr/bin/env python3
"""
DOCplex implementation for journal committee assignment problem
"""

from docplex.mp.model import Model

def journal_committee_optimization():
    """Optimize journal assignments to maximize sales while respecting editor workloads."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="journal_committee")
    
    # Data from the problem
    journal_sales = [1200.0, 1800.0, 900.0]
    editor_workloads = [4, 3, 5]
    
    # Number of journals and editors
    n_journals = len(journal_sales)
    n_editors = len(editor_workloads)
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert n_journals > 0 and n_editors > 0, "Array length mismatch or empty arrays"
    
    # Safe indexing range
    safe_journals = range(n_journals)
    safe_editors = range(n_editors)
    
    # 2. VARIABLES
    # Binary decision variables: x_ej = 1 if editor e is assigned to journal j
    x = {(e, j): mdl.binary_var(name=f"x_{e}_{j}") for e in safe_editors for j in safe_journals}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total sales: sum(Sales_j * x_ej) for all e, j
    total_sales = mdl.sum(journal_sales[j] * x[e, j] for e in safe_editors for j in safe_journals)
    mdl.maximize(total_sales)
    
    # 4. CONSTRAINTS
    
    # Constraint 1: Editor workload limit
    for e in safe_editors:
        workload = mdl.sum(x[e, j] for j in safe_journals)
        mdl.add_constraint(workload <= editor_workloads[e], ctname=f"workload_{e}")
    
    # Constraint 2: Each journal must have at least one editor
    for j in safe_journals:
        assignment = mdl.sum(x[e, j] for e in safe_editors)
        mdl.add_constraint(assignment >= 1, ctname=f"assignment_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for e in safe_editors:
            for j in safe_journals:
                if solution.get_value(x[e, j]) > 0.5:  # Check if assigned
                    print(f"Editor {e} assigned to Journal {j}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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