# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def product_catalog_optimization():
    # Exchange rates
    r_de = 0.85  # Exchange rate from dollars to euros
    r_dp = 0.75  # Exchange rate from dollars to pounds

    # Data setup
    prices_dollars = [12.99, 18.49, 25.0]
    prices_euros = [11.04, 15.72, 21.25]
    prices_pounds = [9.74, 13.87, 18.75]
    min_prices_dollars = [11.99, 16.99, 22.5]
    min_prices_euros = [10.19, 14.44, 19.13]
    min_prices_pounds = [8.99, 12.74, 16.88]
    sales_volumes = [120, 180, 90]
    stock_available = [150, 200, 100]

    # Validate array lengths
    n_products = len(prices_dollars)
    assert len(prices_euros) == len(prices_pounds) == len(min_prices_dollars) == n_products
    assert len(min_prices_euros) == len(min_prices_pounds) == len(sales_volumes) == n_products
    assert len(stock_available) == n_products, "Array length mismatch"

    # Model setup
    model = gp.Model("product_catalog")

    # Variables
    p_d = model.addVars(n_products, vtype=GRB.CONTINUOUS, name="p_d", lb=0)
    p_e = model.addVars(n_products, vtype=GRB.CONTINUOUS, name="p_e", lb=0)
    p_p = model.addVars(n_products, vtype=GRB.CONTINUOUS, name="p_p", lb=0)

    # Objective function: Maximize total revenue
    model.setObjective(
        gp.quicksum(
            (p_d[i] * sales_volumes[i] + p_e[i] * sales_volumes[i] / r_de + p_p[i] * sales_volumes[i] / r_dp)
            for i in range(n_products)
        ),
        GRB.MAXIMIZE
    )

    # Constraints
    for i in range(n_products):
        # Minimum price constraints
        model.addConstr(p_d[i] >= min_prices_dollars[i], name=f"min_price_dollars_{i}")
        model.addConstr(p_e[i] >= min_prices_euros[i], name=f"min_price_euros_{i}")
        model.addConstr(p_p[i] >= min_prices_pounds[i], name=f"min_price_pounds_{i}")

        # Stock availability constraints
        model.addConstr(sales_volumes[i] <= stock_available[i], name=f"stock_availability_{i}")

        # Price consistency constraints
        model.addConstr(p_e[i] == p_d[i] * r_de, name=f"price_consistency_euros_{i}")
        model.addConstr(p_p[i] == p_d[i] * r_dp, name=f"price_consistency_pounds_{i}")

    # Solve the model
    model.optimize()

    # Output results
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in range(n_products):
            print(f"Product {i+1}: Price in dollars = {p_d[i].x:.2f}, Price in euros = {p_e[i].x:.2f}, Price in pounds = {p_p[i].x:.2f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

# Run the optimization
product_catalog_optimization()