<?php

namespace App\Models\ProductManagement;

use App\Models\OrderManagement\Order;
use App\Models\OrderManagement\OrderProduct;
use App\Models\StockManagement\Traits\Destockable;
use App\Models\Traits\Bootables\Auditable;
use App\Models\Traits\CanUploadFiles;
use App\Models\Traits\Activable;
use Axn\EloquentAuthorable\AuthorableTrait;
use Cviebrock\EloquentSluggable\Sluggable;
use Database\Factories\ProductFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Nicolaslopezj\Searchable\SearchableTrait;
use Spatie\MediaLibrary\HasMedia as SpatieHasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Product extends Model implements SpatieHasMedia{
    use HasFactory, Sluggable, SearchableTrait,Activable,Auditable,
     Destockable,AuthorableTrait,CanUploadFiles,InteractsWithMedia;

    protected $guarded = [];
    protected $table = "product_mgt__products";

   // protected $hidden = ['pivot'];

    const FK_ID = "product_id";

    public function sluggable():array {
        return [
            'slug' => [
                'source' => 'name'
            ]
        ];
    }

    protected $searchable = [

        'columns' => [
            'products.name' => 10,
            'products.slug' => 10
        ],
    ];

    protected $appends = [
         "image","files","fullName","is_available"
    ];

    protected static function newFactory(){
        return ProductFactory::new();
    }



    public function scopeHasQuantity($query){
        return $query->where('quantity', '>', 0);
    }

    public function scopeActiveCategory($query){
        return $query->whereHas('category', fn ($query) => $query->active());
    }

    public function scopeAvailables($query){
        return $query->whereHas('stocks',
                        fn ($q) => $q->availables() // les qte > 0
                                     ->noneExpired() // qui ne sont pas expirés
                    );
    }

    public function scopeFeatured($query){
        return $query->whereFeatured(true);
    }

//    public function getFeaturedAttribute(){
//        return $this->attributes['featured'] == 0 ? __("Non") : __("Oui");
//    }

    public function getFullNameAttribute(){
        if ($this->ref){
            return $this->name."[Ref:$this->ref]";
        }
        return $this->name;
    }

    public function getIsAvailableAttribute(){
        return true;
    }


    //RELATIONS
    /**
     * @return BelongsTo
     */
    public function category(){
        return $this->belongsTo(Category::class,"category_id");
    }

    /**
     * @return BelongsToMany
     */
    public function tags(){
        return $this->belongsToMany(
            Tag::class,
            (new ProductHasTag)->getTable(),
            'product_id',
            'tag_id');
    }

    /**
     * @return BelongsToMany
     */
    public function orders(){
        return $this->belongsToMany(
            Order::class,
            (new OrderProduct)->getTable(),
            'product_id',
            'order_id'
        ) ;
       // ->wherePivot('quantity');
    }

    /**
     * @return HasMany
     */
    public function reviews(){
        return $this->hasMany(Review::class,'product_id');
    }

    /**
     * @return mixed
     */
    public function approvedReviews(){
        return $this->hasMany(Review::class,'product_id')->active();
    }

    /**
     * @return HasMany
     */
    public function ratings(){
        return $this->hasMany(Rating::class,"product_id");
    }

    public function rate(){
        return filled($this->ratings)
              ? $this->ratings()->sum('value') / $this->ratings()->count()
              : 0 ;
    }


    public function registerMediaCollections(): void{
        //$default = url('/img/no-img.png'); // ''
        $default = url('default.png'); // '/img/cartwhite.png'
        $this->addMediaCollection('products')
//            ->singleFile() // ne doit contenir qu'un seul fichier sur la collection ( utilisateur n'a qu'un seul avatar )
//             ->onlyKeepLatest(3) // limiter le nombre de fichier dans la collection
             ->useFallbackUrl($default) // retouné lorsque getUrl = null
              ->useFallbackPath($default) // retouné lorsque getPath = null
//             ->acceptsFile(function (File $file) {  // Autoriser uniquement certains fichiers dans une collection
//                return $file->mimeType === 'image/jpeg';
//             })
//            ->acceptsMimeTypes(['image/jpeg']) // Autoriser uniquement certains types mime dans une collection
//            ->useDisk('s3') // Utiliser un disque spécifique

            //Définit les conversions de media lorsqu'une resource enregistrera un média
//            ->registerMediaConversions(function (Media $media) {
//                $this->addMediaConversion('thumb')
//                    ->width(100) // largeur : 100px
//                    ->height(100) // hauteur : 100px
//                    ->sharpen(10)
//                    ->nonQueued() //Précise que image soit créée directement (et non dans une file d'attente)
//                    ->queued() //  générer une conversion sur une file d'attente
//                ;
//            })
        ;

        // ... more
    }
}
