#!/usr/bin/env python3
"""
DOCPLEX Implementation for Product Pricing Optimization
"""

from docplex.mp.model import Model

def optimize_product_pricing():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="product_pricing_optimization")
    
    # Exchange rates and maximum price difference
    usd_to_eur = 0.92
    usd_to_gbp = 0.79
    eur_to_gbp = 0.86
    max_price_diff = 5.0
    
    # Data from the database
    product_ids = [1, 2, 3]
    sales_volumes = [150, 200, 100]
    
    min_price_dollars = [10.0, 15.0, 20.0]
    max_price_dollars = [50.0, 55.0, 60.0]
    
    min_price_euros = [9.0, 14.0, 19.0]
    max_price_euros = [45.0, 50.0, 55.0]
    
    min_price_pounds = [8.0, 13.0, 18.0]
    max_price_pounds = [40.0, 45.0, 50.0]
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(product_ids) == len(sales_volumes) == len(min_price_dollars) == len(max_price_dollars) == len(min_price_euros) == len(max_price_euros) == len(min_price_pounds) == len(max_price_pounds), "Array length mismatch"
    safe_range = range(len(product_ids))  # Safe indexing
    
    # 2. VARIABLES
    p_usd = {i: mdl.continuous_var(name=f"p_usd_{product_ids[i]}", lb=min_price_dollars[i], ub=max_price_dollars[i]) for i in safe_range}
    p_eur = {i: mdl.continuous_var(name=f"p_eur_{product_ids[i]}", lb=min_price_euros[i], ub=max_price_euros[i]) for i in safe_range}
    p_gbp = {i: mdl.continuous_var(name=f"p_gbp_{product_ids[i]}", lb=min_price_pounds[i], ub=max_price_pounds[i]) for i in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    revenue = mdl.sum(sales_volumes[i] * (p_usd[i] + p_eur[i] + p_gbp[i]) for i in safe_range)
    mdl.maximize(revenue)
    
    # 4. CONSTRAINTS
    # Currency Price Differences
    for i in safe_range:
        mdl.add_constraint(mdl.abs(usd_to_eur * p_usd[i] - p_eur[i]) <= max_price_diff, ctname=f"usd_eur_diff_{product_ids[i]}")
        mdl.add_constraint(mdl.abs(usd_to_gbp * p_usd[i] - p_gbp[i]) <= max_price_diff, ctname=f"usd_gbp_diff_{product_ids[i]}")
        mdl.add_constraint(mdl.abs(eur_to_gbp * p_eur[i] - p_gbp[i]) <= max_price_diff, ctname=f"eur_gbp_diff_{product_ids[i]}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            print(f"Product {product_ids[i]}:")
            print(f"  USD Price: {solution.get_value(p_usd[i]):.2f}")
            print(f"  EUR Price: {solution.get_value(p_eur[i]):.2f}")
            print(f"  GBP Price: {solution.get_value(p_gbp[i]):.2f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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