total_rides ?? 0; } /** * Get the percentage of coasters among all rides. */ public function getCoasterPercentageAttribute(): float { if ($this->total_rides === 0) { return 0; } return round(($this->total_coasters / $this->total_rides) * 100, 1); } /** * Get a summary of ride types distribution. * * @return array */ public function getRideDistributionAttribute(): array { return [ 'coasters' => $this->total_coasters ?? 0, 'flat_rides' => $this->total_flat_rides ?? 0, 'water_rides' => $this->total_water_rides ?? 0, ]; } /** * Get a summary of area statistics. * * @return array */ public function getAreaDistributionAttribute(): array { return [ 'total' => $this->total_areas ?? 0, 'operating' => $this->operating_areas ?? 0, 'closed' => $this->closed_areas ?? 0, ]; } /** * Get the formatted daily capacity. */ public function getFormattedDailyCapacityAttribute(): string { if (!$this->total_daily_capacity) { return 'Unknown capacity'; } return number_format($this->total_daily_capacity) . ' riders/day'; } /** * Get the formatted average wait time. */ public function getFormattedWaitTimeAttribute(): string { if (!$this->average_wait_time) { return 'Unknown wait time'; } return $this->average_wait_time . ' minutes'; } /** * Get the rating display with stars. */ public function getRatingDisplayAttribute(): string { if (!$this->average_rating) { return 'Not rated'; } $stars = str_repeat('★', floor($this->average_rating)); $stars .= str_repeat('☆', 5 - floor($this->average_rating)); return $stars . ' (' . number_format($this->average_rating, 1) . ')'; } /** * Get historical statistics summary. * * @return array */ public function getHistoricalStatsAttribute(): array { return [ 'total_operated' => $this->total_rides_operated, 'total_retired' => $this->total_rides_retired, 'last_expansion' => $this->last_expansion_date?->format('M Y') ?? 'Never', 'last_update' => $this->last_major_update?->format('M Y') ?? 'Never', 'retirement_rate' => $this->getRetirementRate(), ]; } /** * Get performance metrics summary. * * @return array */ public function getPerformanceMetricsAttribute(): array { return [ 'utilization' => $this->utilization_rate ? $this->utilization_rate . '%' : 'Unknown', 'peak_attendance' => $this->peak_daily_attendance ? number_format($this->peak_daily_attendance) : 'Unknown', 'satisfaction' => $this->guest_satisfaction ? number_format($this->guest_satisfaction, 1) . '/5.0' : 'Unknown', ]; } /** * Calculate the retirement rate (retired rides as percentage of total operated). */ protected function getRetirementRate(): float { if ($this->total_rides_operated === 0) { return 0; } return round(($this->total_rides_retired / $this->total_rides_operated) * 100, 1); } /** * Update area counts. */ public function updateAreaCounts(): void { $this->update([ 'total_areas' => $this->areas()->count(), 'operating_areas' => $this->areas()->operating()->count(), 'closed_areas' => $this->areas()->whereNotNull('closing_date')->count(), ]); } /** * Update ride statistics. */ public function updateRideStatistics(): void { $areas = $this->areas; $this->update([ 'total_rides' => $areas->sum('ride_count'), 'total_coasters' => $areas->sum('coaster_count'), 'total_flat_rides' => $areas->sum('flat_ride_count'), 'total_water_rides' => $areas->sum('water_ride_count'), 'total_daily_capacity' => $areas->sum('daily_capacity'), ]); } /** * Update visitor statistics. */ public function updateVisitorStats(): void { $areas = $this->areas()->whereNotNull('average_rating'); $this->update([ 'average_wait_time' => $areas->avg('peak_wait_time'), 'average_rating' => $areas->avg('average_rating'), ]); } /** * Record an expansion. */ public function recordExpansion(): void { $this->update(['last_expansion_date' => now()]); } /** * Record a major update. */ public function recordMajorUpdate(): void { $this->update(['last_major_update' => now()]); } /** * Update all statistics. */ public function refreshStatistics(): void { $this->updateAreaCounts(); $this->updateRideStatistics(); $this->updateVisitorStats(); } }