# Complete GUROBIPY implementation

import gurobipy as gp
from gurobipy import GRB

def optimize_store_product_distribution():
    """Optimize product distribution to maximize sales potential across stores."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("store_product")
    
    # Data from the database schema
    product_sales_value = {1: 12.5, 2: 25.0, 3: 18.0}
    product_availability = {1: 60, 2: 80, 3: 70}
    store_capacity = {1: 120, 2: 180, 3: 150}
    
    products = list(product_sales_value.keys())
    stores = list(store_capacity.keys())
    
    # CRITICAL: Validate array lengths before loops
    assert len(product_sales_value) == len(product_availability) == len(products), "Product array length mismatch"
    assert len(store_capacity) == len(stores), "Store array length mismatch"
    
    # 2. VARIABLES
    # Decision variables: units assigned to each product-store pair
    units_assigned = model.addVars(products, stores, vtype=GRB.INTEGER, name="units_assigned", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total sales value
    model.setObjective(
        gp.quicksum(product_sales_value[i] * units_assigned[i, j] for i in products for j in stores),
        GRB.MAXIMIZE
    )
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Product Availability Constraint
    model.addConstrs(
        (gp.quicksum(units_assigned[i, j] for j in stores) <= product_availability[i] for i in products),
        name="product_availability"
    )
    
    # Store Capacity Constraint
    model.addConstrs(
        (gp.quicksum(units_assigned[i, j] for i in products) <= store_capacity[j] for j in stores),
        name="store_capacity"
    )
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in products:
            for j in stores:
                if units_assigned[i, j].x > 1e-6:
                    print(f"units_assigned[{i},{j}] = {units_assigned[i, j].x:.0f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
optimize_store_product_distribution()