#!/usr/bin/env python3
"""
DOCplex implementation for store product allocation optimization
"""

from docplex.mp.model import Model

def store_product_allocation():
    """Optimize product allocation across stores to maximize sales revenue"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="store_product_allocation")
    
    # Sample data from the problem description
    sales_potential = {
        (1, 101): 50.0,
        (1, 102): 75.0,
        (1, 103): 100.0
    }
    
    product_availability = {
        101: 500,
        102: 750,
        103: 1000
    }
    
    store_capacity = {
        1: 1000,
        2: 1500,
        3: 2000
    }
    
    # Extract unique store and product IDs
    stores = set(s for s, _ in sales_potential.keys())
    products = set(p for _, p in sales_potential.keys())
    
    # Business configuration
    min_allocation = 10
    max_allocation = 100
    
    # 2. VARIABLES
    x = {(s, p): mdl.integer_var(name=f"x_{s}_{p}", lb=min_allocation, ub=max_allocation) 
         for s in stores for p in products}
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(sales_potential.get((s, p), 0) * x[s, p] 
                        for s in stores for p in products)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Store Capacity Constraint
    for s in stores:
        total_units = mdl.sum(x[s, p] for p in products)
        mdl.add_constraint(total_units <= store_capacity.get(s, 0), 
                          ctname=f"store_capacity_{s}")
    
    # Product Availability Constraint
    for p in products:
        total_units = mdl.sum(x[s, p] for s in stores)
        mdl.add_constraint(total_units <= product_availability.get(p, 0), 
                          ctname=f"product_availability_{p}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for (s, p), var in x.items():
            value = solution.get_value(var)
            if value > 1e-6:
                print(f"Allocation for store {s}, product {p}: {value:.0f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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