# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_customer_complaints():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="customer_complaints_optimization")
    
    # Data from the database
    staff_wages = [
        (1, 25.0),
        (2, 30.0),
        (3, 35.0)
    ]
    
    complaint_time_constraints = [
        (1, 1.0, 3.0),
        (2, 1.5, 4.0),
        (3, 2.0, 5.0)
    ]
    
    staff_working_hours = [
        (1, 40.0),
        (2, 45.0),
        (3, 50.0)
    ]
    
    # Extract unique staff and complaint IDs
    staff_ids = sorted({sw[0] for sw in staff_wages})
    complaint_ids = sorted({ctc[0] for ctc in complaint_time_constraints})
    
    # Create dictionaries for easy access
    hourly_wage = {sw[0]: sw[1] for sw in staff_wages}
    min_time = {ctc[0]: ctc[1] for ctc in complaint_time_constraints}
    max_time = {ctc[0]: ctc[2] for ctc in complaint_time_constraints}
    max_hours = {swh[0]: swh[1] for swh in staff_working_hours}
    
    # 2. VARIABLES
    # Decision variable: time spent by staff member i on complaint j
    x = {(i, j): mdl.continuous_var(name=f"x_{i}_{j}", lb=0) for i in staff_ids for j in complaint_ids}
    
    # 3. OBJECTIVE FUNCTION
    # Minimize the total cost of handling complaints
    total_cost = mdl.sum(hourly_wage[i] * x[i, j] for i in staff_ids for j in complaint_ids)
    mdl.minimize(total_cost)
    
    # 4. CONSTRAINTS
    
    # Complaint Assignment Constraint: Each complaint must be fully assigned
    for j in complaint_ids:
        mdl.add_constraint(mdl.sum(x[i, j] for i in staff_ids) == 1, ctname=f"complaint_assignment_{j}")
    
    # Time Bounds Constraint: Time spent must be within min and max time for each complaint
    for i in staff_ids:
        for j in complaint_ids:
            mdl.add_constraint(x[i, j] >= min_time[j], ctname=f"min_time_{i}_{j}")
            mdl.add_constraint(x[i, j] <= max_time[j], ctname=f"max_time_{i}_{j}")
    
    # Staff Working Hours Constraint: Total time spent by each staff member must not exceed max hours
    for i in staff_ids:
        mdl.add_constraint(mdl.sum(x[i, j] for j in complaint_ids) <= max_hours[i], ctname=f"max_hours_{i}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in staff_ids:
            for j in complaint_ids:
                value = solution.get_value(x[i, j])
                if value > 1e-6:
                    print(f"Time spent by staff {i} on complaint {j}: {value:.3f}")
    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

# Run the optimization
optimize_customer_complaints()