#!/usr/bin/env python3
"""
Gurobipy Implementation for Trust-Weighted Review Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def optimize_trust_weights():
    """Optimize trust weights for reviews to maximize trust-weighted ratings"""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("trust_weight_optimization")
    
    # Data from the problem
    ratings = [4.5, 3.8, 5.0, 3.0, 4.0]  # From review.rating table
    trust_levels = [0.6, 0.8, 1.0, 0.7, 0.7]  # From trust.trust table
    
    # Number of reviews
    n_reviews = len(ratings)
    
    # CRITICAL: Validate array lengths before loops
    assert len(ratings) == len(trust_levels) == n_reviews, "Array length mismatch"
    
    # 2. VARIABLES
    # Trust weights for each review
    w = {i: model.addVar(vtype=GRB.CONTINUOUS, name=f"w_{i}", lb=0) 
         for i in range(n_reviews)}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the sum of trust-weighted ratings
    model.setObjective(gp.quicksum(ratings[i] * w[i] for i in range(n_reviews)), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    # Pattern A: Trust weight upper bounds
    for i in range(n_reviews):
        model.addConstr(w[i] <= trust_levels[i], name=f"trust_bound_{i}")
    
    # Pattern B: Non-negative trust weights (already handled by lb=0 in variable definition)
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    # Handle solution status
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in range(n_reviews):
            print(f"w[{i}] = {w[i].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

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