<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasApiTokens;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'google_id',
        'stripe_customer_id',
        'fcm_token',
        'device_platform',
        'phone_number',
        'mobile_number',
        'profile_image',
        'profile_picture',
        'bio',
        'member_since',
        'followers_count',
        'following_count',
        'has_verification_badge',
        'verification_badge_purchased_at',
        'current_plan_id',
        'is_verified',
        'verified_badge_style',
        'is_admin',
        'city',
        'area',
        'state',
        'country',
        'latitude',
        'longitude',
        'leads_received',
        'contacts_initiated',
        'cycle_reset_at',
        'featured_ads_used',
        'boost_ads_used',
    ];


    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
        'is_verified' => 'boolean',
        'cycle_reset_at' => 'datetime',
        'member_since' => 'datetime',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array<int, string>
     */
    protected $appends = [
        'average_rating',
        'total_reviews',
        'review_breakdown',
        'rating_percentage',
    ];

    /**
     * Get the user plan associated with the user.
     */
    public function currentPlan()
    {
        return $this->belongsTo(UserPlan::class, 'current_plan_id');
    }

    /**
     * Get the subscriptions for the user.
     */
    public function subscriptions()
    {
        return $this->hasMany(Subscription::class);
    }

    /**
     * Get the ads posted by the user.
     */
    public function ads()
    {
        return $this->hasMany(Ad::class);
    }

    /**
     * Get the verification requests for the user.
     */
    // public function verificationRequests()
    // {
    //     return $this->hasMany(VerificationRequest::class);
    // }

    /**
     * Get the conversations where the user is the seller.
     */
    // public function sellerConversations()
    // {
    //     return $this->hasMany(Conversation::class, 'seller_id');
    // }

    /**
     * Get the conversations where the user is the buyer.
     */
    // public function buyerConversations()
    // {
    //     return $this->hasMany(Conversation::class, 'buyer_id');
    // }

    /**
     * Get the messages sent by the user.
     */
    // public function messages()
    // {
    //     return $this->hasMany(Message::class, 'sender_id');
    // }

    /**
     * Get the notifications for the user.
     */
    public function notifications()
    {
        return $this->hasMany(Notification::class);
    }

    /**
     * Get the ad analytics for the user's ads.
     */
    public function adAnalytics()
    {
        return $this->hasManyThrough(AdAnalytics::class, Ad::class);
    }

    /**
     * Get the safety reports for the user (as reported user)
     */
    public function safetyReports()
    {
        return $this->hasMany(SafetyReport::class, 'reported_user_id');
    }

    /**
     * Get the safety reports made by the user (as reporter)
     */
    public function reportedSafetyReports()
    {
        return $this->hasMany(SafetyReport::class, 'reporter_id');
    }


    /**
     * Get the safety actions for the user
     */
    public function safetyActions()
    {
        return $this->hasMany(SafetyAction::class);
    }

    /**
     * Get the user's trust score
     */
    public function trustScore()
    {
        return $this->hasOne(UserTrustScore::class);
    }

    /**
     * Check if user is currently suspended
     */
    public function isSuspended()
    {
        if (!$this->is_suspended) return false;
        if (!$this->suspension_until) return true;
        return now()->lt($this->suspension_until);
    }

    /**
     * Check if user has a specific plan feature
     */
    public function hasPlanFeature(string $feature): bool
    {
        if (!$this->currentPlan) {
            return false;
        }

        return match($feature) {
            'ad_free' => $this->currentPlan->ad_free,
            'analytics' => $this->currentPlan->has_analytics,
            'verified_badge' => $this->currentPlan->verified_badge,
            default => false,
        };
    }

    /**
     * Check if user can post ads (based on plan limits and safety status)
     */
    public function canPostAd(): bool
    {
        // Check if user is suspended
        if ($this->isSuspended()) {
            return false;
        }

        // Check if free ad posting is allowed
        $allowFreePosting = setting('allow_free_ad_posting', true);
        
        if ($allowFreePosting) {
            return true;
        }

        // Check if user has a paid plan
        if (!$this->currentPlan) {
            return false;
        }

        // Check post limit
        if ($this->currentPlan->post_limit !== null) {
            $currentPostCount = $this->ads()->where('status', '!=', 'Draft')->count();
            return $currentPostCount < $this->currentPlan->post_limit;
        }

        return true;
    }

    /**
     * Check if user has available feature credits.
     */
    public function hasFeatureCredit(): bool
    {
        if (!$this->currentPlan) return false;
        return $this->featured_ads_used < ($this->currentPlan->featured_limit ?? 0);
    }

    /**
     * Check if user has available boost credits.
     */
    public function hasBoostCredit(): bool
    {
        if (!$this->currentPlan) return false;
        return $this->boost_ads_used < ($this->currentPlan->boost_limit ?? 0);
    }

    /**
     * Use a feature credit.
     */
    public function useFeatureCredit(): bool
    {
        if ($this->hasFeatureCredit()) {
            $this->increment('featured_ads_used');
            return true;
        }
        return false;
    }

    /**
     * Use a boost credit.
     */
    public function useBoostCredit(): bool
    {
        if ($this->hasBoostCredit()) {
            $this->increment('boost_ads_used');
            return true;
        }
        return false;
    }
    /**
     * Get the notification preference for the user.
     */
    public function notificationPreference()
    {
        return $this->hasOne(UserNotificationPreference::class);
    }
    /**
     * Get the ads favorited by the user.
     */
    public function favorites()
    {
        return $this->belongsToMany(Ad::class, 'favorites', 'user_id', 'ad_id')->withTimestamps();
    }
    /**
     * Get the appeals made by the user.
     */
    public function appeals()
    {
        return $this->hasMany(UserAppeal::class);
    }

    /**
     * Get the reviews written by this user.
     */
    public function reviewsGiven()
    {
        return $this->hasMany(Review::class, 'reviewer_id');
    }

    /**
     * Get the reviews received by this user.
     */
    public function reviewsReceived()
    {
        return $this->hasMany(Review::class, 'reviewee_id');
    }

    /**
     * Get the average rating (decimal with 1 decimal place).
     */
    public function getAverageRatingAttribute()
    {
        return round($this->reviewsReceived()->avg('rating') ?? 0, 1);
    }

    /**
     * Get the total number of reviews received.
     */
    public function getTotalReviewsAttribute()
    {
        return $this->reviewsReceived()->count();
    }

    /**
     * Get the breakdown of reviews by star rating.
     */
    public function getReviewBreakdownAttribute()
    {
        return [
            '5' => $this->reviewsReceived()->where('rating', 5)->count(),
            '4' => $this->reviewsReceived()->where('rating', 4)->count(),
            '3' => $this->reviewsReceived()->where('rating', 3)->count(),
            '2' => $this->reviewsReceived()->where('rating', 2)->count(),
            '1' => $this->reviewsReceived()->where('rating', 1)->count(),
        ];
    }

    /**
     * Get the rating as a percentage (0-100).
     */
    public function getRatingPercentageAttribute()
    {
        $avg = $this->average_rating;
        return round(($avg / 5) * 100, 1);
    }
}
