from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from typing import Optional

from core.database import get_db
from ..models import Airport, Route
from ..schemas.network import NetworkResponse, NetworkNode, NetworkEdge

router = APIRouter(prefix="/api/network", tags=["network"])


@router.get("/", response_model=NetworkResponse)
def get_network(
    min_flights: int = Query(default=500, ge=0),
    min_airport_flights: int = Query(default=10000, ge=0),
    delay_risk: Optional[str] = Query(default=None),
    db: Session = Depends(get_db),
):
    """Returns nodes + edges for the D3 network graph."""
    route_query = db.query(Route).filter(Route.flight_count >= min_flights)
    if delay_risk:
        levels = [r.strip() for r in delay_risk.split(",")]
        route_query = route_query.filter(Route.delay_risk.in_(levels))
    routes = route_query.all()

    # grab airport codes that appear in our filtered routes
    airport_codes = set()
    for r in routes:
        airport_codes.add(r.origin)
        airport_codes.add(r.dest)

    airports = []
    if airport_codes:
        airports = (
            db.query(Airport)
            .filter(Airport.iata.in_(airport_codes))
            .filter(Airport.total_flights >= min_airport_flights)
            .filter(Airport.lat.isnot(None))
            .all()
        )

    # drop routes where one side got filtered out
    valid = {a.iata for a in airports}
    filtered = [r for r in routes if r.origin in valid and r.dest in valid]

    nodes = [
        NetworkNode(
            id=a.iata, name=a.name, lat=a.lat, lon=a.lon,
            total_flights=a.total_flights or 0,
            avg_delay=a.avg_arr_delay, pct_delayed=a.pct_delayed,
            delay_score=a.delay_score,
            recovery_score=a.recovery_score,
        )
        for a in airports
    ]
    edges = [
        NetworkEdge(
            source=r.origin, target=r.dest,
            flight_count=r.flight_count or 0,
            avg_delay=r.avg_delay, pct_delayed=r.pct_delayed,
            delay_risk=r.delay_risk or "low",
        )
        for r in filtered
    ]

    return NetworkResponse(
        nodes=nodes, edges=edges,
        meta={
            "node_count": len(nodes),
            "edge_count": len(edges),
            "filters": {
                "min_flights": min_flights,
                "min_airport_flights": min_airport_flights,
                "delay_risk": delay_risk,
            },
        },
    )
