<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Offer extends Model implements HasMedia
{
    use HasFactory, InteractsWithMedia;

    protected $fillable = [
        'user_id',
        'country_store_id',
        'brand_id',
        'status',
        'type',
        'code',
        'currency',
        'promotion_type',
        'promotion_value',
        'discount_value',
        'regular_price',
        'sale_price',
        'is_featured',
        'is_exclusive',
        'is_free_shipping',
        'is_new_customer',
        'store_order',
        'brand_order',
        'favorites_count',
        'uses_count',
        'views_count',
        'impressions_count',
        'popularity',
        'expires_at',
        'last_usage',
    ];

    protected $casts = [
        'discount_value' => 'decimal:2',
        'regular_price' => 'decimal:2',
        'sale_price' => 'decimal:2',
        'is_featured' => 'boolean',
        'is_exclusive' => 'boolean',
        'is_free_shipping' => 'boolean',
        'is_new_customer' => 'boolean',
        'store_order' => 'integer',
        'brand_order' => 'integer',
        'favorites_count' => 'integer',
        'uses_count' => 'integer',
        'views_count' => 'integer',
        'impressions_count' => 'integer',
        'popularity' => 'integer',
        'expires_at' => 'datetime',
        'last_usage' => 'datetime',
    ];

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

    public function countryStore()
    {
        return $this->belongsTo(CountryStore::class);
    }

    public function brand()
    {
        return $this->belongsTo(Brand::class);
    }

    public function translations()
    {
        return $this->hasMany(OfferTranslation::class);
    }

    public function categories()
    {
        return $this->belongsToMany(Category::class, 'category_offer');
    }

    public function occasions()
    {
        return $this->belongsToMany(Occasion::class, 'occasion_offer');
    }

    public function subscriptions()
    {
        return $this->morphMany(Subscription::class, 'subscribable');
    }

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

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

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

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

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

    public function scopeNotExpired($query)
    {
        return $query->where(function ($q) {
            $q->whereNull('expires_at')
              ->orWhere('expires_at', '>', now());
        });
    }

    public function scopeExpired($query)
    {
        return $query->where('expires_at', '<=', now());
    }

    public function scopeByType($query, $type)
    {
        return $query->where('type', $type);
    }

    public function scopeByPromotionType($query, $promotionType)
    {
        return $query->where('promotion_type', $promotionType);
    }

    public function scopePopular($query, $threshold = 100)
    {
        return $query->where('popularity', '>=', $threshold);
    }

    public function scopeHighDiscount($query, $minDiscount = 50)
    {
        return $query->where('discount_value', '>=', $minDiscount);
    }

    // Accessors
    public function getIsActiveAttribute()
    {
        return $this->status === 'active';
    }

    public function getIsExpiredAttribute()
    {
        return $this->expires_at && $this->expires_at->isPast();
    }

    public function getIsValidAttribute()
    {
        return $this->is_active && !$this->is_expired;
    }

    public function getSavingAmountAttribute()
    {
        if ($this->regular_price && $this->sale_price) {
            return $this->regular_price - $this->sale_price;
        }
        return null;
    }

    public function getSavingPercentageAttribute()
    {
        if ($this->regular_price && $this->sale_price) {
            return round((($this->regular_price - $this->sale_price) / $this->regular_price) * 100, 2);
        }
        return $this->discount_value;
    }

    // Helper Methods
    public function getTranslation($localeId)
    {
        return $this->translations()->where('locale_id', $localeId)->first();
    }

    public function getTitle($localeId = null)
    {
        if ($localeId) {
            $translation = $this->getTranslation($localeId);
            return $translation ? $translation->title : 'Offer #' . $this->id;
        }
        return 'Offer #' . $this->id;
    }

    public function getDescription($localeId = null)
    {
        if ($localeId) {
            $translation = $this->getTranslation($localeId);
            return $translation ? $translation->description : null;
        }
        return null;
    }

    public function incrementViews($amount = 1)
    {
        $this->increment('views_count', $amount);
        $this->updatePopularity();
    }

    public function incrementUses($amount = 1)
    {
        $this->increment('uses_count', $amount);
        $this->update(['last_usage' => now()]);
        $this->updatePopularity();
        
        // Update country store stats
        $this->countryStore->stats?->incrementUses($amount);
    }

    public function incrementImpressions($amount = 1)
    {
        $this->increment('impressions_count', $amount);
    }

    public function updatePopularity()
    {
        $popularity = ($this->favorites_count * 3) + 
                     ($this->uses_count * 5) + 
                     ($this->views_count * 1);

        $this->update(['popularity' => $popularity]);
    }

    // Media Collections
    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('images')
              ->acceptsMimeTypes(['image/jpeg', 'image/png', 'image/webp']);
    }
}