<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class LocationRating extends Model
{
    protected $table = 'ratings';

    protected $fillable = [
        'title_id',
        'category',
        'hotel_name',
        'name',
        'email',
        'user_phone',
        'rating',
        'overall_rating',
        'service_rating',
        'quality_rating',
        'location_rating',
        'price_rating',
        'cleanliness_rating',
        'comment',
        'positive_comment',
        'negative_comment',
        'visit_date',
        'visit_purpose',
        'recommendation',
        'ip_address',
        'user_agent',
        'status',
        'helpful_count',
        'not_helpful_count',
        'is_verified',
        'is_featured',
        'admin_reply',
        'admin_reply_date',
        'approved_at',
        'approved_by'
    ];

    protected $casts = [
        'visit_date' => 'date',
        'admin_reply_date' => 'datetime',
        'approved_at' => 'datetime',
        'timestamp' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'is_verified' => 'boolean',
        'is_featured' => 'boolean',
        'helpful_count' => 'integer',
        'not_helpful_count' => 'integer',
        'rating' => 'integer',
        'overall_rating' => 'integer',
        'service_rating' => 'integer',
        'quality_rating' => 'integer',
        'location_rating' => 'integer',
        'price_rating' => 'integer',
        'cleanliness_rating' => 'integer'
    ];

    protected $dates = [
        'visit_date',
        'admin_reply_date',
        'approved_at',
        'timestamp',
        'created_at',
        'updated_at'
    ];

    // Relationships
    public function location()
    {
        return $this->belongsTo(Location::class, 'title_id', 'title_id');
    }

    public function helpfulVotes()
    {
        return $this->hasMany(RatingHelpfulVote::class, 'rating_id');
    }

    // Scopes
    public function scopeApproved($query)
    {
        return $query->where('status', 'approved');
    }

    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }

    public function scopeRejected($query)
    {
        return $query->where('status', 'rejected');
    }

    public function scopeFeatured($query)
    {
        return $query->where('is_featured', true);
    }

    public function scopeVerified($query)
    {
        return $query->where('is_verified', true);
    }

    public function scopeForLocation($query, $titleId)
    {
        return $query->where('title_id', $titleId);
    }

    public function scopeRecent($query, $days = 30)
    {
        return $query->where('created_at', '>=', Carbon::now()->subDays($days));
    }

    public function scopeHighRated($query, $minRating = 4)
    {
        return $query->where('rating', '>=', $minRating);
    }

    public function scopeLowRated($query, $maxRating = 2)
    {
        return $query->where('rating', '<=', $maxRating);
    }

    // Accessors
    public function getFormattedDateAttribute()
    {
        return $this->created_at ? $this->created_at->diffForHumans() : '';
    }

    public function getStarRatingAttribute()
    {
        $rating = $this->rating ?? 0;
        $stars = '';
        for ($i = 1; $i <= 5; $i++) {
            $stars .= $i <= $rating ? '★' : '☆';
        }
        return $stars;
    }

    public function getRecommendationTextAttribute()
    {
        switch ($this->recommendation) {
            case 'yes':
                return 'بله، توصیه می‌کنم';
            case 'maybe':
                return 'شاید';
            case 'no':
                return 'خیر، توصیه نمی‌کنم';
            default:
                return 'نظری ندارم';
        }
    }

    public function getVisitPurposeTextAttribute()
    {
        switch ($this->visit_purpose) {
            case 'business':
                return 'کاری';
            case 'leisure':
                return 'تفریحی';
            case 'family':
                return 'خانوادگی';
            case 'romantic':
                return 'عاشقانه';
            case 'solo':
                return 'انفرادی';
            case 'group':
                return 'گروهی';
            default:
                return 'نامشخص';
        }
    }

    public function getStatusTextAttribute()
    {
        switch ($this->status) {
            case 'approved':
                return 'تایید شده';
            case 'pending':
                return 'در انتظار بررسی';
            case 'rejected':
                return 'رد شده';
            case 'spam':
                return 'اسپم';
            default:
                return 'نامشخص';
        }
    }

    public function getAverageDetailedRatingAttribute()
    {
        $ratings = array_filter([
            $this->service_rating,
            $this->quality_rating,
            $this->location_rating,
            $this->price_rating,
            $this->cleanliness_rating
        ]);

        return count($ratings) > 0 ? round(array_sum($ratings) / count($ratings), 1) : null;
    }

    public function getHelpfulnessRatioAttribute()
    {
        $total = $this->helpful_count + $this->not_helpful_count;
        return $total > 0 ? round(($this->helpful_count / $total) * 100, 1) : 0;
    }

    // Mutators
    public function setEmailAttribute($value)
    {
        $this->attributes['email'] = strtolower(trim($value));
    }

    public function setNameAttribute($value)
    {
        $this->attributes['name'] = trim($value);
    }

    // Static methods
    public static function getAverageRatingForLocation($titleId)
    {
        return static::approved()
            ->forLocation($titleId)
            ->avg('rating');
    }

    public static function getTotalRatingsForLocation($titleId)
    {
        return static::approved()
            ->forLocation($titleId)
            ->count();
    }

    public static function getRatingDistributionForLocation($titleId)
    {
        $distribution = [];
        for ($i = 1; $i <= 5; $i++) {
            $distribution[$i] = static::approved()
                ->forLocation($titleId)
                ->where('rating', $i)
                ->count();
        }
        return $distribution;
    }

    public static function getDetailedAveragesForLocation($titleId)
    {
        $ratings = static::approved()->forLocation($titleId)->get();

        return [
            'service_avg' => $ratings->whereNotNull('service_rating')->avg('service_rating'),
            'quality_avg' => $ratings->whereNotNull('quality_rating')->avg('quality_rating'),
            'location_avg' => $ratings->whereNotNull('location_rating')->avg('location_rating'),
            'price_avg' => $ratings->whereNotNull('price_rating')->avg('price_rating'),
            'cleanliness_avg' => $ratings->whereNotNull('cleanliness_rating')->avg('cleanliness_rating'),
        ];
    }

    // Helper methods
    public function approve($adminId = null)
    {
        $this->update([
            'status' => 'approved',
            'approved_at' => now(),
            'approved_by' => $adminId
        ]);
    }

    public function reject()
    {
        $this->update(['status' => 'rejected']);
    }

    public function markAsSpam()
    {
        $this->update(['status' => 'spam']);
    }

    public function feature()
    {
        $this->update(['is_featured' => true]);
    }

    public function unfeature()
    {
        $this->update(['is_featured' => false]);
    }

    public function verify()
    {
        $this->update(['is_verified' => true]);
    }

    public function unverify()
    {
        $this->update(['is_verified' => false]);
    }

    public function addAdminReply($reply, $adminId = null)
    {
        $this->update([
            'admin_reply' => $reply,
            'admin_reply_date' => now(),
            'approved_by' => $adminId
        ]);
    }

    public function incrementHelpful()
    {
        $this->increment('helpful_count');
    }

    public function decrementHelpful()
    {
        $this->decrement('helpful_count');
    }

    public function incrementNotHelpful()
    {
        $this->increment('not_helpful_count');
    }

    public function decrementNotHelpful()
    {
        $this->decrement('not_helpful_count');
    }
}
