<?php


namespace App\Models\Traits;


use App\Models\ProductManagement\Product;
use App\Services\CartTempDeletion;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Intervention\Image\Facades\Image;
use Throwable;

trait CanUploadFiles{


    public static function bootCanUploadFiles(){

        static::retrieved(function ($model){
           // $model->flushMediasToDeletion();
        });

        static::saved(function ($model){
            [$success] = (new CartTempDeletion)->processToDeleteMedias($model);
        });
    }


    public function getMediasForDeletions(){
         return  (new CartTempDeletion)->getMediasForDeletions($this);
    }

    public function flushMediasToDeletion(): bool
    {
        $service = new CartTempDeletion();
        $items = $service->getMediasForDeletions($this);

        return $service->removeItems(Arr::pluck($items,['rowId']));
    }

    /**
     * @throws Exception|Throwable
     */
    protected function resizeAndConvert(string|UploadedFile $file, ?array $resize = [], ?string $finalExtension = "webp"): string
    {
        $width = $resize['width'] ?? null;
        $height = $resize['height'] ?? null;
        $quality = $resize['quality'] ?? 90;
        $directory = storage_path('app/temp-img-resizes');

        // Vérifier et créer le dossier temporaire si nécessaire
        if (!File::exists($directory)) {
            File::makeDirectory($directory, 0777, true, true);
        }

        // 📌 Gérer le cas où $file est une URL
        $tempPath = null;
        $isTempFile = false;
        if (is_string($file) && filter_var($file, FILTER_VALIDATE_URL)) {
            $tempPath = tempnam(sys_get_temp_dir(), 'img_'); // Fichier temporaire
            file_put_contents($tempPath, file_get_contents($file)); // Télécharger l'image
            $file = new UploadedFile($tempPath, basename($file)); // Convertir en UploadedFile
            $isTempFile = true; // Indique que c'est un fichier temporaire
        }

        // Vérifier si le fichier est valide
        throw_if(!$file instanceof UploadedFile || !$file->isValid(), new Exception('Le fichier image est invalide.'));

        // Définir les noms et extensions
        $originalExtension = $file->getClientOriginalExtension();
        $imageName = pathinfo($file->hashName(), PATHINFO_FILENAME);

        $finalExtension ??= $originalExtension;

        $path = "{$directory}/{$imageName}.{$finalExtension}";

        // Charger et redimensionner l'image
        $image = Image::make($file->getRealPath());

        if ($width || $height) {
            $image->resize($width, $height, function ($constraint) {
                $constraint->aspectRatio();
                $constraint->upsize();
            });
        }

        // Compression et conversion
        $image->encode($finalExtension, $quality)->save($path);

        // 🗑 Supprimer le fichier temporaire si l'image provient d'une URL
        if ($isTempFile && file_exists($tempPath)) {
            unlink($tempPath);
        }

        return $path;
    }


    /**
     * Télécharge les fichiers et les rattaches au model
     * @param array $files
     * @param array $options
     * @return bool
     * @throws Throwable
     */

    public function uploadFiles(array $files, array $options = []): bool
    {
        try {
            $resize = $options['resize'] ?? [];
            $collectionName = $this->getMediaCollectionName();

            // S'assurer que $files est bien un tableau
            $files = Arr::wrap($files);

            // Vérification si la liste est vide
            if (empty($files)) {
                return false;
            }

            foreach ($files as $file) {

                // Redimensionnement si nécessaire
                $resizedImagePath = $this->resizeAndConvert($file, $resize); // Remplace le fichier original par la version redimensionnée

                // Enregistrement du fichier dans la collection
                $this->addMedia($resizedImagePath)
                    ->sanitizingFileName(fn(string $fileName) => strtolower(str_replace(['#', '/', '\\', ' '], '-', $fileName)))
                    ->preservingOriginal()
                    ->toMediaCollection($collectionName);

                // Suppression du fichier temporaire après traitement
                if ($resizedImagePath) {
                    File::delete($resizedImagePath);
                }
            }

            return true;
        } catch (\Throwable $e) {
            write_log("uploads",$e);
            return false;
        }
    }

    /** Le nom de la collection de groupe de tous les fichiers rattaché au enregistrements de ce model
     * @return string
     */
    public function getMediaCollectionName(){
        return $this->getRegisteredMediaCollections()->first()->name ?? "default";
    }

    /** Un seul fichier rataché à l'enregistremen (représentant l'avatar)
     * @return mixed
     */
    public function getAvatarAttribute(){
        return  $this->getFirstMediaUrl($this->getMediaCollectionName());
    }

    public function getHasFilesAttribute(){
        return filled($this->files);
    }

    /** Un seul fichier rataché à l'enregistrement
     * @return mixed
     */
    public function getImageAttribute(){
        return  $this->getFirstMediaUrl($this->getMediaCollectionName());
    }

    /** Tous les fichiers rattachés à l'enregistrement
     * @return mixed
     */
    public function getFilesAttribute(){
        return $this->getMedia($this->getMediaCollectionName())->map->getUrl();
    }


    /**
     * Préparer les configurations de prévisualisation pour le FileInput
     * @return array
     */
    public function getInitialPreviewConfig(): array
    {
        return $this->media->map(fn($media)=> [
                    "caption" => $media->file_name,
                    "size" => $media->size,
                    "width" => "120px",
                    "url" => route('admin.medias.add-to-deletion',$media),
                    "key" => (int) $media->id,
                    "extra" => [
                      //  "mediaId" => $media->id,
                        "_token" => csrf_token(),
                    ]
                ])
                ->toArray();
    }

}
