<?php

namespace App\Models;

use App\Enums\RideCategory;
use App\Enums\RideStatus;
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\Support\Facades\Auth;

class Ride extends Model
{
    protected $fillable = [
        'name',
        'description',
        'status',
        'category',
        'opening_date',
        'closing_date',
        'park_id',
        'park_area_id',
        'manufacturer_id',
        'designer_id',
        'ride_model_id',
        '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',
        'min_height_in' => 'integer',
        'max_height_in' => 'integer',
        'capacity_per_hour' => 'integer',
        'ride_duration_seconds' => 'integer',
    ];

    // Base Relationships
    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);
    }

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

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

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

    // Review Relationships
    public function reviews(): HasMany
    {
        return $this->hasMany(Review::class);
    }

    public function approvedReviews(): HasMany
    {
        return $this->reviews()->approved();
    }

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

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

    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' => ReviewStatus::PENDING,
        ]);
    }
}