#!/usr/bin/env python3
"""
DOCplex implementation for Real Estate Properties Optimization Problem
"""

from docplex.mp.model import Model

def real_estate_optimization():
    """Optimize the agreed selling price for real estate properties to maximize total revenue."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="real_estate_properties")
    
    # Data from the problem
    property_ids = [1, 2, 3]
    vendor_prices = {1: 300000.0, 2: 450000.0, 3: 240000.0}
    buyer_prices = {1: 340000.0, 2: 500000.0, 3: 280000.0}
    feature_scores = {
        1: [0.15, 0.1],  # Pool and Garage for property 1
        2: [0.2],        # Garden for property 2
        3: [0.1]         # Garage for property 3
    }
    weighting_factor = 0.3
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(property_ids) == len(vendor_prices) == len(buyer_prices) == len(feature_scores), "Array length mismatch"
    
    # 2. VARIABLES
    # Decision variable: agreed_selling_price for each property
    x = {i: mdl.continuous_var(name=f"x_{i}", lb=0) for i in property_ids}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total revenue
    objective = mdl.sum(x[i] for i in property_ids)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    # Vendor's Minimum Price Constraint
    for i in property_ids:
        mdl.add_constraint(x[i] >= vendor_prices[i], ctname=f"vendor_min_{i}")
    
    # Buyer's Maximum Price Constraint
    for i in property_ids:
        mdl.add_constraint(x[i] <= buyer_prices[i], ctname=f"buyer_max_{i}")
    
    # Feature-Adjusted Price Constraint
    for i in property_ids:
        sum_feature_scores = sum(feature_scores[i])
        adjusted_price = vendor_prices[i] * (1 + weighting_factor * sum_feature_scores)
        mdl.add_constraint(x[i] >= adjusted_price, ctname=f"feature_adjusted_{i}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in property_ids:
            value = solution.get_value(x[i])
            print(f"Agreed selling price for property {i}: {value:.2f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

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