<?php

declare(strict_types=1);

namespace SmsNotifier\Facade;

use Exception;
use SmsNotifier\Factory\MessageTextFactory;
use SmsNotifier\Service\Logger;
use SmsNotifier\Service\SmsNumberProvider;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Ubnt\UcrmPluginSdk\Service\UcrmApi;
use Ubnt\UcrmPluginSdk\Service\PluginConfigManager;
use Ubnt\UcrmPluginSdk\Service\PluginLogManager;


/*
 * send message to client's number
 */

abstract class AbstractOxxoOperationsFacade
{
    /**
     * @var Logger
     */
    protected $logger;

    /**
     * @var MessageTextFactory
     */
    protected $messageTextFactory;

    /**
     * @var SmsNumberProvider
     */
    protected $clientPhoneNumber;

    /**
     * @var \SmsNotifier\Service\MinioStorageService
     */
    protected $minioStorage;

    /**
     * @var UcrmApi
     */
    protected $ucrmApi;

    protected $stripeCustomAttributeID;
    protected $clabeInterbancariaBanamexID;

    public function __construct(
        Logger $logger,
        MessageTextFactory $messageTextFactory,
        SmsNumberProvider $clientPhoneNumber,
        \SmsNotifier\Service\MinioStorageService $minioStorage
    ) {
        $this->logger = $logger;
        $this->messageTextFactory = $messageTextFactory;
        $this->clientPhoneNumber = $clientPhoneNumber;
        $this->minioStorage = $minioStorage;

        $config = PluginConfigManager::create()->loadConfig();
        $ipServer = $config['ipserver'] ?? 'localhost';
        $apiUrl = "https://$ipServer/crm/api/v1.0/";
        
        $client = new Client([
            'base_uri' => $apiUrl,
            'verify' => false,
        ]);
        
        $this->ucrmApi = new UcrmApi($client, $config['apitoken'] ?? '');
    }

    /*
     * Creates a PaymentIntent for OXXO in Stripe for a Customer
     * @param array $event_json
     * @param int|null $amount
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Stripe\Exception\ApiErrorException
     * @throws Exception
     */
public function createOxxoPaymentIntent($event_json, $amount = null, bool $uploadToFtp = true): array
    {
        // 1. Obtener Referencia de Stripe (Lógica Común)
        $stripeResult = $this->createStripeReference($event_json, $amount);

        // Si hubo error en Stripe, retornar el resultado de error
        if ($stripeResult['hasError']) {
            return $stripeResult['data'];
        }

        // 2. Procesamiento Síncrono (Generación inmediata)
        // Usamos los datos obtenidos de Stripe
        $oxxoData = $stripeResult['data'];
        
        return $this->processSynchronousGeneration($oxxoData, $uploadToFtp);
    }

    /**
     * Crea la orden en el servicio Docker y retorna el ID para flujo asíncrono
     */
    public function createAsyncOxxoOrder($event_json, $amount = null): array
    {
        // 1. Obtener Referencia de Stripe
        $stripeResult = $this->createStripeReference($event_json, $amount);

        if ($stripeResult['hasError']) {
            return $stripeResult['data'];
        }

        $data = $stripeResult['data'];

        // 2. Llamar al servicio Docker para crear la orden (POST /orders)
        $config = PluginConfigManager::create()->loadConfig();
        $ipPuppeteer = $config['ipPuppeteer'];
        $portPuppeteer = $config['portPuppeteer'];
        $api_url = "http://$ipPuppeteer:$portPuppeteer/orders";

        try {
            $client = new Client(['timeout' => 5]);
            $response = $client->post($api_url, [
                'json' => [
                    'client_id' => $data['clientID'],
                    'amount' => $data['amount'],
                    'client_full_name' => $data['clientFullName'],
                    'oxxo_reference' => $data['oxxo_reference'],
                    'stripe_url' => $data['url']
                ]
            ]);

            $orderData = json_decode($response->getBody()->getContents(), true);

            // Agregar el order_id al resultado para que el Plugin lo devuelva
            $data['order_id'] = $orderData['order_id'] ?? null;
            
            return $data; // Retornamos los datos básicos + order_id

        } catch (Exception $e) {
            $this->logger->error("Error creando orden asíncrona en Docker: " . $e->getMessage());
            // Fallback: Retornar los datos de Stripe aunque falle el guardado en DB local (mejor que nada)
            $data['error'] = 'docker_order_creation_failed';
            return $data;
        }
    }

    /**
     * Trigger para generar la imagen en background, subirla y actualizar la orden
     */
    public function generateAndUploadOrder(int $orderId, string $stripeUrl, string $clientFullName, bool $uploadToFtp = true): void
    {
        $this->logger->info("Iniciando generación en background para Orden #$orderId");
        
        $config = PluginConfigManager::create()->loadConfig();
        $ipPuppeteer = $config['ipPuppeteer'];
        $portPuppeteer = $config['portPuppeteer'];
        
        // 1. Solicitar Generación (POST /orders/:id/generate)
        // Calculamos nombre de archivo
        $clientFullNameWithoutSpaces = str_replace(' ', '_', $clientFullName);
        $voucherFileName = 'voucher_'.$clientFullNameWithoutSpaces.'_' . time() . '.jpeg';
        $output_filename = realpath(__DIR__ . '/../../vouchers_oxxo') . '/'. $voucherFileName;

        $generateUrl = "http://$ipPuppeteer:$portPuppeteer/orders/$orderId/generate";
        
        try {
            $client = new Client(['timeout' => 60]); // Mayor timeout para Puppeteer
            $response = $client->post($generateUrl, [
            'json' => [
                'url' => $stripeUrl,
                'filename' => $voucherFileName,
                'clip' => ['x' => 325, 'y' => 30, 'width' => 550, 'height' => 550]
            ]
        ]);

            if ($response->getStatusCode() === 200) {
                // Guardar imagen localmente
                $imageContent = $response->getBody()->getContents();
                file_put_contents($output_filename, $imageContent);
                $this->logger->info("Imagen generada y guardada localmente: $voucherFileName");

                $voucherUrl = '';
                // 2. Subir a S3/MinIO (si aplica)
                if ($uploadToFtp) {
                    // $voucherUrl = $this->UploadVoucherToWordpressByImageFileName($voucherFileName);
                    // $this->logger->info("Imagen subida a FTP: $voucherUrl");
                    
                    // Nueva implementación MinIO
                    $voucherUrl = $this->minioStorage->uploadFile($output_filename, $voucherFileName);
                    $this->logger->info("Imagen subida a MinIO: $voucherUrl");
                }

                // 3. Actualizar Orden (POST /orders/:id/complete)
                if ($voucherUrl) {
                     $completeUrl = "http://$ipPuppeteer:$portPuppeteer/orders/$orderId/complete";
                     $client->post($completeUrl, [
                         'json' => ['voucher_image_url' => $voucherUrl]
                     ]);
                }
            }

        } catch (Exception $e) {
            $this->logger->error("Error en flujo de background para Orden #$orderId: " . $e->getMessage());
        }
    }

    /**
     * Obtiene el estado de una orden desde el servicio Docker
     */
    public function getOxxoOrderStatus($orderId): array
    {
        $config = PluginConfigManager::create()->loadConfig();
        $ipPuppeteer = $config['ipPuppeteer'];
        $portPuppeteer = $config['portPuppeteer'];
        $api_url = "http://$ipPuppeteer:$portPuppeteer/orders/$orderId";

        try {
            $client = new Client(['timeout' => 5]);
            $response = $client->get($api_url);
            $data = json_decode($response->getBody()->getContents(), true);
            
            // Si la URL de la imagen es relativa o local, ajustarla si es necesario
            // pero el servicio ya guarda la URL completa del FTP si se subió.
            
            return $data;
        } catch (Exception $e) {
            $this->logger->error("Error obteniendo estado de orden #$orderId: " . $e->getMessage());
            return ['error' => 'fetch_failed', 'message' => $e->getMessage()];
        }
    }
    
    /**
     * Lógica extraída de Stripe
     * Retorna ['hasError' => bool, 'data' => array]
     */
    public function createStripeReference($event_json, $amount = null): array
    {
        $arrayOxxoPayment = [];
        $integerAmount = $amount;
        
        // Inicializar Config y Clientes (Copied logic)
        $configManager = PluginConfigManager::create();
        $config = $configManager->loadConfig();
        $StripeToken = $config['tokenstripe'];
        $IPServer = $config['ipserver'];
        $tokenCRM = $config['apitoken'];
        
        $baseUri = 'https://' . $IPServer . '/crm/api/v1.0/';
        if (!isset($this->ucrmApi)) {
             // Re-instanciar si es necesario, aunque ya está en consructor
             // Pero usamos la propiedad de clase
        }
        
        // ... Lógica de obtención de cliente, Stripe Customer, PaymentIntent ...
        // [RESUMIDO: Copiaremos el tocho de código aquí, simplificado]
        
        $clientID = $event_json['client_id'];
        $clientFullName = '';
        
        // --- 1. Obtener Cliente CRM ---
        try {
            $clientGuzzle = new Client([
                'base_uri' => $baseUri,
                'headers' => ['X-Auth-App-Key' => $tokenCRM, 'Accept' => 'application/json'],
                'verify' => false,
                'timeout' => 5
            ]);
            $resp = $clientGuzzle->get("clients/" . $clientID);
            $arrayClientCRM = json_decode($resp->getBody()->getContents(), true);
            $clientFullName = $arrayClientCRM['firstName'] . ' ' . $arrayClientCRM['lastName'];
        } catch (Exception $e) {
             return ['hasError' => true, 'data' => $this->buildErrorArray('errorGetClient', 'Error obteniendo cliente', $clientID, $clientFullName, $amount)];
        }

        // --- 2. Obtener Email y Stripe ID ---
        $clientEmail = 'siip8873@gmail.com'; // Default
        foreach ($arrayClientCRM['contacts'] as $contact) {
            if (!empty($contact['email'])) { $clientEmail = $contact['email']; break; }
        }

        $stripeCustomerId = null;
        foreach ($arrayClientCRM['attributes'] as $attr) {
            if ($attr['key'] === 'stripeCustomerId') { $stripeCustomerId = $attr['value']; break; }
        }
        if (!$stripeCustomerId) {
             return ['hasError' => true, 'data' => $this->buildErrorArray('errorGetCustomerStripe', 'Cliente sin Stripe ID', $clientID, $clientFullName, $amount)];
        }

        // --- 3. Calcular Monto ---
        if ($amount === null) {
            $amount = abs($arrayClientCRM['accountOutstanding']);
        } else {
             if(!is_numeric($amount)) $amount = preg_replace('/[^\d.]/', '', $amount);
        }

        if ($amount <= 10) {
             return ['hasError' => true, 'data' => $this->buildErrorArray('errorsinadeudo', 'Monto insuficiente o sin deuda', $clientID, $clientFullName, $amount)];
        }

        // --- 4. Crear Payment Intent en Stripe ---
        try {
            $amountInCents = intval($amount * 100);
            $guzzleClient = new Client(['timeout' => 10]);
            
            // Payment Intent
            $piResp = $guzzleClient->post('https://api.stripe.com/v1/payment_intents', [
                'auth' => [$StripeToken, ''],
                'form_params' => [
                    'amount' => $amountInCents,
                    'currency' => 'mxn',
                    'payment_method_types' => ['customer_balance', 'card', 'oxxo'],
                    'customer' => $stripeCustomerId,
                    'metadata' => [
                        'clientId' => $clientID,
                        'ucrm_client_id' => $clientID, // Backwards compatibility
                        'createdBy' => 'UCRM',
                        'paymentType' => 'card.one_time',
                        'signedInAdminId' => $config['idPaymentAdminCRM'] ?? 1,
                        'tipoPago' => 'OXXO'
                    ],
                    'payment_method_options' => ['oxxo' => ['expires_after_days' => 3]]
                ]
            ]);
            $paymentIntent = json_decode($piResp->getBody()->getContents(), true);

            // Payment Method
            $firstName = $arrayClientCRM['firstName'] ?? '';
            $lastName = $arrayClientCRM['lastName'] ?? '';
            $pmResp = $guzzleClient->post('https://api.stripe.com/v1/payment_methods', [
                'auth' => [$StripeToken, ''],
                'form_params' => [
                    'type' => 'oxxo',
                    'billing_details' => ['name' => "$firstName $lastName", 'email' => $clientEmail]
                ]
            ]);
            $paymentMethod = json_decode($pmResp->getBody()->getContents(), true);

            // Confirm
            $confResp = $guzzleClient->post('https://api.stripe.com/v1/payment_intents/' . $paymentIntent['id'] . '/confirm', [
                'auth' => [$StripeToken, ''],
                'form_params' => ['payment_method' => $paymentMethod['id']]
            ]);
            $paymentIntentConfirm = json_decode($confResp->getBody()->getContents(), true);

        } catch (Exception $e) {
             return ['hasError' => true, 'data' => $this->buildErrorArray('errorStripeApi', $e->getMessage(), $clientID, $clientFullName, $amount)];
        }

        // --- 5. Extraer Datos OXXO ---
        if (!empty($paymentIntentConfirm['next_action']['oxxo_display_details'])) {
            $oxxoDetails = $paymentIntentConfirm['next_action']['oxxo_display_details'];
            return [
                'hasError' => false,
                'data' => [
                    'oxxo_reference' => $oxxoDetails['number'],
                    'url' => $oxxoDetails['hosted_voucher_url'],
                    'error' => '',
                    'clientID' => $clientID,
                    'clientFullName' => $clientFullName,
                    'amount' => $amount,
                    'voucher_image_url' => ''
                ]
            ];
        }

        return ['hasError' => true, 'data' => $this->buildErrorArray('errorNoOxxoDetails', 'No se recibieron detalles OXXO', $clientID, $clientFullName, $amount)];
    }

    private function buildErrorArray($code, $desc, $clientId, $name, $amount) {
        return [
            'oxxo_reference' => '',
            'url' => '',
            'error' => $code,
            'failDescription' => $desc,
            'clientID' => $clientId,
            'clientFullName' => $name,
            'amount' => $amount,
            'voucher_image_url' => ''
        ];
    }

    /**
     * Crea la orden en el microservicio (Paso 1 del flujo asíncrono)
     */
    public function createOxxoOrder($arrayOxxoPayment) {
        $config = PluginConfigManager::create()->loadConfig();
        $ipPuppeteer = $config['ipPuppeteer'];
        $portPuppeteer = $config['portPuppeteer'];
        $baseUrl = 'http://'.$ipPuppeteer.':'.$portPuppeteer;
        $guzzleClient = new Client(['timeout' => 10]);

        try {
            $createOrderResp = $guzzleClient->post($baseUrl . '/orders', [
                'json' => [
                    'client_id' => $arrayOxxoPayment['clientID'],
                    'amount' => $arrayOxxoPayment['amount'],
                    'client_full_name' => $arrayOxxoPayment['clientFullName'],
                    'oxxo_reference' => $arrayOxxoPayment['oxxo_reference'],
                    'stripe_url' => $arrayOxxoPayment['url']
                ]
            ]);
            $orderData = json_decode($createOrderResp->getBody()->getContents(), true);
            $arrayOxxoPayment['order_id'] = $orderData['order_id'] ?? null;
            return $arrayOxxoPayment;

        } catch (Exception $e) {
            $this->logger->error("Error creando orden OXXO: " . $e->getMessage());
            return $arrayOxxoPayment;
        }
    }

    /**
     * Genera el voucher y lo sube (Paso 2 del flujo asíncrono)
     */
    public function generateOxxoVoucher($arrayOxxoPayment, $uploadToFtp) {
        if (empty($arrayOxxoPayment['order_id'])) {
             $this->logger->error("Intentando generar voucher sin order_id");
             return $arrayOxxoPayment;
        }

        $config = PluginConfigManager::create()->loadConfig();
        $ipPuppeteer = $config['ipPuppeteer'];
        $portPuppeteer = $config['portPuppeteer'];
        $baseUrl = 'http://'.$ipPuppeteer.':'.$portPuppeteer;
        $guzzleClient = new Client(['timeout' => 60]);

        $clientFullNameWithoutSpaces = str_replace(' ', '_', $arrayOxxoPayment['clientFullName']);
        $voucherFileName = 'voucher_'.$clientFullNameWithoutSpaces.'_' . time() . '.jpeg';
        $output_filename = realpath(__DIR__ . '/../../vouchers_oxxo') . '/'. $voucherFileName;

        $request_data = [
            'url' => $arrayOxxoPayment['url'],
            'filename' => $voucherFileName,
            'clip' => ['x' => 325, 'y' => 30, 'width' => 550, 'height' => 550]
        ];

        try {
            $response = $guzzleClient->post($baseUrl . '/orders/' . $arrayOxxoPayment['order_id'] . '/generate', [
                'json' => $request_data,
                'headers' => ['Accept' => 'image/jpeg, image/png']
            ]);

            if ($response->getStatusCode() === 200) {
                file_put_contents($output_filename, $response->getBody()->getContents());
                
                $arrayOxxoPayment['voucher_filename'] = $voucherFileName;
                
                if ($uploadToFtp) {
                    $url_file = $this->minioStorage->uploadFile($output_filename, $voucherFileName);
                    $arrayOxxoPayment['voucher_image_url'] = $url_file;

                     try {
                        $guzzleClient->post($baseUrl . '/orders/' . $arrayOxxoPayment['order_id'] . '/complete', [
                            'json' => ['voucher_image_url' => $url_file]
                        ]);
                        
                        // CLEANUP: Eliminar voucher local tras subida exitosa
                        if (file_exists($output_filename)) {
                            unlink($output_filename);
                            //$this->logger->info("Limpieza: Voucher local eliminado ($voucherFileName)");
                        }
                        
                    } catch (Exception $ex) {
                        $this->logger->warning("No se pudo actualizar URL final: " . $ex->getMessage());
                    }
                }
            }
        } catch (Exception $e) {
            $this->logger->error("Error generando voucher (Puppeteer): " . $e->getMessage());
        }

        return $arrayOxxoPayment;
    }

    /**
     * Mantiene compatibilidad con llamadas anteriores
     */
    private function processSynchronousGeneration($arrayOxxoPayment, $uploadToFtp) {
         $arrayOxxoPayment = $this->createOxxoOrder($arrayOxxoPayment);
         if (!empty($arrayOxxoPayment['order_id'])) {
             $arrayOxxoPayment = $this->generateOxxoVoucher($arrayOxxoPayment, $uploadToFtp);
         }
         return $arrayOxxoPayment;
    }






    //     /**
    //      * implement in subclass with the specific messaging provider
    //      * @see TwilioNotifierFacade::sendWhatsApp()
    //      */
    abstract protected function sendWhatsApp(
        string $message
    ): void;




    function validarEmail($email)
    {
        $this->logger->debug('SE VALIDA EL EMAIL!!! ' . PHP_EOL);
        // Utilizar la función filter_var con el filtro FILTER_VALIDATE_EMAIL para validar el email
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            // Si el email es válido, devolver el email
            return $email;
        } else {
            // Si el email no es válido, devolver una cadena vacía
            return '';
        }
    }


    function UploadReceiptToWordpressByImageFileName($imageFileName): string
    {

        // $log = PluginLogManager::create(); //Initialize Logger
        $configManager = PluginConfigManager::create();
        $config = $configManager->loadConfig();

        // Configuración de conexión FTP
        $ftp_server = $config['hostServerFTP'];
        $ftp_username = $config['usernameServerFTP'];
        $ftp_password = $config['passServerFTP'];

        $remote_folder = "/public_html/wp/wp-content/uploads/img/";


        // Configuración de conexión FTP
        $remote_file = "/public_html/wp/wp-content/uploads/img/" . $imageFileName;
        $file_to_upload = __DIR__ . '/' . $imageFileName;
        $url = 'https://siip.mx/wp/wp-content/uploads/img/' . $imageFileName;



        // Conexión FTP
        $ftp_conn = ftp_connect($ftp_server) or die("No se pudo conectar al servidor FTP");
        $login = ftp_login($ftp_conn, $ftp_username, $ftp_password);
        ftp_pasv($ftp_conn, true);
        // Verificar conexión y login
        if ($ftp_conn && $login) {
            print_r("Conexión FTP exitosa" . PHP_EOL);
            // $log->appendLog("Conexión FTP exitosa" . PHP_EOL);

            // Cargar archivo
            if (ftp_put($ftp_conn, $remote_file, $file_to_upload, FTP_BINARY)) {
                print_r("El archivo  ha sido cargado exitosamente." . PHP_EOL);
                print_r("La URL es: " . $url . PHP_EOL);
                // $log->appendLog("El archivo  ha sido cargado exitosamente." . PHP_EOL);
                // $log->appendLog("La URL es: " . $url . PHP_EOL);
                // Cerrar conexión FTP
                //ftp_close($ftp_conn);
                //return $url;

            } else {
                //$log->appendLog("Error al cargar el archivo " . PHP_EOL);
                print_r("Error al cargar el archivo " . PHP_EOL);
                ftp_close($ftp_conn);
                return '';
            }

            // Obtener lista de archivos en la carpeta
            $files = ftp_nlist($ftp_conn, $remote_folder);
            if (is_array($files)) {
                // Eliminar la ruta del directorio de los archivos
                $files = array_map(function ($file) use ($remote_folder) {
                    return str_replace($remote_folder, '', $file);
                }, $files);

                // Obtener fechas de modificación
                $filesWithTime = [];
                foreach ($files as $file) {
                    $modifiedTime = ftp_mdtm($ftp_conn, $remote_folder . $file);
                    if ($modifiedTime != -1) {
                        $filesWithTime[$file] = $modifiedTime;
                    }
                }

                // Ordenar archivos por fecha de modificación, más recientes primero
                arsort($filesWithTime);

                // Obtener los archivos a eliminar (todos menos los 5 más recientes)
                $filesToDelete = array_slice(array_keys($filesWithTime), 5);

                // Eliminar archivos antiguos
                foreach ($filesToDelete as $file) {
                    if (ftp_delete($ftp_conn, $remote_folder . $file)) {
                        print_r("Comprobante eliminado de Wordpress: " . $file . PHP_EOL);
                        // $log->appendLog("Comprobante eliminado de Wordpress: " . $file . PHP_EOL);
                    } else {
                        print_r('Error al borrar comprobante' . $file . PHP_EOL);
                        // $log->appendLog('Error al borrar comprobante' . $file . PHP_EOL);
                    }
                }
                print_r("Archivos eliminados" . PHP_EOL);
                // $log->appendLog("Archivos eliminados" . PHP_EOL);
                ftp_close($ftp_conn);
                return $url;
            } else {
                print_r("No se pudo obtener la lista de archivos de la carpeta FTP" . PHP_EOL);
                // $log->appendLog("No se pudo obtener la lista de archivos de la carpeta FTP" . PHP_EOL);
                ftp_close($ftp_conn);
                return $url;
            }

            // Cerrar conexión FTP
            //ftp_close($ftp_conn);
            //return '';
        } else {
            print_r("No se pudo conectar o iniciar sesión en el servidor FTP." . PHP_EOL);
            // $log->appendLog("No se pudo conectar o iniciar sesión en el servidor FTP." . PHP_EOL);
            return '';
        }

    }



    function UploadVoucherToWordpressByImageFileName($imageFileName): string
    {

        $log = PluginLogManager::create(); //Initialize Logger
        $configManager = PluginConfigManager::create();
        $config = $configManager->loadConfig();

        // Configuración de conexión FTP
        $ftp_server = $config['hostServerFTP'];
        $ftp_username = $config['usernameServerFTP'];
        $ftp_password = $config['passServerFTP'];
        $remote_folder = "/public_html/wp/wp-content/uploads/vouchers_oxxo/";

        $log->appendLog("Subiendo voucher a worpdpress " . PHP_EOL);
        // Configuración de conexión FTP
        $remote_file = "/public_html/wp/wp-content/uploads/vouchers_oxxo/" . $imageFileName;
        $file_to_upload = __DIR__ . '/../../vouchers_oxxo/' . $imageFileName;
        $url = 'https://siip.mx/wp/wp-content/uploads/vouchers_oxxo/' . $imageFileName;

        $log->appendLog("file_to_upload: " . $file_to_upload . PHP_EOL);

        // Conexión FTP
        $ftp_conn = ftp_connect($ftp_server) or die("No se pudo conectar al servidor FTP");
        $login = ftp_login($ftp_conn, $ftp_username, $ftp_password);
        ftp_pasv($ftp_conn, true);
        // Verificar conexión y login
        if ($ftp_conn && $login) {
            $log->appendLog("Conexión FTP exitosa" . PHP_EOL);

            // Cargar archivo
            if (ftp_put($ftp_conn, $remote_file, $file_to_upload, FTP_BINARY)) {
                $log->appendLog("El archivo  ha sido cargado exitosamente." . PHP_EOL);
                $log->appendLog("La URL es: " . $url . PHP_EOL);

                // try {
                //     $this->deleteFilesWordpressExceptLastHundred($log, $ftp_conn, $remote_folder);
                // } catch (\Exception $e) {
                //     $log->appendLog("Error en limpieza de archivos antiguos: " . $e->getMessage() . PHP_EOL);
                // }
                
                // Cerrar conexión FTP (o dejar abierta si se prefiere, pero mejor cerrar al final si es posible, aunque aquí retornamos directo)
                // ftp_close($ftp_conn); 
                // Cerrar conexión FTP
                //ftp_close($ftp_conn); //COMENTAR AQUÍ SI SE BORRAN LOS ARCHIVOS DE WORDPRESS DESCOMENTANDO EL CÓDIGO DE MÁS ABAJO
                return $url;          //COMENTAR AQUÍ SI SE BORRAN LOS ARCHIVOS DE WORDPRESS DESCOMENTANDO EL CÓDIGO DE MÁS ABAJO

            } else {
                $log->appendLog("Error al cargar el archivo " . PHP_EOL);
                ftp_close($ftp_conn);
                return '';
            }

            //SI SE DECIDE VOLVER A ELIMINAR LOS COMPROBANTES ENTONCES DESCOMENTAR ESTA PARTE DE ABAJO Y COMENTAR LA SECCIÓN DE ARRIBA

            // Obtener lista de archivos en la carpeta
            // $files = ftp_nlist($ftp_conn, $remote_folder);
            // if (is_array($files)) {
            //     // Eliminar la ruta del directorio de los archivos
            //     $files = array_map(function ($file) use ($remote_folder) {
            //         return str_replace($remote_folder, '', $file);
            //     }, $files);

            //     // Obtener fechas de modificación
            //     $filesWithTime = [];
            //     foreach ($files as $file) {
            //         $modifiedTime = ftp_mdtm($ftp_conn, $remote_folder . $file);
            //         if ($modifiedTime != -1) {
            //             $filesWithTime[$file] = $modifiedTime;
            //         }
            //     }

            //     // Ordenar archivos por fecha de modificación, más recientes primero
            //     arsort($filesWithTime);

            //     // Obtener los archivos a eliminar (todos menos los 50 más recientes)
            //     $filesToDelete = array_slice(array_keys($filesWithTime), 50);

            //     // Eliminar archivos antiguos
            //     foreach ($filesToDelete as $file) {
            //         if (ftp_delete($ftp_conn, $remote_folder . $file)) {
            //             $log->appendLog("Comprobante eliminado de Wordpress: " . $file . PHP_EOL);
            //         } else {
            //             $log->appendLog('Error al borrar comprobante' . $file . PHP_EOL);
            //         }
            //     }
            //     $log->appendLog("Archivos eliminados" . PHP_EOL);
            //     ftp_close($ftp_conn);
            //     return $url;
            // } else {
            //     $log->appendLog("No se pudo obtener la lista de archivos de la carpeta FTP" . PHP_EOL);
            // ftp_close($ftp_conn);
            // return $url;
            // }

        } else {
            $log->appendLog("No se pudo conectar o iniciar sesión en el servidor FTP." . PHP_EOL);
            return '';
        }
    }

    function deleteFilesWordpressExceptLastHundred($log, $ftp_conn, $remote_folder): bool
    {

        // Obtener lista de archivos en la carpeta
        $files = ftp_nlist($ftp_conn, $remote_folder);
        if (is_array($files)) {
            // Eliminar la ruta del directorio de los archivos
            $files = array_map(function ($file) use ($remote_folder) {
                return str_replace($remote_folder, '', $file);
            }, $files);

            // Obtener fechas de modificación
            $filesWithTime = [];
            foreach ($files as $file) {
                $modifiedTime = ftp_mdtm($ftp_conn, $remote_folder . $file);
                if ($modifiedTime != -1) {
                    $filesWithTime[$file] = $modifiedTime;
                }
            }

            // Ordenar archivos por fecha de modificación, más recientes primero
            arsort($filesWithTime);

            // Obtener los archivos a eliminar (todos menos los 50 más recientes)
            $filesToDelete = array_slice(array_keys($filesWithTime), 50);

            // Eliminar archivos antiguos
            foreach ($filesToDelete as $file) {
                if (ftp_delete($ftp_conn, $remote_folder . $file)) {
                    $log->appendLog("Voucher eliminado de Wordpress: " . $file . PHP_EOL);
                } else {
                    $log->appendLog('Error al borrar voucher' . $file . PHP_EOL);
                }
            }
            $log->appendLog("Archivos eliminados" . PHP_EOL);
            ftp_close($ftp_conn);
            return true;
        } else {
            $log->appendLog("No se pudo obtener la lista de archivos de la carpeta FTP" . PHP_EOL);
            ftp_close($ftp_conn);
            return false;
        }
    }

}
