<?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 UcrmApi
     */
    protected $ucrmApi;

    protected $stripeCustomAttributeID;
    protected $clabeInterbancariaBanamexID;

    public function __construct(
        Logger $logger,
        MessageTextFactory $messageTextFactory,
        SmsNumberProvider $clientPhoneNumber
    ) {
        $this->logger = $logger;
        $this->messageTextFactory = $messageTextFactory;
        $this->clientPhoneNumber = $clientPhoneNumber;
    }

    /*
     * 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): array
    {
        //declarar un array asociativo de strings pero no asignarle nada aun
        $arrayOxxoPayment = array();
        $integerAmount = $amount;

        $this->logger->info("Creando referencia del cliente para OXXO: " . PHP_EOL);
        $configManager = PluginConfigManager::create();
        $config = $configManager->loadConfig();
        $StripeToken = $config['tokenstripe'];
        $IPServer = $config['ipserver'];
        $tokenCRM = $config['apitoken'];
        $ipPuppeteer = $config['ipPuppeteer'];
        $portPuppeteer = $config['portPuppeteer'];

        $baseUri = 'https://' . $IPServer . '/crm/api/v1.0/';
        $this->ucrmApi = UcrmApi::create();
        $currentUserAdmin = $this->ucrmApi->get('users/admins', []);
        $clientID = $event_json['client_id'];

        $stripeCustomerId = null;
        $clientEmail = '';
        $clientFullName = '';

        $clientGuzzleHttp = new Client([
            'base_uri' => $baseUri,
            'headers' => [
                'X-Auth-App-Key' => $tokenCRM,
                'Accept' => 'application/json',
            ],
            'verify' => false,
            'timeout' => 5, // Timeout de 5 segundos
        ]);

        try {
            $response = $clientGuzzleHttp->request('GET', "clients/" . $clientID);
            $arrayClientCRM = json_decode($response->getBody()->getContents(), true);
            //$this->logger->info("Valor de arrayClientCRM: " . print_r($arrayClientCRM, true) . PHP_EOL);
            $clientFullName = $arrayClientCRM['firstName'] . ' ' . $arrayClientCRM['lastName'];
        } catch (RequestException $e) {
            if ($e->getCode() === 404) {
                $this->logger->error("Cliente no encontrado en CRM: " . $clientID . PHP_EOL);
                //devolver un array con los campos del codigo error, descripción de la falla, clientID, clientFullName y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorGetClientNotFound';
                $arrayOxxoPayment['failDescription'] = 'Cliente no encontrado en CRM: ' . $clientID;
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $integerAmount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;


            }
            //timeout
            if ($e->getCode() === 408) {
                $this->logger->error("Timeout al obtener el cliente en CRM: " . $clientID . PHP_EOL);
                //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorTimeoutGetClient';
                $arrayOxxoPayment['failDescription'] = 'Timeout al obtener el cliente en CRM: ' . $clientID;
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $integerAmount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;
            }
            $this->logger->error("Error al obtener el cliente en CRM (Error {$e->getCode()}): " . $e->getMessage() . PHP_EOL);
            //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
            $arrayOxxoPayment['oxxo_reference'] = '';
            $arrayOxxoPayment['url'] = '';
            $arrayOxxoPayment['error'] = 'errorGetClient';
            $arrayOxxoPayment['failDescription'] = 'Error al obtener el cliente en CRM: ' . $clientID;
            $arrayOxxoPayment['clientID'] = $clientID;
            $arrayOxxoPayment['clientFullName'] = $clientFullName;
            $arrayOxxoPayment['amount'] = $integerAmount;
            $arrayOxxoPayment['voucher_image_url'] = '';
            return $arrayOxxoPayment;

        }

        // Obtener email del cliente
        foreach ($arrayClientCRM['contacts'] as $contact) {
            if (!empty($contact['email'])) {
                $clientEmail = $contact['email'];
                break;
            } else {
                $clientEmail = 'siip8873@gmail.com';  // Default
            }
        }

        try {
            // Obtener stripeCustomerId
            foreach ($arrayClientCRM['attributes'] as $attribute) {
                if ($attribute['key'] === 'stripeCustomerId') {
                    $stripeCustomerId = $attribute['value'];
                    break;
                }
            }

            $this->logger->info("Stripe Customer ID obtenido: " . $stripeCustomerId . PHP_EOL);
        } catch (Exception $e) {
            $this->logger->error("Error al obtener el Customer ID de Stripe (Error {$e->getCode()}): " . $e->getMessage() . PHP_EOL);
            //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
            $arrayOxxoPayment['oxxo_reference'] = '';
            $arrayOxxoPayment['error'] = 'errorGetCustomerStripe';
            $arrayOxxoPayment['failDescription'] = 'Error al obtener el Customer ID de Stripe: ' . $clientID;
            $arrayOxxoPayment['clientID'] = $clientID;
            $arrayOxxoPayment['clientFullName'] = $clientFullName;
            $arrayOxxoPayment['amount'] = $integerAmount;
            $arrayOxxoPayment['voucher_image_url'] = '';
            return $arrayOxxoPayment;
        }

        if ($amount === null) {
            $amount = abs($arrayClientCRM['accountOutstanding']); //Monto adeudado del cliente
        } else {
            //la variable $amount debe ser numérica pero en ocasiones la solicitud puede traer signos o alguna letra ingresada mal por el cliente, se debe analizar para limpiar cualquier caracter que no sea numérico
            if(!is_numeric($amount)) {
                $amount = preg_replace('/[^\d.]/', '', $amount); // Eliminar todo lo que no sea dígito o punto decimal
            }
            $this->logger->debug("Monto proporcionado directamente: $amount " . PHP_EOL);
        }

        if ($amount > 10) {
            $amountInCents = intval($amount * 100); // Convertir a centavos

            try {
                $this->logger->debug("Creando referencia en Stripe por $amount para el cliente $stripeCustomerId" . PHP_EOL);
                $guzzleClient = new Client([
                    'timeout' => 5, // Timeout de 5 segundos
                ]);

                $response = $guzzleClient->post('https://api.stripe.com/v1/payment_intents', [
                    'auth' => [$StripeToken, ''],
                    'form_params' => [
                        'amount' => $amountInCents,
                        'currency' => 'mxn',
                        'payment_method_types' => ['customer_balance', 'card', 'oxxo'],
                        'description' => 'Pago de servicio de SIIP Internet',
                        'customer' => $stripeCustomerId,
                        'metadata' => [
                            'clientId' => $clientID,
                            'createdBy' => 'UCRM',
                            'paymentType' => 'card.one_time',
                            'signedInAdminId' => $currentUserAdmin[1]['id'],
                            'tipoPago' => 'OXXO',
                        ],
                        'payment_method_options' => [
                            'oxxo' => [
                                'expires_after_days' => 3,
                            ],
                        ],
                    ]
                ]);

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

            } catch (\Stripe\Exception\ApiConnectionException $e) {
                $this->logger->error("Error de conexión con Stripe (Error {$e->getCode()}): " . $e->getMessage() . PHP_EOL);
                //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorConnectionStripe';
                $arrayOxxoPayment['failDescription'] = 'Error de conexión con Stripe: ' . $clientID;
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $amount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;

            } catch (\Stripe\Exception\ApiErrorException $e) {
                $this->logger->error("Error de la API de Stripe: " . $e->getMessage() . PHP_EOL);
                //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorApiStripe';
                $arrayOxxoPayment['failDescription'] = 'Error de la API de Stripe: ' . $clientID;
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $amount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;

            } catch (Exception $e) {
                $this->logger->error("Error inesperado al crear PaymentIntent (Error {$e->getCode()}): " . $e->getMessage() . PHP_EOL);
                //si e->getMessage incluye el mensaje: You must provide a customer when creating or updating a PaymentIntent with a `customer_ba (truncated...) declarar una variable y ahi poner "Este cliente no tiene cuenta de Stripe"
                if ($e->getMessage() == 'You must provide a customer when creating or updating a PaymentIntent with a `customer_ba (truncated...)') {
                    $this->logger->error("Este cliente no tiene cuenta de Stripe" . PHP_EOL);
                    $arrayOxxoPayment['failDescription'] = 'Este cliente no tiene cuenta de Stripe: ' . $clientID;
                } else {
                    $this->logger->error("Error inesperado al crear PaymentIntent: " . $e->getMessage() . PHP_EOL);
                    $arrayOxxoPayment['failDescription'] = 'Error inesperado al crear PaymentIntent: ' . $clientID;
                }
                //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorCreatePaymentIntent';
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $amount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;

            }

            try {
                $firstName = isset($arrayClientCRM['firstName']) ? trim($arrayClientCRM['firstName']) : '';
                $lastName = isset($arrayClientCRM['lastName']) ? trim($arrayClientCRM['lastName']) : '';

                if (strlen($firstName) < 2 || strlen($lastName) < 2) {
                    $this->logger->error("Nombre/apellido inválido: ' . $firstName . ' ' . $lastName" . PHP_EOL);
                    //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                    $arrayOxxoPayment['oxxo_reference'] = '';
                    $arrayOxxoPayment['url'] = '';
                    $arrayOxxoPayment['error'] = 'errorNombreApellidoInvalido';
                    $arrayOxxoPayment['failDescription'] = "Nombre/apellido inválido: ' . $firstName . ' ' . $lastName";
                    $arrayOxxoPayment['clientID'] = $clientID;
                    $arrayOxxoPayment['clientFullName'] = $clientFullName;
                    $arrayOxxoPayment['amount'] = $amount;
                    $arrayOxxoPayment['voucher_image_url'] = '';
                    return $arrayOxxoPayment;

                }

                $responsePaymentMethod = $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($responsePaymentMethod->getBody()->getContents(), true);

                $responseConfirmPaymentIntent = $guzzleClient->post('https://api.stripe.com/v1/payment_intents/' . $paymentIntent['id'] . '/confirm', [
                    'auth' => [$StripeToken, ''],
                    'form_params' => [
                        'payment_method' => $paymentMethod['id'],
                    ]
                ]);

                $paymentIntentConfirm = json_decode($responseConfirmPaymentIntent->getBody()->getContents(), true);

            } catch (Exception $e) {
                $this->logger->error("Error al confirmar PaymentIntent: " . $e->getMessage() . PHP_EOL);
                //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorConfirmPaymentIntent';
                $arrayOxxoPayment['failDescription'] = 'Error al confirmar PaymentIntent: ' . $e->getMessage();
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $amount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;
            }

            if (!empty($paymentIntentConfirm['next_action']) && isset($paymentIntentConfirm['next_action']['oxxo_display_details'])) {
                $oxxoPayment = $paymentIntentConfirm['next_action']['oxxo_display_details'];
                $oxxo_reference = $oxxoPayment['number'];
                $oxxo_receipt_url = $oxxoPayment['hosted_voucher_url'];

                $this->logger->info("Referencia OXXO: " . $oxxo_reference . PHP_EOL);
                $this->logger->info("URL del recibo: " . $oxxo_receipt_url . PHP_EOL);
                //$this->captureScreenshot($oxxo_receipt_url);
                //devolver un array con los campos de url de oxxo, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = $oxxo_reference;
                $arrayOxxoPayment['url'] = $oxxo_receipt_url;
                $arrayOxxoPayment['error'] = '';
                $arrayOxxoPayment['failDescription'] = '';
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $amount;
                $this->logger->info("Referencia OXXO creada correctamente." . PHP_EOL);

                
                // Configuración de la API de tu servicio Docker de Puppeteer
                $api_url = 'http://'.$ipPuppeteer.':'.$portPuppeteer.'/screenshot'; // Asegúrate que esta URL sea accesible

                // --- Datos para la petición ---
                $request_data = [
                    'url' => $oxxo_receipt_url, // URL del recibo de OXXO
                    // Opcional: Si quieres recortar la imagen, descomenta y ajusta el 'clip'

                    'clip' => [
                        'x' => 325,
                        'y' => 30,
                        'width' => 550,
                        'height' => 550
                    ]

                ];

                // Nombre del archivo donde se guardará la imagen
                $clientFullNameWithoutSpaces = str_replace(' ', '_', $clientFullName); // Reemplazar espacios por guiones bajos
                $voucherFileName = 'voucher_'.$clientFullNameWithoutSpaces.'_' . time() . '.jpeg'; // Usamos .jpeg por defecto
                $output_filename = __DIR__ . '/../../vouchers_oxxo/' . $voucherFileName; // Usamos .jpeg por defecto
                $output_filename = realpath(__DIR__ . '/../../vouchers_oxxo') . '/'. $voucherFileName;  // Mejor: ruta absoluta y verifica que el directorio exista
                //$output_filename = '/path/to/vouchers_oxxo/voucher_' . time() . '.jpeg'; // Mejor aún: ruta absoluta y fija, si es posible

                $guzzleClient = new Client([
                    'timeout' => 5, // Timeout de 5 segundos
                ]);
                // Descargar el recibo de OXXO
                try {
                    // --- Realizar la petición POST ---
                    $response = $guzzleClient->post($api_url, [
                        'json' => $request_data, // Guzzle codifica automáticamente el array a JSON y establece Content-Type: application/json
                        'headers' => [
                            'Accept' => 'image/jpeg, image/png', // Indicar que esperamos una imagen
                        ],
                        // Opcional: para depuración si necesitas ver el cuerpo de la respuesta en caso de error
                        // 'http_errors' => false // Desactiva las excepciones para códigos de estado 4xx/5xx y maneja la respuesta manualmente
                    ]);

                    // --- Procesar la respuesta ---
                    $statusCode = $response->getStatusCode();
                    $contentType = $response->getHeaderLine('Content-Type');

                    $this->logger->debug("Status Code: " . $statusCode);
                    $this->logger->debug("Content Type: " . $contentType);

                    if ($statusCode === 200 && str_contains($contentType, 'image/')) {
                        // La respuesta es una imagen y el código de estado es 200 OK
                        $image_content = $response->getBody()->getContents();

                        // *** VERIFICACIÓN IMPORTANTE: ***
                        if (file_put_contents($output_filename, $image_content)) {
                            $this->logger->debug("¡Imagen guardada exitosamente en: " . $output_filename);
                            $url_file = $this->UploadVoucherToWordpressByImageFileName($voucherFileName); //Carga del comprobante PDF a Wordpress para su posterior envío
                            $arrayOxxoPayment['voucher_image_url'] = $url_file; // Agregar la URL del archivo de imagen al array
                        } else {
                            $this->logger->error("Error: No se pudo guardar la imagen en " . $output_filename);
                            $this->logger->error("Ruta del archivo: " . $output_filename); // Agregado para depuración
                            $this->logger->error("Directorio del script: " . __DIR__); // Agregado para depuración
                            $this->logger->error("Error de PHP: " . error_get_last()['message']); // Agregado para depuración
                        }
                    } else {
                        // No es una imagen o hubo un error en el servicio
                        $this->logger->debug("Error: La respuesta no es una imagen o el código de estado no es 200 OK.");
                        $this->logger->debug("Cuerpo de la respuesta: " . $response->getBody()->getContents());
                    }

                } catch (RequestException $e) {
                    // Manejo de errores de red o del servidor (ej. timeouts, 4xx, 5xx si http_errors no es false)
                    $this->logger->error("Error en la petición: " . $e->getMessage());
                    if ($e->hasResponse()) {
                        $this->logger->error("Cuerpo de la respuesta de error: " . $e->getResponse()->getBody()->getContents());
                        $this->logger->error("Código de estado HTTP de error: " . $e->getResponse()->getStatusCode());
                    }
                } catch (Exception $e) {
                    // Otros errores inesperados
                    $this->logger->error("Error inesperado: " . $e->getMessage());
                }




                return $arrayOxxoPayment;
            } else {
                $this->logger->info("El PaymentIntent no tiene detalles de OXXO disponibles. Estado: " . $paymentIntentConfirm['status'] . PHP_EOL);
                //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
                $arrayOxxoPayment['oxxo_reference'] = '';
                $arrayOxxoPayment['url'] = '';
                $arrayOxxoPayment['error'] = 'errorPaymentIntentWithoutOxxoDetails';
                $arrayOxxoPayment['failDescription'] = 'El PaymentIntent no tiene detalles de OXXO disponibles. Estado: ' . $paymentIntentConfirm['status'];
                $arrayOxxoPayment['clientID'] = $clientID;
                $arrayOxxoPayment['clientFullName'] = $clientFullName;
                $arrayOxxoPayment['amount'] = $amount;
                $arrayOxxoPayment['voucher_image_url'] = '';
                return $arrayOxxoPayment;

            }

        } else {
            $this->logger->info("Este cliente no tiene adeudos." . PHP_EOL);
            //devolver un array con los campos del codigo error, descripción de la falla, clientID y amount
            $arrayOxxoPayment['oxxo_reference'] = '';
            $arrayOxxoPayment['url'] = '';
            $arrayOxxoPayment['error'] = 'errorsinadeudo';
            $arrayOxxoPayment['failDescription'] = 'Este cliente no tiene adeudos.';
            $arrayOxxoPayment['clientID'] = $clientID;
            $arrayOxxoPayment['clientFullName'] = $clientFullName;
            $arrayOxxoPayment['amount'] = $amount;
            $arrayOxxoPayment['voucher_image_url'] = '';
            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
        $ftp_server = "siip.mx";
        $ftp_username = "siip0001";
        $ftp_password = '$spGiT,[wa)n';
        $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
        // $ftp_server = "siip.mx";
        // $ftp_username = "siip0001";
        // $ftp_password = '$spGiT,[wa)n';
        $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);

                $this->deleteFilesWordpressExceptLastHundred($log, $ftp_conn, $remote_file);
                // 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;
        }
    }

}
