prepare( "SELECT t.id, t.status, t.started_at, t.completed_at, t.delay_minutes, t.current_stop_seq, r.name_ar AS route_name, sc.departure_time, v.plate AS vehicle_plate, d.name AS driver_name, d.phone AS driver_phone FROM transit_trips t JOIN transit_routes r ON r.id = t.route_id JOIN transit_schedules sc ON sc.id = t.schedule_id JOIN transit_vehicles v ON v.id = t.vehicle_id JOIN transit_drivers d ON d.id = t.driver_id WHERE t.org_id = ? AND t.trip_date = ? ORDER BY sc.departure_time ASC" ); $stTrips->execute([$transit_org_id, $today]); $trips = $stTrips->fetchAll(); foreach ($trips as &$trip) { $trip['live_position'] = null; if ($trip['status'] === 'started') { $pos = transitGetBusPosition((int)$trip['id']); if ($pos) $trip['live_position'] = ['lat' => (float)$pos['lat'], 'lng' => (float)$pos['lng'], 'ts' => (int)$pos['ts']]; } } unset($trip); $stStats = $transit_con->prepare( "SELECT COUNT(*) total_trips, SUM(status='started') active_now, SUM(status='completed') completed_today, SUM(status='no_show') no_show_today FROM transit_trips WHERE org_id=? AND trip_date=?" ); $stStats->execute([$transit_org_id, $today]); $stats = $stStats->fetch(); $stMembers = $transit_con->prepare( "SELECT COUNT(*) active_members FROM transit_enrollments WHERE org_id=? AND status='active'" ); $stMembers->execute([$transit_org_id]); $stBc = $transit_con->prepare( "SELECT id, title_ar, body_ar, sent_at, target_type FROM transit_broadcasts WHERE org_id=? ORDER BY created_at DESC LIMIT 5" ); $stBc->execute([$transit_org_id]); jsonSuccess([ 'date' => $today, 'trips' => $trips, 'stats' => [ 'total_trips' => (int)$stats['total_trips'], 'active_now' => (int)$stats['active_now'], 'completed_today' => (int)$stats['completed_today'], 'no_show_today' => (int)$stats['no_show_today'], 'active_members' => (int)$stMembers->fetchColumn(), ], 'recent_broadcasts' => $stBc->fetchAll(), ]);