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

from docplex.mp.model import Model

def employee_hire_optimization():
    """Optimize employee hiring to minimize total costs"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="employee_hire_optimization")
    
    # Data from the problem statement
    shop_ids = [1, 2, 3]
    cost_full_time = {1: 1500, 2: 1600, 3: 1700}
    cost_part_time = {1: 800, 2: 850, 3: 900}
    min_staff = {1: 5, 2: 6, 3: 7}
    max_full_time = {1: 10, 2: 12, 3: 15}
    max_part_time = {1: 8, 2: 10, 3: 12}
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(shop_ids) == len(cost_full_time) == len(cost_part_time) == len(min_staff) == len(max_full_time) == len(max_part_time), "Array length mismatch"
    safe_range = range(min(len(shop_ids), len(cost_full_time), len(cost_part_time), len(min_staff), len(max_full_time), len(max_part_time)))  # Safe indexing
    
    # 2. VARIABLES
    x_full_time = {i: mdl.integer_var(name=f"x_full_time_{i}", lb=0) for i in safe_range}
    x_part_time = {i: mdl.integer_var(name=f"x_part_time_{i}", lb=0) for i in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(cost_full_time[shop_ids[i]] * x_full_time[i] + cost_part_time[shop_ids[i]] * x_part_time[i] for i in safe_range)
    mdl.minimize(objective)
    
    # 4. CONSTRAINTS
    # Pattern A: Minimum Staffing Requirement
    for i in safe_range:
        mdl.add_constraint(x_full_time[i] + x_part_time[i] >= min_staff[shop_ids[i]], ctname=f"min_staff_{shop_ids[i]}")
    
    # Pattern B: Maximum Full-Time Employees
    for i in safe_range:
        mdl.add_constraint(x_full_time[i] <= max_full_time[shop_ids[i]], ctname=f"max_full_time_{shop_ids[i]}")
    
    # Pattern C: Maximum Part-Time Employees
    for i in safe_range:
        mdl.add_constraint(x_part_time[i] <= max_part_time[shop_ids[i]], ctname=f"max_part_time_{shop_ids[i]}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            print(f"Shop {shop_ids[i]}: Full-time = {solution.get_value(x_full_time[i])}, Part-time = {solution.get_value(x_part_time[i])}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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