<?php

namespace App\Models;

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 HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'language_id',
        'country_id',
        'current_country_id',
        'name',
        'email',
        'country_code',
        'phone',
        'e164_number',
        'password',
        'role',
        'is_guest',
        'ip_country',
        'otp_code',
        'otp_expires_at',
        'otp_sent_at',
        'otp_attempts',
        'otp_verified_at',
        'email_verified_at',
        'banned_at',
    ];

    protected $hidden = [
        'password',
        'remember_token',
        'otp_code',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'otp_expires_at' => 'datetime',
        'otp_sent_at' => 'datetime',
        'otp_verified_at' => 'datetime',
        'banned_at' => 'datetime',
        'is_guest' => 'boolean',
        'otp_attempts' => 'integer',
    ];

    // Relations
    public function language()
    {
        return $this->belongsTo(Language::class);
    }

    public function country()
    {
        return $this->belongsTo(Country::class);
    }

    public function currentCountry()
    {
        return $this->belongsTo(Country::class, 'current_country_id');
    }

    public function stores()
    {
        return $this->hasMany(Store::class);
    }

    public function countryStores()
    {
        return $this->hasMany(CountryStore::class);
    }

    public function offers()
    {
        return $this->hasMany(Offer::class);
    }

    public function devices()
    {
        return $this->hasMany(UserDevice::class);
    }

    public function providers()
    {
        return $this->hasMany(UserProvider::class);
    }

    public function subscriptions()
    {
        return $this->hasMany(Subscription::class);
    }

    public function userLocales()
    {
        return $this->hasMany(UserLocale::class);
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->whereNull('banned_at');
    }

    public function scopeVerified($query)
    {
        return $query->whereNotNull('email_verified_at');
    }

    public function scopeByRole($query, $role)
    {
        return $query->where('role', $role);
    }

    // Mutators & Accessors
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = bcrypt($value);
    }

    public function getIsVerifiedAttribute()
    {
        return !is_null($this->email_verified_at);
    }

    public function getIsBannedAttribute()
    {
        return !is_null($this->banned_at);
    }

/**
 * Check if user is subscribed to a specific item
 */
public function isSubscribedTo($subscribable, $type = 'follow')
{
    return $this->subscriptions()
                ->where('subscribable_type', get_class($subscribable))
                ->where('subscribable_id', $subscribable->id)
                ->where('type', $type)
                ->exists();
}

/**
 * Subscribe to an item
 */
public function subscribeTo($subscribable, $type = 'follow')
{
    return $this->subscriptions()->firstOrCreate([
        'subscribable_type' => get_class($subscribable),
        'subscribable_id' => $subscribable->id,
        'type' => $type,
    ]);
}

/**
 * Unsubscribe from an item
 */
public function unsubscribeFrom($subscribable, $type = 'follow')
{
    return $this->subscriptions()
                ->where('subscribable_type', get_class($subscribable))
                ->where('subscribable_id', $subscribable->id)
                ->where('type', $type)
                ->delete();
}

/**
 * Get subscribed stores
 */
public function getSubscribedStores()
{
    return $this->subscriptions()
                ->where('subscribable_type', \App\Models\CountryStore::class)
                ->with('subscribable.store', 'subscribable.country')
                ->get()
                ->pluck('subscribable');
}

/**
 * Get subscribed categories
 */
public function getSubscribedCategories()
{
    return $this->subscriptions()
                ->where('subscribable_type', \App\Models\Category::class)
                ->with('subscribable')
                ->get()
                ->pluck('subscribable');
}

/**
 * Get subscribed brands
 */
public function getSubscribedBrands()
{
    return $this->subscriptions()
                ->where('subscribable_type', \App\Models\Brand::class)
                ->with('subscribable')
                ->get()
                ->pluck('subscribable');
}

/**
 * Get favorite offers
 */
public function getFavoriteOffers()
{
    return $this->subscriptions()
                ->where('subscribable_type', \App\Models\Offer::class)
                ->where('type', 'favorite')
                ->with('subscribable.countryStore.store', 'subscribable.brand')
                ->get()
                ->pluck('subscribable');
}

/**
 * Get subscription statistics
 */
public function getSubscriptionStats()
{
    return [
        'total' => $this->subscriptions()->count(),
        'stores' => $this->subscriptions()->where('subscribable_type', \App\Models\CountryStore::class)->count(),
        'categories' => $this->subscriptions()->where('subscribable_type', \App\Models\Category::class)->count(),
        'brands' => $this->subscriptions()->where('subscribable_type', \App\Models\Brand::class)->count(),
        'offers' => $this->subscriptions()->where('subscribable_type', \App\Models\Offer::class)->count(),
        'follows' => $this->subscriptions()->where('type', 'follow')->count(),
        'favorites' => $this->subscriptions()->where('type', 'favorite')->count(),
        'notifications' => $this->subscriptions()->where('type', 'notify')->count(),
    ];
}

/**
 * Get recommendations based on subscriptions
 */
public function getRecommendations($limit = 10)
{
    // Get user's subscribed categories
    $subscribedCategoryIds = $this->subscriptions()
                                 ->where('subscribable_type', \App\Models\Category::class)
                                 ->pluck('subscribable_id');

    // Get user's subscribed brands
    $subscribedBrandIds = $this->subscriptions()
                              ->where('subscribable_type', \App\Models\Brand::class)
                              ->pluck('subscribable_id');

    // Get offers from subscribed categories and brands
    $recommendations = \App\Models\Offer::query()
        ->active()
        ->notExpired()
        ->where(function ($query) use ($subscribedCategoryIds, $subscribedBrandIds) {
            if ($subscribedCategoryIds->isNotEmpty()) {
                $query->whereHas('categories', function ($q) use ($subscribedCategoryIds) {
                    $q->whereIn('categories.id', $subscribedCategoryIds);
                });
            }
            if ($subscribedBrandIds->isNotEmpty()) {
                $query->orWhereIn('brand_id', $subscribedBrandIds);
            }
        })
        ->with(['countryStore.store', 'brand', 'categories'])
        ->orderBy('popularity', 'desc')
        ->limit($limit)
        ->get();

    return $recommendations;
}

/**
 * Clean up expired offer subscriptions
 */
public function cleanupExpiredOfferSubscriptions()
{
    return $this->subscriptions()
                ->where('subscribable_type', \App\Models\Offer::class)
                ->whereHas('subscribable', function ($query) {
                    $query->where('expires_at', '<=', now());
                })
                ->delete();
}

/**
 * Get subscription activity feed
 */
public function getSubscriptionActivityFeed($limit = 20)
{
    // Get latest offers from subscribed stores
    $subscribedStoreIds = $this->subscriptions()
                              ->where('subscribable_type', \App\Models\CountryStore::class)
                              ->pluck('subscribable_id');

    $storeOffers = \App\Models\Offer::query()
        ->whereIn('country_store_id', $subscribedStoreIds)
        ->active()
        ->notExpired()
        ->with(['countryStore.store', 'brand'])
        ->orderBy('created_at', 'desc')
        ->limit($limit)
        ->get();

    // Get latest offers from subscribed brands
    $subscribedBrandIds = $this->subscriptions()
                              ->where('subscribable_type', \App\Models\Brand::class)
                              ->pluck('subscribable_id');

    $brandOffers = \App\Models\Offer::query()
        ->whereIn('brand_id', $subscribedBrandIds)
        ->active()
        ->notExpired()
        ->with(['countryStore.store', 'brand'])
        ->orderBy('created_at', 'desc')
        ->limit($limit)
        ->get();

    // Merge and sort by creation date
    $allOffers = $storeOffers->merge($brandOffers)
                            ->unique('id')
                            ->sortByDesc('created_at')
                            ->take($limit);

    return $allOffers->values();
}



}
