#!/usr/bin/env python3
"""
DOCplex implementation for news agency journalist assignment optimization
"""

from docplex.mp.model import Model

def optimize_journalist_assignments():
    """Optimize journalist assignments to maximize coverage quality"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="news_report_optimization")
    
    # Journalist data
    journalists = [
        {"Years_working": 5, "max_assignments": 3},
        {"Years_working": 10, "max_assignments": 4},
        {"Years_working": 15, "max_assignments": 5}
    ]
    
    # Event data
    events = [
        {"Event_Attendance": 100},
        {"Event_Attendance": 200},
        {"Event_Attendance": 300}
    ]
    
    # CRITICAL: Validate array lengths
    n_journalists = len(journalists)
    n_events = len(events)
    assert n_journalists > 0 and n_events > 0, "Empty data arrays"
    
    # Safe indexing range
    safe_journalists = range(n_journalists)
    safe_events = range(n_events)
    
    # 2. VARIABLES
    # Binary decision variables: x[i][j] = 1 if journalist i is assigned to event j
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") 
         for i in safe_journalists for j in safe_events}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total coverage quality
    coverage_quality = mdl.sum(
        journalists[i]["Years_working"] * events[j]["Event_Attendance"] * x[(i, j)]
        for i in safe_journalists for j in safe_events
    )
    mdl.maximize(coverage_quality)
    
    # 4. CONSTRAINTS
    
    # Event Coverage Requirement: Each event must be covered by at least one journalist
    for j in safe_events:
        mdl.add_constraint(
            mdl.sum(x[(i, j)] for i in safe_journalists) >= 1,
            ctname=f"event_coverage_{j}"
        )
    
    # Journalist Assignment Limit: No journalist can be assigned to more than max_assignments
    for i in safe_journalists:
        mdl.add_constraint(
            mdl.sum(x[(i, j)] for j in safe_events) <= journalists[i]["max_assignments"],
            ctname=f"journalist_limit_{i}"
        )
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_journalists:
            for j in safe_events:
                if solution.get_value(x[(i, j)]) > 0.5:  # Binary variable threshold
                    print(f"Journalist {i} assigned to Event {j}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Run the optimization
if __name__ == "__main__":
    optimize_journalist_assignments()