#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Phone Production Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def phone_production_optimization():
    """Optimize phone production to minimize total cost while meeting hardware and accreditation requirements."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("phone_production")
    
    # Chip models data
    chip_models = {
        1: {"cost": 50.0, "RAM_MiB": 2048, "ROM_MiB": 32768},
        2: {"cost": 75.0, "RAM_MiB": 4096, "ROM_MiB": 65536},
        3: {"cost": 100.0, "RAM_MiB": 8192, "ROM_MiB": 131072}
    }
    
    # Screen modes data
    screen_modes = {
        1: {"cost": 30.0, "Accreditation_level": 3},
        2: {"cost": 45.0, "Accreditation_level": 4},
        3: {"cost": 60.0, "Accreditation_level": 5}
    }
    
    # Minimum requirements
    min_RAM = 8000
    min_ROM = 128000
    min_Accreditation = 5
    
    # Validate data lengths
    assert len(chip_models) == 3, "Chip models data length mismatch"
    assert len(screen_modes) == 3, "Screen modes data length mismatch"
    
    # 2. VARIABLES
    x = model.addVars(chip_models.keys(), screen_modes.keys(), vtype=GRB.CONTINUOUS, name="x", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(
        gp.quicksum((chip_models[i]["cost"] + screen_modes[j]["cost"]) * x[i, j] 
                    for i in chip_models.keys() for j in screen_modes.keys()), 
        GRB.MINIMIZE
    )
    
    # 4. CONSTRAINTS
    
    # Total RAM Constraint
    model.addConstr(
        gp.quicksum(chip_models[i]["RAM_MiB"] * x[i, j] 
                    for i in chip_models.keys() for j in screen_modes.keys()) >= min_RAM, 
        name="total_RAM"
    )
    
    # Total ROM Constraint
    model.addConstr(
        gp.quicksum(chip_models[i]["ROM_MiB"] * x[i, j] 
                    for i in chip_models.keys() for j in screen_modes.keys()) >= min_ROM, 
        name="total_ROM"
    )
    
    # Total Accreditation Level Constraint
    model.addConstr(
        gp.quicksum(screen_modes[j]["Accreditation_level"] * x[i, j] 
                    for i in chip_models.keys() for j in screen_modes.keys()) >= min_Accreditation, 
        name="total_Accreditation"
    )
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in chip_models.keys():
            for j in screen_modes.keys():
                if x[i, j].x > 1e-6:
                    print(f"x[{i},{j}] = {x[i, j].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

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