<?php

namespace App\Models\ProductManagement;

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\CategoryFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Nicolaslopezj\Searchable\SearchableTrait;
use Spatie\MediaLibrary\HasMedia as SpatieHasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

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

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


    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable(): array{
        return [
            'slug' => [
                'source' => 'name'
            ]
        ];
    }

    protected $searchable = [

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

    protected $appends = [
        "image",
    ];

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

    public function allProducts(){
        $category_id = $this->id;
        $childrens = $this->children->pluck("id")->toArray() ?? [];
        $childrens[] = $category_id;
        return Product::whereIn("category_id",$childrens)->active()
                    //   ->OrWhere("category_i",$category_id)
            ;
    }

    /** Une Catégorie a plusieurs produits
     * @return HasMany
     */
    public function products(){
        return $this->hasMany(Product::class,"category_id");
    }

    /** Une Sous-Catégorie n'a qu'un seul parent
     * @return HasOne
     */
    public function parent(){
        return $this->hasOne(Category::class, 'id', 'parent_id');
    }

    /** Une Catégorie peut avoir plusieurs enfants(sous-catégories)
     * @return HasMany
     */
    public function children(){
        return $this->hasMany(
            Category::class,
            'parent_id', // la clef etrangère qui se trouve dans le model (Category)
            'id'
        );
    }

    public function appearedChildren(): HasMany{
        return $this->hasMany(Category::class, 'parent_id', 'id')->active();
    }

    public static function tree($level = 1){
        return static::with(implode('.', array_fill(0, $level, 'children')))
            ->whereNull('parent_id')
            ->active()
            ->orderBy('id', 'asc')
            ->get();
    }


    public function registerMediaCollections(): void{
        $this->addMediaCollection('categories')
            ->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(url('/img/no-img.png')) // retouné lorsque getUrl = null
             ->useFallbackPath(url('/img/no-img.png')) // 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
    }

    public function getChildrenIdsAttribute(){

        return $this->children->pluck('id')->toArray();
    }

}
