#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Employee Hiring Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def employee_hire_optimization():
    """Optimize employee hiring to minimize total hiring costs."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("employee_hire_evaluation")
    
    # Data from the problem
    shops = [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 before loops
    assert len(shops) == len(cost_full_time) == len(cost_part_time) == len(min_staff) == len(max_full_time) == len(max_part_time), "Array length mismatch"
    
    # 2. VARIABLES
    x_full_time = {i: model.addVar(vtype=GRB.INTEGER, name=f"x_full_time_{i}", lb=0) for i in shops}
    x_part_time = {i: model.addVar(vtype=GRB.INTEGER, name=f"x_part_time_{i}", lb=0) for i in shops}
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(
        gp.quicksum(cost_full_time[i] * x_full_time[i] + cost_part_time[i] * x_part_time[i] for i in shops),
        GRB.MINIMIZE
    )
    
    # 4. CONSTRAINTS
    # Minimum Staffing Requirement
    for i in shops:
        model.addConstr(x_full_time[i] + x_part_time[i] >= min_staff[i], name=f"min_staff_{i}")
    
    # Maximum Full-Time Employees
    for i in shops:
        model.addConstr(x_full_time[i] <= max_full_time[i], name=f"max_full_time_{i}")
    
    # Maximum Part-Time Employees
    for i in shops:
        model.addConstr(x_part_time[i] <= max_part_time[i], name=f"max_part_time_{i}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in shops:
            print(f"Shop {i}: Full-Time Employees = {x_full_time[i].x}, Part-Time Employees = {x_part_time[i].x}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

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