id, trackingCode: $delivery->tracking_code, status: $delivery->status, riderLocation: $riderLocation, pickupLatitude: (float) $delivery->pickup_latitude, pickupLongitude: (float) $delivery->pickup_longitude, dropLatitude: (float) $delivery->drop_latitude, dropLongitude: (float) $delivery->drop_longitude, pickupAddress: $delivery->pickup_address, dropAddress: $delivery->drop_address, eta: $firebaseData['eta'] ?? null, remainingDistance: $firebaseData['remaining_distance'] ?? null, routePolyline: $firebaseData['route']['polyline'] ?? $delivery->route_polyline, riderInfo: $delivery->rider ? [ 'id' => $delivery->rider->id, 'name' => $delivery->rider->full_name, 'phone' => $delivery->rider->phone, 'photo' => $delivery->rider->photo_url, 'rating' => $delivery->rider->rating, 'vehicle_type' => $delivery->rider->vehicle_type, ] : null, timeline: $delivery->statusHistory?->map(fn ($h) => [ 'status' => $h->to_status, 'timestamp' => $h->changed_at->toIso8601String(), 'label' => DeliveryStatus::from($h->to_status)->label(), ])->toArray(), ); } /** * Convert to array. */ public function toArray(): array { return [ 'delivery_id' => $this->deliveryId, 'tracking_code' => $this->trackingCode, 'status' => $this->status->value, 'status_label' => $this->status->label(), 'status_description' => $this->status->description(), 'status_color' => $this->status->color(), 'rider_location' => $this->riderLocation?->toArray(), 'pickup' => [ 'latitude' => $this->pickupLatitude, 'longitude' => $this->pickupLongitude, 'address' => $this->pickupAddress, ], 'drop' => [ 'latitude' => $this->dropLatitude, 'longitude' => $this->dropLongitude, 'address' => $this->dropAddress, ], 'eta' => $this->eta, 'eta_formatted' => $this->eta ? $this->formatEta($this->eta) : null, 'remaining_distance' => $this->remainingDistance, 'remaining_distance_formatted' => $this->remainingDistance ? round($this->remainingDistance, 1).' km' : null, 'route_polyline' => $this->routePolyline, 'rider' => $this->riderInfo, 'timeline' => $this->timeline, ]; } /** * Format ETA in human-readable format. */ protected function formatEta(int $minutes): string { if ($minutes < 60) { return "{$minutes} min"; } $hours = floor($minutes / 60); $mins = $minutes % 60; if ($mins === 0) { return "{$hours} hr"; } return "{$hours} hr {$mins} min"; } }