<?php

namespace App\Models;

use App\Enums\RideCategory;
use App\Enums\RideStatus;
use App\Traits\HasSlugHistory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;

class Ride extends Model
{
    use SoftDeletes, HasSlugHistory;

    protected $fillable = [
        'name',
        'slug',
        'description',
        'park_id',
        'park_area_id',
        'manufacturer_id',
        'designer_id',
        'ride_model_id',
        'category',
        'status',
        'post_closing_status',
        'status_since',
        'opening_date',
        'closing_date',
        'min_height_in',
        'max_height_in',
        'capacity_per_hour',
        'ride_duration_seconds',
    ];

    protected $casts = [
        'status' => RideStatus::class,
        'category' => RideCategory::class,
        'opening_date' => 'date',
        'closing_date' => 'date',
        'status_since' => 'date',
        'min_height_in' => 'integer',
        'max_height_in' => 'integer',
        'capacity_per_hour' => 'integer',
        'ride_duration_seconds' => 'integer',
    ];

    // Core Relationships (Django Parity)
    public function park(): BelongsTo
    {
        return $this->belongsTo(Park::class);
    }

    public function parkArea(): BelongsTo
    {
        return $this->belongsTo(ParkArea::class);
    }

    public function manufacturer(): BelongsTo
    {
        return $this->belongsTo(Manufacturer::class, 'manufacturer_id');
    }

    public function designer(): BelongsTo
    {
        return $this->belongsTo(Designer::class);
    }

    public function rideModel(): BelongsTo
    {
        return $this->belongsTo(RideModel::class);
    }

    // Extended Relationships
    public function coasterStats(): HasOne
    {
        return $this->hasOne(RollerCoasterStats::class);
    }

    // Photo Relationships (Polymorphic)
    public function photos(): MorphMany
    {
        return $this->morphMany(Photo::class, 'photosable');
    }

    // Review Relationships
    public function reviews(): MorphMany
    {
        return $this->morphMany(Review::class, 'reviewable');
    }

    public function approvedReviews(): MorphMany
    {
        return $this->reviews()->where('status', 'approved');
    }

    // Query Scopes
    public function scopeActive($query)
    {
        return $query->where('status', 'operating');
    }

    public function scopeByCategory($query, $category)
    {
        return $query->where('category', $category);
    }

    public function scopeInPark($query, $parkId)
    {
        return $query->where('park_id', $parkId);
    }

    public function scopeByManufacturer($query, $manufacturerId)
    {
        return $query->where('manufacturer_id', $manufacturerId);
    }

    // Attributes & Helper Methods
    public function getAverageRatingAttribute(): ?float
    {
        return $this->approvedReviews()->avg('rating');
    }

    public function getReviewCountAttribute(): int
    {
        return $this->approvedReviews()->count();
    }

    public function getDisplayNameAttribute(): string
    {
        return $this->name . ' at ' . $this->park->name;
    }

    public function getIsOperatingAttribute(): bool
    {
        return $this->status === RideStatus::OPERATING;
    }

    public function getHeightRequirementTextAttribute(): ?string
    {
        if (!$this->min_height_in) {
            return null;
        }

        $text = "Must be at least {$this->min_height_in}\" tall";
        
        if ($this->max_height_in) {
            $text .= " and no taller than {$this->max_height_in}\" tall";
        }

        return $text;
    }

    // Review Management Methods
    public function canBeReviewedBy(?int $userId): bool
    {
        if (!$userId) {
            return false;
        }

        return !$this->reviews()
            ->where('user_id', $userId)
            ->exists();
    }

    public function addReview(array $data): Review
    {
        return $this->reviews()->create([
            'user_id' => Auth::id(),
            'rating' => $data['rating'],
            'title' => $data['title'] ?? null,
            'content' => $data['content'],
            'status' => 'pending',
        ]);
    }

    // Cache Management (Future: will use HasCaching trait)
    public function getCacheKey(string $suffix = ''): string
    {
        return "ride:{$this->id}" . ($suffix ? ":{$suffix}" : '');
    }

    public function clearRelatedCache(): void
    {
        cache()->forget($this->getCacheKey('reviews'));
        cache()->forget($this->getCacheKey('statistics'));
        cache()->forget($this->getCacheKey('photos'));
    }

    // Statistics Management (Future: will use HasStatistics trait)
    public function updateStatistics(): void
    {
        // Placeholder for future HasStatistics trait integration
        // For now, manually manage statistics
        $totalReviews = $this->reviews()->count();
        $averageRating = $this->reviews()->avg('rating');
        
        // Update any related statistics tracking
        $this->clearRelatedCache();
    }
}