<?php
namespace PrestaShop\Module\PolarisPrestaTheme\Classes;
use PrestaShopLogger;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use PrestaShop\Module\PolarisPrestaTheme\Config\ConfigTheme;
use \Imagick;


/**
 * Ensemble d'utilitaires pour la gestion des fichiers et répertoires liés au thème PrestaShop.
 */
class ThemeTools
{
    /** 
     * removeDirectory 
     *
     * Supprime le dossier $path et tout son contenu.
     * 
     * @param string $path Dossier à supprimer
     * @throws Exception en cas d'erreur lors de la suppression
     */
    public static function removeDirectory(string $path): void
    {
        if (!is_dir($path)) {
            PrestaShopLogger::addLog("ℹ️ Le répertoire n'existe pas : $path", 1);
            return;
        }
    
        $handle = opendir($path);
        if (!$handle) {
            throw new \Exception("Impossible d’ouvrir le répertoire : $path");
        }
    
        try {
            while (($entry = readdir($handle)) !== false) {
                if ($entry === '.' || $entry === '..') {
                    continue;
                }
    
                $file = $path . DIRECTORY_SEPARATOR . $entry;
    
                if (is_dir($file)) {
                    self::removeDirectory($file);
                } else {
                    if (!unlink($file)) {
                        throw new \Exception("Impossible de supprimer le fichier : $file");
                    }
                }
            }
        } finally {
            closedir($handle);
    
            if (file_exists($path) && !rmdir($path)) {
                throw new \Exception("Impossible de supprimer le répertoire : $path");
            }
        }
    }

    /** 
     * copyTheme
     *
     * copie le dossier $source et tout son contenu vers sa $destination
     * 
     * @param string $soure fichier a copier
     * @param string $destination route ou copier le fichier
     * @throws Exception en cas d'erreur lors de la copie
     */
    public static function copyTheme($source, $destination)
    {
        if (!is_dir($source)) {
            PrestaShopLogger::addLog("❌ Le dossier source n'existe pas : $source", 3);
            return false;
        }
    
        if (!file_exists($destination)) {
            @mkdir($destination, 0755, true);
        }
    
        $dir = opendir($source);
        if (!$dir) {
            PrestaShopLogger::addLog("❌ Impossible d'ouvrir le dossier source : $source", 3);
            return false;
        }
    
        while (($file = readdir($dir)) !== false) {
            if ($file === '.' || $file === '..') {
                continue;
            }
    
            $srcPath = $source . '/' . $file;
            $destPath = $destination . '/' . $file;
    
            if (is_dir($srcPath)) {
                if (!self::copyTheme($srcPath, $destPath)) {
                    closedir($dir);
                    return false;
                }
            } else {
                if (!copy($srcPath, $destPath)) {
                    PrestaShopLogger::addLog("❌ Erreur lors de la copie de $srcPath vers $destPath", 3);
                    closedir($dir);
                    return false;
                }
            }
        }
    
        closedir($dir);
        return true;
    }

     
    /**
     * uploadImage
     *
     * Upload une image Symfony (UploadedFile), la convertit en WebP
     * et la stocke dans le dossier spécifié ($uploadDir).
     *
     * @param UploadedFile $file Fichier image uploadé via Symfony
     * @param string $uploadDir Dossier cible pour l’enregistrement
     * @return string URL publique de l’image WebP générée
     * @throws \Exception En cas d’erreur d’extension, d’upload ou de conversion
     */
    public static function uploadImage(UploadedFile $file, string $uploadDir): string
    {
    // Extensions autorisées
        $_registration_allowed_extensions = ['png', 'jpg', 'jpeg', 'webp'];

        // Extension du fichier
        $image_extension = $file->guessExtension();
        if (!in_array(strtolower($image_extension), $_registration_allowed_extensions)) {
            throw new \Exception("Extension de fichier non prise en charge.");
        }

        // Nom original (sans l’extension)
        $original_name = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
        $image_name = $original_name . '.' . $image_extension;
        $finalPath = $uploadDir . DIRECTORY_SEPARATOR . $image_name;

        // Éviter les collisions de nom
        $counter = 1;
        while (file_exists($finalPath)) {
            $image_name = $original_name . '_' . $counter . '.' . $image_extension;
            $finalPath = $uploadDir . DIRECTORY_SEPARATOR . $image_name;
            $counter++;
        }

        // Déplacement du fichier depuis le cache Symfony vers le répertoire cible
        $file->move($uploadDir, $image_name);

        // Vérification de l’existence réelle
        if (!file_exists($finalPath)) {
            throw new \Exception("Le fichier uploadé n'existe pas : " . $finalPath);
        }

        // Utilisation de ImageMagick pour convertir en WebP
        if (class_exists('Imagick')) {
            try {
                // Création d'un objet Imagick pour l'image téléchargée
                $imagick = new Imagick($finalPath);
                
                // Conversion au format WebP
                $imagick->setImageFormat('webp');
                
                // Définir une qualité de compression (facultatif, de 0 à 100)
                $imagick->setImageCompressionQuality(100);
                
                // Définir le chemin de l'image WebP
                $webpPath = $uploadDir . DIRECTORY_SEPARATOR . $original_name . '.webp';
                
                // Sauvegarde de l'image convertie en WebP
                $imagick->writeImage($webpPath);
                
                // Libération des ressources
                $imagick->clear();
                
                // Suppression de l’image originale
                unlink($finalPath);
                
            } catch (\Exception $e) {
                throw new \Exception("Erreur de conversion avec Imagick: " . $e->getMessage());
            }
        } else {
            throw new \Exception("Imagick n'est pas installé sur le serveur.");
        }

        // Retourne l’URL publique de l’image WebP
        return __PS_BASE_URI__ . 'themes/presta_theme/assets/img/' . $original_name . '.webp';

    }




    /**
     * updateCssFile
     * 
     * Met à jour le fichier var.css avec les nouvelles variables de configuration
     * 
     */
    public static function updateCssFile(){

         $config = ConfigTheme::load();

        // Chemin vers le fichier var.css
        $fileVarCss = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . 'presta_theme' . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'css' . DIRECTORY_SEPARATOR . 'var.css';

        // Générer le contenu du fichier var.css avec les nouvelles variables
        $css = ':root{
            --primary: ' . ($config->configGeneral[0]->primary ?? '') . ';
            --secondary: ' . ($config->configGeneral[0]->secondary ?? '') . ';
            --PoliceTitle: "' . ($config->configGeneral[0]->fontTitle ?? '') . '";
            --PoliceText: "' . ($config->configGeneral[0]->fontText ?? '') . '";
            --HeaderBackground: ' . ($config->configHeader[0]->background ?? '') . ';
            --HeaderColor: ' . ($config->configHeader[0]->color ?? '') . ';
            --FooterBackground: ' . ($config->configFooter[0]->background ?? '') . ';
            --FooterColor: ' . ($config->configFooter[0]->color ?? '') . ';
            --BandeauBackground: ' . ($config->configTopBandeauParameter[0]->background ?? '') . ';
            --BandeauColor: ' . ($config->configTopBandeauParameter[0]->color ?? '') . ';
        };';

        
        
        // Sauvegarder le nouveau contenu dans le fichier var.css
        file_put_contents($fileVarCss, $css);
    }


      public static function getShippingEstimator()
    {
       
        $config = ConfigTheme::load();
        $livraison = $config->configLivraison[0];

        // Current timestamp and hour
        $currentTimestamp = time();
        $currentHour = (int) date('G', $currentTimestamp); // Hour in 0–23

        // Get non-shipping days, delivery times per carrier, default carrier, and shipping cutoff hour
        $noShippingDays = $livraison->noShippingDays ?? [];
        $deliveryTimes = $livraison->deliveryTime ?? [];
        $defaultCarrier = $livraison->defaultCarrier ?? null;
        $shippingTime = (int) ($livraison->shippingTime ?? 0);

        // Map weekday names to numeric representation (0 = Sunday, 1 = Monday, …)
        $dayMapping = [
            'monday' => 1,
            'tuesday' => 2,
            'wednesday' => 3,
            'thursday' => 4,
            'friday' => 5,
            'saturday' => 6,
            'sunday' => 0,
        ];
        
            

        // Convert non-shipping days to numbers for easy comparison
        $noShippingDaysNumeric = array_map(
            function ($day) use ($dayMapping) {
                return $dayMapping[$day];
            },
            $noShippingDays
        );

        // Prepare arrays to store delivery dates
        $deliverys = [];
        $defaultDelivery = null;

        // Loop through each carrier and calculate its estimated delivery date
        foreach ($deliveryTimes as $carrierId => $deliveryTime) {
            $deliveryTime = (int) $deliveryTime;

            // ❗ If delivery time is 0, skip calculation and just return 0
            if ($deliveryTime === 0) {
                $deliverys[$carrierId] = 0;
                continue;
            }

           

            // 🔁 Start calculation from current timestamp for each carrier
            $currentTime = $currentTimestamp;
            $currentDay = (int) date('w', $currentTime);

            // If current hour exceeds shipping cutoff, push shipment to next day
            if ($currentHour >= $shippingTime) {
                $currentTime += 86400; // Add 1 day in seconds
                $currentDay = (int) date('w', $currentTime);
            }

            // Skip non-shipping days
            while (in_array($currentDay, $noShippingDaysNumeric, true)) {
                $currentTime += 86400; // Add 1 day
                $currentDay = (int) date('w', $currentTime);
            }

            // Estimated shipment date (after accounting for cutoff & no-shipping days)
            $expeditionDate = $currentTime;

            // Estimated delivery date = shipment date + delivery time in days
            $deliveryDate = $expeditionDate + ($deliveryTime * 86400);
            $deliveryDay = (int) date('w', $deliveryDate);


            // Skip non-shipping days for delivery as well
            while (in_array($deliveryDay, $noShippingDaysNumeric, true)) {
                $deliveryDate += 86400; // Add 1 day
                $deliveryDay = (int) date('w', $deliveryDate);
            }


            // Format the date based on language
            $formattedDate = date('d/m/Y', $deliveryDate); // DD/MM/YYYY 

            // Store the formatted date for this carrier
            $deliverys[$carrierId] = $formattedDate;

            // 📌 Store the delivery date for the default carrier
            if ((int) $carrierId === (int) $defaultCarrier) {
                $defaultDelivery = $formattedDate;
            }
        }

        // Return all the relevant shipping estimation data
        return [
            'delivery' => $defaultDelivery, // Date for default carrier
            'deliverys' => $deliverys,       // Dates for all carriers
            'shippingTime' => $shippingTime,    // Shipping cutoff hour
        ];
    }
    
 
}