#!/usr/bin/env python3
"""
DOCPLEX implementation for phone stock allocation optimization
"""

from docplex.mp.model import Model

def phone_stock_allocation():
    """Optimize phone stock allocation across markets to maximize revenue"""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="phone_stock_allocation")
    
    # Data from the problem
    phone_ids = [1, 2, 3]
    market_ids = [1, 2, 3]
    
    # Prices for each phone model
    prices = {1: 699.99, 2: 899.99, 3: 999.99}
    
    # Maximum capacities for each market
    max_capacities = {1: 1000, 2: 1500, 3: 2000}
    
    # Minimum stock requirements for each phone in each market
    min_stocks = {
        (1, 1): 50,
        (2, 2): 100,
        (3, 3): 150
    }
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(phone_ids) == len(prices), "Phone IDs and prices length mismatch"
    assert len(market_ids) == len(max_capacities), "Market IDs and capacities length mismatch"
    
    # 2. VARIABLES
    # Decision variables: x[i,j] = number of units of phone i allocated to market j
    x = {(i, j): mdl.integer_var(name=f"x_{i}_{j}", lb=0) for i in phone_ids for j in market_ids}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total revenue
    revenue = mdl.sum(prices[i] * x[i, j] for i in phone_ids for j in market_ids)
    mdl.maximize(revenue)
    
    # 4. CONSTRAINTS
    
    # Market Capacity Constraint
    for j in market_ids:
        total_allocation = mdl.sum(x[i, j] for i in phone_ids)
        mdl.add_constraint(total_allocation <= max_capacities[j], ctname=f"market_capacity_{j}")
    
    # Minimum Stock Requirement Constraint
    for (i, j), min_stock in min_stocks.items():
        mdl.add_constraint(x[i, j] >= min_stock, ctname=f"min_stock_{i}_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for (i, j), var in x.items():
            value = solution.get_value(var)
            if value > 1e-6:
                print(f"x[{i},{j}] = {value}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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