#!/usr/bin/env python3
"""
Gurobipy Implementation for Flight Scheduling Optimization Problem
"""

import gurobipy as gp
from gurobipy import GRB

def flight_scheduling_optimization():
    # 1. MODEL & DATA SETUP
    model = gp.Model("flight_scheduling")
    
    # Example data (replace with actual data loading from database)
    flights = [1, 2, 3]
    airports = [1, 2, 3]
    companies = [1, 2, 3]
    
    fuel_coefficients = {1: 0.5, 2: 0.6, 3: 0.7}
    airport_capacities = {1: 10, 2: 15, 3: 20}
    company_capacities = {1: 5, 2: 10, 3: 15}
    
    # CRITICAL: Validate array lengths before loops
    assert len(flights) == len(fuel_coefficients), "Flight data length mismatch"
    assert len(airports) == len(airport_capacities), "Airport data length mismatch"
    assert len(companies) == len(company_capacities), "Company data length mismatch"
    
    # 2. VARIABLES
    # Binary decision variable: x[f, a, c] = 1 if flight f is assigned to airport a and company c
    x = model.addVars(flights, airports, companies, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    # Minimize total fuel consumption
    model.setObjective(gp.quicksum(fuel_coefficients[f] * x[f, a, c] for f in flights for a in airports for c in companies), GRB.MINIMIZE)
    
    # 4. CONSTRAINTS
    
    # Flight Assignment Constraint: Each flight must be assigned to exactly one airport and one company
    for f in flights:
        model.addConstr(gp.quicksum(x[f, a, c] for a in airports for c in companies) == 1, name=f"flight_assignment_{f}")
    
    # Airport Capacity Constraint: Total flights assigned to an airport cannot exceed its capacity
    for a in airports:
        model.addConstr(gp.quicksum(x[f, a, c] for f in flights for c in companies) <= airport_capacities[a], name=f"airport_capacity_{a}")
    
    # Company Capacity Constraint: Total flights assigned to a company cannot exceed its capacity
    for c in companies:
        model.addConstr(gp.quicksum(x[f, a, c] for f in flights for a in airports) <= company_capacities[c], name=f"company_capacity_{c}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for f in flights:
            for a in airports:
                for c in companies:
                    if x[f, a, c].x > 0.5:
                        print(f"Flight {f} assigned to Airport {a} and Company {c}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
if __name__ == "__main__":
    flight_scheduling_optimization()