#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Wedding Optimization Problem
"""

import gurobipy as gp
from gurobipy import GRB

def wedding_optimization():
    """Optimize the number of weddings at each church to minimize total cost."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("wedding_optimization")
    
    # Data from the problem
    churches = [1, 2, 3]
    years = [2023, 2024]
    
    # Cost per wedding at each church and year
    cost_per_wedding = {
        (1, 2023): 5000.0,
        (2, 2023): 4500.0,
        (3, 2023): 6000.0,
        (1, 2024): 5200.0,
        (2, 2024): 4600.0,
        (3, 2024): 6100.0
    }
    
    # Maximum number of weddings per year
    max_weddings_per_year = 120
    
    # Maximum number of weddings per church per year
    max_weddings_per_church = 30
    
    # CRITICAL: Validate data consistency
    assert len(churches) == 3, "Expected 3 churches"
    assert len(years) == 2, "Expected 2 years"
    assert len(cost_per_wedding) == 6, "Expected 6 cost entries"
    
    # 2. VARIABLES
    # Decision variables: number of weddings at each church each year
    x = model.addVars(churches, years, vtype=GRB.INTEGER, name="x", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    # Minimize the total cost of weddings
    model.setObjective(
        gp.quicksum(cost_per_wedding[c, y] * x[c, y] for c in churches for y in years),
        GRB.MINIMIZE
    )
    
    # 4. CONSTRAINTS
    
    # Annual Wedding Limit
    for y in years:
        model.addConstr(
            gp.quicksum(x[c, y] for c in churches) <= max_weddings_per_year,
            name=f"annual_limit_{y}"
        )
    
    # Church Capacity Limit
    for c in churches:
        for y in years:
            model.addConstr(
                x[c, y] <= max_weddings_per_church,
                name=f"church_capacity_{c}_{y}"
            )
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for c in churches:
            for y in years:
                if x[c, y].x > 1e-6:
                    print(f"Weddings at church {c} in year {y}: {x[c, y].x:.0f}")
    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__":
    wedding_optimization()