<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ClientException;

require(__DIR__ . '/vendor/autoload.php');


$ucrmBaseUri = 'https://172.16.5.120/crm/api/v1.0/'; //endpoint  de la API REST del CRM
$unmsBaseUri = 'https://172.16.5.120/nms/api/v2.1/'; //endpoint  de la API REST del UISP NMS
$token = '7adc9198-50b1-41d0-9bfa-d4946902ed89'; //Token  para acceder a los recursos del CRM
// $ucrmBaseUri = 'https://172.16.5.134/crm/api/v1.0/'; //endpoint  de la API REST del CRM
// $token = '6abef18c-783d-4dd0-b530-be6e6a7bbd1d'; //Token  para acceder a los recursos del CRM

$stripe = new \Stripe\StripeClient('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'); //Token de clave privada en modo prodcucción para la API de Stripe
$CallBellAPIToken = 'g8thcZkXGd3xBj2g3TtYNYFMH1fuesbJ.b6a940ea7d78cf6c9e42f067b21c8ddf96e9fa2a9e307bfd0c7c7c4d7fa38f79';

// $ucrmBaseUri = 'https://172.16.5.134/crm/api/v1.0/'; //endpoint  de la API REST del CRM
// $token = '6abef18c-783d-4dd0-b530-be6e6a7bbd1d'; //Token  para acceder a los recursos del CRM
// $stripe = new \Stripe\StripeClient('sk_test_51OkG0REFY1WEUtgRH6UxBK5pu80Aq5Iy8EcdPnf0cOWzuVLQTpyLCd7CbPzqMsWMafZOHElCxhEHF7g8boURjWlJ00tBwE0W1M'); //Token de clave privada en modo prueba para la API de Stripe
// $CallBellAPIToken = 'g8thcZkXGd3xBj2g3TtYNYFMH1fuesbJ.b6a940ea7d78cf6c9e42f067b21c8ddf96e9fa2a9e307bfd0c7c7c4d7fa38f79'; // Add this line

//cliente GuzzleHttp para consumir API del UISP CRM
$clientGuzzleHttp = new Client([
    'base_uri' => $ucrmBaseUri,
    'headers' => [
        'X-Auth-App-Key' => $token,
        'Accept' => 'application/json',
    ],
    'verify' => false,
    'timeout' => 5, // Timeout de 5 segundos
]);


// $archivoCsv = './proceso-crm-callbell.csv';  //ruta al archivo csv
$archivoCsv = './ProcesoActualizarSaldosCRM-To-CallBell.csv';  //ruta al archivo csv
// $archivoCsv = './Client_IDs_CRM.csv';  //ruta al archivo csv
$columnaDeseada = 0; // Columna para leer del archivo csv
$hayTituloColumna = false; // Variable de control para detectar la primera fila e ignorarla ya que son las columnas
$ucrm_client_id;
$error = 0; // Variable de control para detectar si hubo un error al procesar el cliente

if (($gestor = fopen($archivoCsv, 'r')) !== false) {
    $mensaje = '************************************************************ COMIENZA EL PROCESO *****************************************' . PHP_EOL;
    log_message($mensaje);
    print_r('************************************************************ COMIENZA EL PROCESO *****************************************' . PHP_EOL);

    while (($fila = fgetcsv($gestor, 1000, ',')) !== false) {
        //sleep(1);
        if ($hayTituloColumna) {
            // Si es la primera fila, cambia la variable de control y pasa a la siguiente iteración donde empiezan los datos
            $hayTituloColumna = false;
            // $lineasProcesadas[] = $fila;
            print_r('Ignoramos la fila de las columnas: ' . $fila[0] . PHP_EOL);
            continue;
        }

        // Verificar si la fila del archivo csv tiene la columna deseada
        if (isset($fila[$columnaDeseada])) {
            // Para cada client ID que vaya leyendo aquí entonces obtenemos por medio del API de UCRM los datos del cliente para mandarlos al Stripe

            print_r('________________________________________________________________________________' . PHP_EOL);
            $logMessage = '________________________________________________________________________________' . PHP_EOL;
            log_message($logMessage);

            print_r('Registro del archivo csv: ' . $fila[$columnaDeseada] . PHP_EOL);
            $logMessage = 'Registro del archivo csv: ' . $fila[$columnaDeseada] . PHP_EOL;
            log_message($logMessage);
            $ucrm_client_id = $fila[$columnaDeseada];
            $responseCRM = null;
            $stripeNuevaClabeInterbancariaUCRM = '';
            $clientNetworkData = getClientDataNetwork($ucrm_client_id, $token);
            $passwordAntenaCliente = '';
            $urlChatCallBell = ''; //URL del chat de CallBell
            $uuid = ''; //UUID del contacto en CallBell



            try {
                $responseCRM = $clientGuzzleHttp->get('clients/' . $ucrm_client_id);

                // print_r("Response from CRM: " . $responseCRM->getBody() . PHP_EOL); // Debug message
            } catch (ClientException $e) {
                if ($e->getResponse()->getStatusCode() === 404) {
                    $logMessage = "Cliente no encontrado en el CRM: " . $ucrm_client_id;
                    log_message($logMessage);
                    print_r("Cliente no encontrado en el CRM: " . $ucrm_client_id);
                } else {
                    $logMessage = sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage());
                    log_message($logMessage);
                    print_r(sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage()));
                }
                $responseCRM = null;
            } catch (RequestException $e) {
                //timeout
                if ($e->getCode() === 408) {
                    $logMessage = sprintf("Error de timeout al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage());
                    log_message($logMessage);
                    print_r(sprintf("Error de timeout al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage()));
                } else {
                    $logMessage = sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage());
                    log_message($logMessage);
                    print_r(sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage()));
                }
                $responseCRM = null;
            }

            // Verificar si la solicitud fue exitosa (código de estado 200)
            if ($responseCRM && $responseCRM->getStatusCode() === 200) {
                print_r("Solicitud exitosa de datos para el cliente: " . $ucrm_client_id . PHP_EOL);


                //Decodificar la respuesta del API UISP CRM a JSON
                $responseBody = $responseCRM->getBody();
                //echo 'response del body: ' . $responseBody; // Verifica la salida en tu consola o log
                $dataCRM = json_decode($responseBody, true);
                //$clientCRM = json_decode($responseCRM->getBody();


                try {
                    $responseCRMPayments = $clientGuzzleHttp->get('payments?clientId=' . $ucrm_client_id . '&limit=1&direction=DESC'); //Obtener el último pago del cliente

                    // print_r("Response from CRM: " . $responseCRM->getBody() . PHP_EOL); // Debug message
                } catch (GuzzleHttp\Exception\ClientException $e) {
                    if ($e->getResponse()->getStatusCode() === 404) {
                        $logMessage = "Pago no encontrado en el CRM: " . $ucrm_client_id;
                        log_message($logMessage);
                        print_r("Pago no encontrado en el CRM: " . $ucrm_client_id);
                    } else {
                        $logMessage = sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage());
                        log_message($logMessage);
                        print_r(sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage()));
                    }
                    $responseCRM = null;
                } catch (RequestException $e) {
                    //timeout
                    if ($e->getCode() === 408) {
                        $logMessage = sprintf("Error de timeout al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage());
                        log_message($logMessage);
                        print_r(sprintf("Error de timeout al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage()));
                    } else {
                        $logMessage = sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage());
                        log_message($logMessage);
                        print_r(sprintf("Error al realizar la solicitud con el cliente: %s con el error %s", $ucrm_client_id, $e->getMessage()));
                    }

                    $responseCRM = null;
                }





                //Si $el response code $responseCRMPayments es 200 entonces se obtiene el último pago del cliente
                if ($responseCRMPayments && $responseCRMPayments->getStatusCode() === 200) {
                    $paymentData = json_decode($responseCRMPayments->getBody(), true); // Decodificamos la respuesta del API UISP CRM a JSON
                    print_r("Solicitud exitosa de datos para el último pago del cliente: " . $ucrm_client_id . PHP_EOL);
                    log_message("Solicitud exitosa de datos para el último pago del cliente: " . $ucrm_client_id . PHP_EOL);
                } else {
                    print_r("Error al obtener el último pago del cliente: " . $ucrm_client_id . PHP_EOL);
                    log_message("Error al obtener el último pago del cliente: " . $ucrm_client_id . PHP_EOL);
                    $error = 1; //Error al obtener el último pago del cliente
                    continue; // Salir del bucle actual y continuar con la siguiente iteración
                }



                //print_r("último pago del cliente: " . json_encode($responseCRMPayments));

                $clienteJson = extraerDatosCliente(json_encode($dataCRM));
                //print_r(($clienteJson) . PHP_EOL);
                // Decodificamos el JSON para acceder a los valores
                $clienteData = json_decode($clienteJson, true);


                //ejemplo en json de attributes: {"attributes":[{"id":21180,"clientId":3201,"customAttributeId":35,"name":"Site","key":"site","value":"0LOCS","clientZoneVisible":true},{"id":18147,"clientId":3201,"customAttributeId":1,"name":"ip","key":"ip","value":"172.16.13.64","clientZoneVisible":false},{"id":19859,"clientId":3201,"customAttributeId":29,"name":"Stripe Customer ID","key":"stripeCustomerId","value":"cus_RKiSN955qKhmch","clientZoneVisible":true},{"id":19860,"clientId":3201,"customAttributeId":30,"name":"Clabe Interbancaria","key":"clabeInterbancaria","value":"124180650741646979","clientZoneVisible":true},{"id":27184,"clientId":3201,"customAttributeId":21,"name":"Chat de CallBell","key":"chatDeCallbell","value":"https://dash.callbell.eu/chat/53c8229c428c4081b197ab136feab73b","clientZoneVisible":false},{"id":21181,"clientId":3201,"customAttributeId":36,"name":"Antena/Sectorial","key":"antenaSectorial","value":"Sectorial-4b 172.16.13.16/24","clientZoneVisible":true},{"id":28687,"clientId":3201,"customAttributeId":22,"name":"uuid","key":"uuid","value":"74cc2bb45eb8409f92cd5dba99200d26","clientZoneVisible":false}]}
                //buscar la clave passwordAntenaCliente en el json de attributes o sea en la variable $dataCRM

                foreach ($dataCRM['attributes'] as $attribute) {
                    if ($attribute['key'] === 'passwordAntenaCliente') {
                        $passwordAntenaCliente = $attribute['value'];
                        break; // Salir del bucle una vez que se encue-ntra la clave
                    }
                }

                if ($passwordAntenaCliente === null || $passwordAntenaCliente === '') {
                    $passwordAntenaCliente = getVaultCredentials($ucrm_client_id, $token, $ucrmBaseUri, $unmsBaseUri);
                    if ($passwordAntenaCliente === null) {
                        $logMessage = print_r("No se encontró la contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida." . PHP_EOL, true);
                        log_message($logMessage);
                        print_r("No se encontró la contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida." . PHP_EOL);
                        $passwordAntenaCliente = 'Sin contraseña de bóveda, es probable que tenga una conocida'; // Asignar un valor por defecto o manejar el caso según sea necesario
                        if (isset($clientNetworkData['siteName']) && isset($clientNetworkData['device'])) {
                            $responsePatchCRM = patchClientCRM($clientNetworkData['siteName'], $clientNetworkData['device'] . ' ' . $clientNetworkData['ipDevice'], $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, $passwordAntenaCliente);
                            print_r("responsePatchCRM: " . $responsePatchCRM . PHP_EOL);
                        }
                    } else {
                        $logMessage = print_r("Se encontró la contraseña en la bóveda para la antena de este cliente: " . $passwordAntenaCliente . PHP_EOL, true);
                        log_message($logMessage);
                        print_r("Se encontró la contraseña en la bóveda para la antena de este cliente: " . $passwordAntenaCliente . PHP_EOL);
                        if (isset($clientNetworkData['siteName']) && isset($clientNetworkData['device'])) {
                            $responsePatchCRM = patchClientCRM($clientNetworkData['siteName'], $clientNetworkData['device'] . ' ' . $clientNetworkData['ipDevice'], $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, $passwordAntenaCliente);
                            print_r("responsePatchCRM: " . $responsePatchCRM . PHP_EOL);
                        }
                    }
                } else if (strpos($passwordAntenaCliente, "Error: No se encontró una") === 0) { //evalular si la contraseña es decir la variable $passwordAntenaCliente comienza con la cadena 'Error: No se encontró una contraseña'
                    $newPasswordAntenaCliente = generateVaultCredentials($ucrm_client_id, $token, $ucrmBaseUri, $unmsBaseUri);
                    if ($newPasswordAntenaCliente === null || $newPasswordAntenaCliente === '') {
                        $logMessage = "No se pudo generar la contraseña de la bóveda para la antena de este cliente: " . $ucrm_client_id . PHP_EOL;
                        log_message($logMessage);
                        print_r("No se pudo generar la contraseña de la bóveda para la antena de este cliente: " . $ucrm_client_id . PHP_EOL);
                        $newPasswordAntenaCliente = 'No se pudo generar la contraseña de la bóveda para la antena de este cliente: ' . $ucrm_client_id . PHP_EOL; // Asignar un valor por defecto o manejar el caso según sea necesario
                        if (isset($clientNetworkData['siteName']) && isset($clientNetworkData['device'])) {
                            $responsePatchCRM = patchClientCRM($clientNetworkData['siteName'], $clientNetworkData['device'] . ' ' . $clientNetworkData['ipDevice'], $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, $newPasswordAntenaCliente);
                            print_r("responsePatchCRM: " . $responsePatchCRM . PHP_EOL);
                        }
                    } else {
                        $logMessage = "Se generó una nueva contraseña en la bóveda para la antena de este cliente: " . $newPasswordAntenaCliente . PHP_EOL;
                        log_message($logMessage);
                        print_r("Se generó una nueva contraseña en la bóveda para la antena de este cliente: " . $newPasswordAntenaCliente . PHP_EOL);
                        if (isset($clientNetworkData['siteName']) && isset($clientNetworkData['device'])) {
                            $responsePatchCRM = patchClientCRM($clientNetworkData['siteName'], $clientNetworkData['device'] . ' ' . $clientNetworkData['ipDevice'], $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, $newPasswordAntenaCliente);
                            print_r("responsePatchCRM: " . $responsePatchCRM . PHP_EOL);
                        }
                    }
                } else {
                    $logMessage = "Ya está almacenada en el CRM la contraseña de la bóveda para la antena de este cliente: " . $passwordAntenaCliente . PHP_EOL;
                    log_message($logMessage);
                }


                if (isset($dataCRM['contacts'])) {
                    $arrayPhones = getCRMWhatsAppContact($dataCRM['contacts']);
                } else {
                    die("No se encontró la clave 'contacts' en el array.");
                }

                //print_r('valor de array phones: ' . json_encode($arrayPhones) . PHP_EOL);
                $urlChatCallBell = ''; //URL del chat de CallBell
                $uuid = ''; //UUID del contacto en CallBell

                // Procesar el array de teléfonos y ejecutar la función correspondiente
                foreach ($arrayPhones as $type => $phones) {

                    // Registrar el tipo de contacto antes de la normalización para verificar qué valor se recibe
                    //print_r("Procesando tipo de contacto original: '$type'");

                    // Normalizar el tipo para manejar posibles diferencias en las mayúsculas o espacios en blanco
                    $type = trim(strtolower($type));

                    // Registrar el tipo de contacto después de la normalización
                    //print_r("Tipo de contacto normalizado: '$type'");

                    // Asegurarse de que $phones es un array y recorrerlo
                    if (is_array($phones)) {
                        foreach ($phones as $phone) {
                            switch ($type) {
                                case 'whatsapp':
                                    // Ejecutar función de notificación y actualización
                                    $phone_ajustado = ajustarPrefijoTelefono($phone);
                                    // print_r("Contacto whatsapp: " . $phone_ajustado);
                                    // log_message("Contacto whatsapp: " . $phone_ajustado . PHP_EOL);
                                    $response_callbell = json_decode(getContactWhatsapp($phone, $CallBellAPIToken), true);
                                    //ejemplo de json de respuesta de la API de CallBell: {"contact":{"uuid":"74cc2bb45eb8409f92cd5dba99200d26","name":"DANIEL HUMBERTO SOTO VILLEGAS MAY","phoneNumber":"5214181878106","avatarUrl":null,"createdAt":"2024-01-08T17:04:13Z","closedAt":null,"source":"whatsapp","href":"https:\/\/dash.callbell.eu\/contacts\/74cc2bb45eb8409f92cd5dba99200d26","conversationHref":"https:\/\/dash.callbell.eu\/chat\/53c8229c428c4081b197ab136feab73b","tags":["ePA","LIA"],"assignedUser":null,"customFields":{"user entry point":"inbound_message","Clabe Interbancaria":"124180650741646979","Estado":"\ud83d\udfe2 Activo ","Antena\/Sectorial":"Sectorial-4b >> 172.16.13.16\/24","Domicilio":"\ud83d\udccd CALLE CHIAPAS #31, ZONA CENTRO, Dolores Hidalgo Cuna de la Independencia Nacional, 37800","Fecha Ultimo Pago":"\ud83d\udcc6\ud83d\udcb8 20\/02\/2025 23:17 con PayPal \ud83c\udf10\ud83d\udcb3","Saldo Actual":"\ud83d\udcb210 a favor","Fecha Ultima Actualizacion":"\ud83d\udcc6\ud83d\udd04\ufe0f 28\/02\/2025 02:46","Monto Ultimo Pago":"\ud83d\udcb2 10","Cliente":"3201","URL":"\ud83c\udf10 https:\/\/172.16.5.120\/crm\/client\/3201","Nombre":"\ud83d\udc64 DANIEL HUMBERTO SOTO VILLEGAS MAY","Site":"0LOCS","user name":"Daniel Humberto \ud83d\udc01","Resumen":"{\"Cliente\": \"3201\",\"Domicilio\": \"\ud83d\udccd CALLE CHIAPAS #31, ZONA CENTRO, Dolores Hidalgo Cuna de la Independencia Nacional, 37800\",\"Nombre\": \"\ud83d\udc64 DANIEL HUMBERTO SOTO VILLEGAS MAY\",\"URL\": \"\ud83c\udf10 https:\/\/172.16.5.120\/crm\/client\/3201\",\"Saldo Actual\": \"\ud83d\udcb210 a favor\",\"Monto Ultimo Pago\": \"\ud83d\udcb2 10\",\"Estado\": \"\ud83d\udfe2 Activo\",\"Fecha Ultimo Pago\": \"\ud83d\udcc6\ud83d\udcb0 20\/02\/2025 23:17 con PayPal \ud83c\udf10\ud83d\udcb3\",\"Fecha Ultima Actualizacion\": \"\ud83d\udcc6\ud83d\udd04\ufe0f 28\/02\/2025 02:46\",\"Clabe Interbancaria\": \"124180650741646979\"}"},"team":{"uuid":"5faeed738d6a44ccacf6509762eb288d","name":"General","default":true,"members":8,"createdAt":"2023-11-07T00:37:10Z"},"channel":{"uuid":"dbaa248932634e7ea4346a320960c24a","title":null,"type":"whatsapp","main":true},"blockedAt":null}}

                                    //obtener el url del chat de callbell

                                    //print_r("URL del chat de callbell: " . $urlChatCallBell . PHP_EOL);

                                    //compobar si el contacto ya existe en callbell
                                    if (isset($response_callbell['contact']['uuid'])) {
                                        $urlChatCallBell = $response_callbell['contact']['conversationHref'];
                                        $uuid = $response_callbell['contact']['uuid'];
                                        print_r("URL del chat de callbell: " . $urlChatCallBell . " para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                        log_message("URL del chat de callbell: " . $urlChatCallBell . " para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                        if (patchWhatsapp($response_callbell, $paymentData, $clienteData, $CallBellAPIToken)) {
                                            print_r("Se actualizó el contacto en callbell para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                            log_message("Se actualizó el contacto en callbell para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                            $error = 0;
                                        } else {
                                            print_r("No se actualizó el contacto en callbell para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                            log_message("No se actualizó el contacto en callbell para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                            $error = 1;
                                        }
                                    } else {
                                        print_r("No se encontró el contacto en callbell para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                        log_message("No se encontró el contacto en callbell para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                    }


                                    break;

                                case 'whatsactualiza':
                                    // Ejecutar función de actualización
                                    $phone_ajustado = ajustarPrefijoTelefono($phone);
                                    // print_r("Contacto whatsactualiza: " . $phone_ajustado);
                                    // log_message("Contacto whatsactualiza: " . $phone_ajustado . PHP_EOL);
                                    $response_callbell = getContactWhatsapp($phone, $CallBellAPIToken);
                                    //ejemplo de json de respuesta de la API de CallBell: {"contact":{"uuid":"74cc2bb45eb8409f92cd5dba99200d26","name":"DANIEL HUMBERTO SOTO VILLEGAS MAY","phoneNumber":"5214181878106","avatarUrl":null,"createdAt":"2024-01-08T17:04:13Z","closedAt":null,"source":"whatsapp","href":"https:\/\/dash.callbell.eu\/contacts\/74cc2bb45eb8409f92cd5dba99200d26","conversationHref":"https:\/\/dash.callbell.eu\/chat\/53c8229c428c4081b197ab136feab73b","tags":["ePA","LIA"],"assignedUser":null,"customFields":{"user entry point":"inbound_message","Clabe Interbancaria":"124180650741646979","Estado":"\ud83d\udfe2 Activo ","Antena\/Sectorial":"Sectorial-4b >> 172.16.13.16\/24","Domicilio":"\ud83d\udccd CALLE CHIAPAS #31, ZONA CENTRO, Dolores Hidalgo Cuna de la Independencia Nacional, 37800","Fecha Ultimo Pago":"\ud83d\udcc6\ud83d\udcb8 20\/02\/2025 23:17 con PayPal \ud83c\udf10\ud83d\udcb3","Saldo Actual":"\ud83d\udcb210 a favor","Fecha Ultima Actualizacion":"\ud83d\udcc6\ud83d\udd04\ufe0f 28\/02\/2025 02:46","Monto Ultimo Pago":"\ud83d\udcb2 10","Cliente":"3201","URL":"\ud83c\udf10 https:\/\/172.16.5.120\/crm\/client\/3201","Nombre":"\ud83d\udc64 DANIEL HUMBERTO SOTO VILLEGAS MAY","Site":"0LOCS","user name":"Daniel Humberto \ud83d\udc01","Resumen":"{\"Cliente\": \"3201\",\"Domicilio\": \"\ud83d\udccd CALLE CHIAPAS #31, ZONA CENTRO, Dolores Hidalgo Cuna de la Independencia Nacional, 37800\",\"Nombre\": \"\ud83d\udc64 DANIEL HUMBERTO SOTO VILLEGAS MAY\",\"URL\": \"\ud83c\udf10 https:\/\/172.16.5.120\/crm\/client\/3201\",\"Saldo Actual\": \"\ud83d\udcb210 a favor\",\"Monto Ultimo Pago\": \"\ud83d\udcb2 10\",\"Estado\": \"\ud83d\udfe2 Activo\",\"Fecha Ultimo Pago\": \"\ud83d\udcc6\ud83d\udcb0 20\/02\/2025 23:17 con PayPal \ud83c\udf10\ud83d\udcb3\",\"Fecha Ultima Actualizacion\": \"\ud83d\udcc6\ud83d\udd04\ufe0f 28\/02\/2025 02:46\",\"Clabe Interbancaria\": \"124180650741646979\"}"},"team":{"uuid":"5faeed738d6a44ccacf6509762eb288d","name":"General","default":true,"members":8,"createdAt":"2023-11-07T00:37:10Z"},"channel":{"uuid":"dbaa248932634e7ea4346a320960c24a","title":null,"type":"whatsapp","main":true},"blockedAt":null}}

                                    //validar si existe $response_callbell['contact']['conversationHref'] y $response_callbell['contact']['uuid']
                                    if (isset($response_callbell['contact']['conversationHref']) && isset($response_callbell['contact']['uuid'])) {
                                        $urlChatCallBell = $response_callbell['contact']['conversationHref'];
                                        $uuid = $response_callbell['contact']['uuid'];
                                        print_r("URL del chat de callbell: " . $urlChatCallBell . PHP_EOL);
                                    } else {
                                        print_r("No se encontró el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                        log_message("No se encontró el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                        break;
                                    }



                                    //compobar si el contacto ya existe en callbell
                                    if (isset($response_callbell['contact']['uuid'])) {
                                        print_r("URL del chat de callbell: " . $urlChatCallBell . " para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                        log_message("URL del chat de callbell: " . $urlChatCallBell . " para el tipo de contacto Whatsapp $phone_ajustado" . PHP_EOL);
                                        if (patchWhatsapp($response_callbell, $paymentData, $clienteData, $CallBellAPIToken)) {
                                            print_r("Se actualizó el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                            log_message("Se actualizó el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                            $error = 0;
                                        } else {
                                            print_r("No se actualizó el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                            log_message("No se actualizó el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                            $error = 1;
                                        }
                                    } else {
                                        print_r("No se encontró el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                        log_message("No se encontró el contacto en callbell para el tipo de contacto Whatsactualiza $phone_ajustado" . PHP_EOL);
                                        break;
                                    }
                                    break;

                                default:
                                    // Registrar cuando el tipo no es reconocido
                                    print_r("Tipo de contacto no reconocido: '$type'" . PHP_EOL);
                                    log_message("Tipo de contacto no reconocido: '$type'" . PHP_EOL);
                                    break;
                            }
                        }
                    } else {
                        print_r("Formato no esperado para los números de teléfono en el tipo: $type" . PHP_EOL);
                    }
                }

                $intentosPatch = 0; //Contador de intentos para hacer patch en el CRM

                //imprimir uuid
                print_r("UUID del contacto en callbell: " . $uuid . PHP_EOL);

                do {
                    if (isset($clientNetworkData['siteName']) && isset($clientNetworkData['device'])) {
                        $responsePatchCRM = patchClientCRM($clientNetworkData['siteName'], $clientNetworkData['device'] . ' ' . $clientNetworkData['ipDevice'], $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, null);
                        $intentosPatch++;
                        if ($intentosPatch == 3) {
                            $logMessage = "No se pudo hacer patch del SITE y DEVICE en el CRM del cliente: " . $ucrm_client_id . " Hasta " . $intentosPatch . " intentos" . PHP_EOL;
                            log_message($logMessage);
                            print_r("No se pudo hacer patch del SITE y DEVICE en el CRM del cliente: " . $ucrm_client_id . " Hasta " . $intentosPatch . " intentos" . PHP_EOL);
                            break;
                        }
                    } else {
                        $logMessage = "No se encontro el SITE y DEVICE en el CRM del cliente: " . $ucrm_client_id . PHP_EOL;
                        log_message($logMessage);
                        print_r("Client Network Data: " . json_encode($clientNetworkData) . PHP_EOL);
                        print_r("No se encontro el SITE y DEVICE en el CRM del cliente: " . $ucrm_client_id . PHP_EOL);

                        $tag_name_to_search = "NS REPETIDOR";
                        $tag_exists = false;

                        // Verificar si la clave 'tags' existe en el array y si es un array
                        if (isset($dataCRM['tags']) && is_array($dataCRM['tags'])) {
                            // Iterar sobre el array de tags
                            foreach ($dataCRM['tags'] as $tag) {
                                // Verificar si la clave 'name' existe en el tag y si su valor coincide con el nombre buscado
                                if (isset($tag['name']) && $tag['name'] === $tag_name_to_search) {
                                    $tag_exists = true;
                                    break; // Si se encuentra el tag, no es necesario seguir buscando
                                }
                            }
                        }

                        if ($tag_exists) {
                            print_r("La etiqueta \"" . $tag_name_to_search . "\" existe en el apartado de tags.");
                            log_message("La etiqueta \"" . $tag_name_to_search . "\" existe en el apartado de tags.");
                        } else {
                            print_r("La etiqueta \"" . $tag_name_to_search . "\" no existe en el apartado de tags.");
                            log_message("La etiqueta \"" . $tag_name_to_search . "\" no existe en el apartado de tags.");
                        }

                        $responsePatchCRM = patchClientCRM("ES UN REPETIDOR", "SU ANTENA ES " . ' ' . "UN REPETIDOR", $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, null);
                        $intentosPatch++;
                        if ($intentosPatch == 3) {
                            $logMessage = "No se pudo hacer patch del SITE y DEVICE en el CRM del cliente: " . $ucrm_client_id . " Hasta " . $intentosPatch . " intentos" . PHP_EOL;
                            log_message($logMessage);
                            print_r("No se pudo hacer patch del SITE y DEVICE en el CRM del cliente: " . $ucrm_client_id . " Hasta " . $intentosPatch . " intentos" . PHP_EOL);
                            break;
                        }

                        break;
                    }
                } while ($responsePatchCRM != 200);
            } else if ($responseCRM && $responseCRM->getStatusCode() === 404) {
                $logMessage = "Cliente no encontrado en el CRM: " . $ucrm_client_id;
                log_message($logMessage);
                $error = 1; //Error al obtener el cliente del CRM
                //print_r("Cliente no encontrado en el CRM: " . $ucrm_client_id);
            } else {
                $logMessage = "Error al obtener los datos. Código de estado: " . ($responseCRM ? $responseCRM->getStatusCode() : 'N/A');
                log_message($logMessage);
                $error = 1; //Error al obtener los datos del CRM
                //print_r("Error al obtener los datos. Código de estado: " . ($responseCRM ? $responseCRM->getStatusCode() : 'N/A'));
            }
            print_r('________________________________________________________________________________' . PHP_EOL);
            $logMessage = '________________________________________________________________________________' . PHP_EOL;
            log_message($logMessage);

            if ($error === 0) {
                // Eliminar la fila procesada del archivo CSV
                $lineas = file($archivoCsv, FILE_IGNORE_NEW_LINES);
                $gestorWrite = fopen($archivoCsv, 'w');
                if ($gestorWrite !== false) {
                    foreach ($lineas as $linea) {
                        $filaCsv = str_getcsv($linea);
                        if ($filaCsv[0] !== $fila[$columnaDeseada]) {
                            fputcsv($gestorWrite, $filaCsv);
                        }
                    }
                    fclose($gestorWrite);
                } else {
                    print_r('Error al abrir el archivo CSV para escritura.' . PHP_EOL);
                }
            }
        }
    }
    fclose($gestor);
    $logMessage = '************************************************************ FIN DEL EL PROCESO *****************************************' . PHP_EOL;

    log_message($logMessage);
    print_r('************************************************************ FIN DEL EL PROCESO *****************************************' . PHP_EOL);

    // // Reabrir el archivo en modo escritura para sobrescribirlo
    // $gestor = fopen($archivoCsv, 'w');
    // if ($gestor !== false) {
    //     // Escribir las líneas no procesadas de vuelta al archivo
    //     foreach ($lineasProcesadas as $linea) {
    //         fputcsv($gestor, $linea);
    //     }
    //     fclose($gestor);
    //     print_r('Archivo CSV actualizado.' . PHP_EOL);
    // } else {
    //     print_r('Error al abrir el archivo CSV para escritura.' . PHP_EOL);
    // }

}



function patchClientCRM($clientSite, $clientDevice, $urlChatCallBell, $uuid, $ucrmBaseUri, $token, $ucrm_client_id, $vaultCredentials = null): int|string
{
    $responseCRM = null;
    $json_data_patch = '{
        "attributes": [
        {
            "value": "' . $urlChatCallBell . '",
            "customAttributeId": 21
          },
          {
            "value": "' . $uuid . '",
            "customAttributeId": 22
          },
          {
            "value": "' . $clientSite . '",
            "customAttributeId": 35
          },
          {
            "value": "' . $clientDevice . '",
            "customAttributeId": 36
          }
        ]

      }'; //JSON para hacer patch de los custom fields del cliente en el UISCP CRM

    $clientguzz = new Client(); //instancia de cliente GuzzleHttp para consumir API UISP CRM
    try {
        if ($vaultCredentials != null) {
            $json_data_patch2 = '{
                "attributes": [
                  {
                    "value": "' . $vaultCredentials . '",
                    "customAttributeId": 37
                  }
                ]
              }';

            $responseCRM = $clientguzz->patch($ucrmBaseUri . 'clients/' . $ucrm_client_id, [
                'json' => json_decode($json_data_patch2, true),
                'headers' => [
                    'X-Auth-App-Key' => $token,
                    'Accept' => 'application/json',
                ],
                'verify' => false,
            ]);
        } else {
            $responseCRM = $clientguzz->patch($ucrmBaseUri . 'clients/' . $ucrm_client_id, [
                'json' => json_decode($json_data_patch, true),
                'headers' => [
                    'X-Auth-App-Key' => $token,
                    'Accept' => 'application/json',
                ],
                'verify' => false,
            ]);
        }
    } catch (GuzzleHttp\Exception\GuzzleException $error) {
        $logMessage = "Error al hacer el patch al CRM: " . $error->getMessage() . PHP_EOL;
        log_message($logMessage);
        print_r("Error al hacer el patch al CRM: " . $error->getMessage() . PHP_EOL);
        return '';
    }
    $responseImprimir = json_encode($responseCRM->getStatusCode());
    $logMessageResponse = json_encode($responseCRM->getStatusCode()) . PHP_EOL; //imprimir respuesta del patch de CRM con la clabe y Customer ID Stripe
    log_message($logMessageResponse);
    print_r('Código de respuesta al patch del SITE y DEVICE en el CRM: ' . $responseImprimir . PHP_EOL);
    return $responseCRM->getStatusCode();
}


/* 
 */
function patchWhatsapp($response_getContactCallBell = null, $paymentData, $clientData, $callbellToken): bool
{
    //ejemplo de json de respuesta de la API de CallBell: {"contact":{"uuid":"74cc2bb45eb8409f92cd5dba99200d26","name":"DANIEL HUMBERTO SOTO VILLEGAS MAY","phoneNumber":"5214181878106","avatarUrl":null,"createdAt":"2024-01-08T17:04:13Z","closedAt":null,"source":"whatsapp","href":"https:\/\/dash.callbell.eu\/contacts\/74cc2bb45eb8409f92cd5dba99200d26","conversationHref":"https:\/\/dash.callbell.eu\/chat\/53c8229c428c4081b197ab136feab73b","tags":["ePA","LIA"],"assignedUser":null,"customFields":{"user entry point":"inbound_message","Clabe Interbancaria":"124180650741646979","Estado":"\ud83d\udfe2 Activo ","Antena\/Sectorial":"Sectorial-4b >> 172.16.13.16\/24","Domicilio":"\ud83d\udccd CALLE CHIAPAS #31, ZONA CENTRO, Dolores Hidalgo Cuna de la Independencia Nacional, 37800","Fecha Ultimo Pago":"\ud83d\udcc6\ud83d\udcb8 20\/02\/2025 23:17 con PayPal \ud83c\udf10\ud83d\udcb3","Saldo Actual":"\ud83d\udcb210 a favor","Fecha Ultima Actualizacion":"\ud83d\udcc6\ud83d\udd04\ufe0f 28\/02\/2025 02:46","Monto Ultimo Pago":"\ud83d\udcb2 10","Cliente":"3201","URL":"\ud83c\udf10 https:\/\/172.16.5.120\/crm\/client\/3201","Nombre":"\ud83d\udc64 DANIEL HUMBERTO SOTO VILLEGAS MAY","Site":"0LOCS","user name":"Daniel Humberto \ud83d\udc01","Resumen":"{\"Cliente\": \"3201\",\"Domicilio\": \"\ud83d\udccd CALLE CHIAPAS #31, ZONA CENTRO, Dolores Hidalgo Cuna de la Independencia Nacional, 37800\",\"Nombre\": \"\ud83d\udc64 DANIEL HUMBERTO SOTO VILLEGAS MAY\",\"URL\": \"\ud83c\udf10 https:\/\/172.16.5.120\/crm\/client\/3201\",\"Saldo Actual\": \"\ud83d\udcb210 a favor\",\"Monto Ultimo Pago\": \"\ud83d\udcb2 10\",\"Estado\": \"\ud83d\udfe2 Activo\",\"Fecha Ultimo Pago\": \"\ud83d\udcc6\ud83d\udcb0 20\/02\/2025 23:17 con PayPal \ud83c\udf10\ud83d\udcb3\",\"Fecha Ultima Actualizacion\": \"\ud83d\udcc6\ud83d\udd04\ufe0f 28\/02\/2025 02:46\",\"Clabe Interbancaria\": \"124180650741646979\"}"},"team":{"uuid":"5faeed738d6a44ccacf6509762eb288d","name":"General","default":true,"members":8,"createdAt":"2023-11-07T00:37:10Z"},"channel":{"uuid":"dbaa248932634e7ea4346a320960c24a","title":null,"type":"whatsapp","main":true},"blockedAt":null}}

    if (isset($response_getContactCallBell['contact']['uuid'])) {
        $uuid = $response_getContactCallBell['contact']['uuid'];
        //print ("UUID: " . $uuid . PHP_EOL);
    } else {

        return false;
    }

    // print_r("Datos de pago".json_encode($paymentData).PHP_EOL);
    // print_r("Datos de cliente".json_encode($clientData).PHP_EOL);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Set timeout to 10 seconds
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $callbellToken,
        'Content-Type: application/json',
    ]);
    $UrlChatCallBell = 'https://api.callbell.eu/v1/contacts/' . $uuid;
    curl_setopt($ch, CURLOPT_URL, $UrlChatCallBell);

    $logMessage = "UUID: " . $uuid . PHP_EOL;
    log_message($logMessage);




    $fecha_actual = new DateTime();
    $fecha_actual->setTimezone(new DateTimeZone('America/Mexico_City'));
    $fecha_actual_ajustada = $fecha_actual->format("d/m/Y H:i");
    //evaluar si fecha_ultimoPago_formato es null y si es entonces poner texto de 'Aún sin pagos realizados' y si tiene fecha entonces $fecha_ultimoPago_formato
    $fecha_ultimoPago_formato = $paymentData[0]['createdDate'] ?? null;
    if (is_null($fecha_ultimoPago_formato)) {
        $fecha_ultimoPago_formato = 'Aún sin pagos realizados';
    } else {
        $fecha_ultimoPago_formato = new DateTime($paymentData[0]['createdDate']);
        $fecha_ultimoPago_formato->setTimezone(new DateTimeZone('America/Mexico_City'));
        $fecha_ultimoPago_formato = $fecha_ultimoPago_formato->format("d/m/Y H:i");
    }

    //$fecha_ultimoPago = new DateTime($paymentData[0]['createdDate']);
    //$fecha_ultimoPago = $fecha_ultimoPago->modify('-6 hours');
    //$fecha_ultimoPago_ajustada = $fecha_ultimoPago->format("d/m/Y H:i");



    $accountBalance = $clientData['saldo'];
    $saldoTexto = '';

    if ($accountBalance < 0) {
        // Si el saldo es negativo, quitar el signo y poner "Pendientes"
        $saldoTexto = '💲' . abs($accountBalance) . ' pendientes';
    } elseif ($accountBalance > 0) {
        // Si el saldo es positivo, poner "a favor"
        $saldoTexto = '💲' . $accountBalance . ' a favor';
    } else {
        // Si el saldo es 0, poner "está al corriente"
        $saldoTexto = '💲' . $accountBalance . ' está al corriente';
    }

    if (is_null($paymentData)) {
        echo "Error al decodificar JSON o JSON inválido." . PHP_EOL;
        return false;
    } else {
        $payment_method = '';
        if (is_array($paymentData) && empty($paymentData)) {
            echo "El JSON decodificado está vacío: No tiene pagos" . PHP_EOL;
            $payment_method_id = '0';
        } else {
            $payment_method_id = $paymentData[0]['methodId'] ?? null;
        }


        switch ($payment_method_id) {
            case '11721cdf-a498-48be-903e-daa67552e4f6':
                $payment_method = 'Cheque 📄';
                break;
            case '6efe0fa8-36b2-4dd1-b049-427bffc7d369':
                $payment_method = 'Efectivo 💵';
                break;
            case '4145b5f5-3bbc-45e3-8fc5-9cda970c62fb':
                $payment_method = 'Transferencia bancaria 📱🏦';
                break;
            case '78e84000-9b5b-44a4-8367-da43df86ce34':
                $payment_method = 'PayPal 🌐💳';
                break;
            case '6da98bb9-6df7-4c41-8608-5cdd7fde7d5d':
                $payment_method = 'Tarjeta de crédito PayPal 💳';
                break;
            case '1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae':
                $payment_method = 'Tarjeta de crédito Stripe 💳';
                break;
            case 'b9e1e9d1-5c7b-41d2-b6b2-3e568d700290':
                $payment_method = 'Suscripción de Stripe (tarjeta de crédito) 🌐💳';
                break;
            case '939f7701-00b7-4676-9b1e-17afb268c8ba':
                $payment_method = 'Suscripción de PayPal 🌐💳';
                break;
            case '1c963e35-df24-444d-95d2-12592d5107e8':
                $payment_method = 'MercadoPago 🌐💳';
                break;
            case 'd8c1eae9-d41d-479f-aeaf-38497975d7b3':
                $payment_method = 'Personalizado 📝💸';
                break;
            case '0':
                $payment_method = 'Cliente aún sin pagos realizados';
                break;
            default:
                $payment_method = 'Desconocido, revisar metodos de pago no contemplados';
                break;
        }
    }


    $montoUltimoPago = $paymentData[0]['amount'] ?? null;
    if ($montoUltimoPago === null) {
        $montoUltimoPago = 'Cliente aún sin pagos realizados';
    }
    $fecha_ultimoPago_texto = $fecha_ultimoPago_formato . ' con ' . $payment_method;
    $client_id = $clientData['clientId'];

    // Crear el resumen del cliente usando un array
    $resumenCliente = array(
        "Cliente" => $client_id,
        "Domicilio" => ($clientData['domicilio'] == null) ? '📍❌ Sin domicilio' : '📍 ' . $clientData['domicilio'],
        "Nombre" => sprintf("👤 %s", $clientData['nombreCompleto']),
        "URL" => $clientData['sistemaURL'],
        "Saldo Actual" => $saldoTexto,
        "Monto Ultimo Pago" => '$' . $montoUltimoPago,
        "Estado" => ($clientData['estadoServicio']) ? '🔴 Suspendido' : '🟢 Activo',
        "Fecha Ultimo Pago" => $fecha_ultimoPago_texto,
        "Fecha Ultima Actualizacion" => $fecha_actual_ajustada,
        "Clabe Interbancaria" => $clientData['clabeInterbancaria'],
        "Site" => $clientData['site'],
        "Antena/Sectorial" => $clientData['antenaSectorial']
    );

    // Convertir el resumen a JSON
    $resumenClienteJSON = json_encode($resumenCliente, JSON_UNESCAPED_UNICODE);

    // Crear los datos para el CRM con el campo Resumen como JSON
    $data_CRM = array(
        "name" => $clientData['nombreCompleto'],
        "custom_fields" => array(
            "Cliente" => $client_id,
            "Domicilio" => ($clientData['domicilio'] == null) ? '📍❌ Sin domicilio' : '📍 ' . $clientData['domicilio'],
            "Nombre" => sprintf("👤 %s", $clientData['nombreCompleto']),
            "URL" => $clientData['sistemaURL'],
            "Saldo Actual" => $saldoTexto,
            "Monto Ultimo Pago" => '$' . $montoUltimoPago,
            "Estado" => ($clientData['estadoServicio']) ? '🔴 Suspendido' : '🟢 Activo',
            "Fecha Ultimo Pago" => $fecha_ultimoPago_texto,
            "Fecha Ultima Actualizacion" => $fecha_actual_ajustada,
            "Clabe Interbancaria" => $clientData['clabeInterbancaria'],
            "Site" => $clientData['site'],
            "Antena/Sectorial" => $clientData['antenaSectorial'],
            // Aquí colocas el resumen convertido en JSON
            "Resumen" => $resumenClienteJSON
        )
    );

    // Convertir los datos a JSON
    $data_CRM_JSON = json_encode($data_CRM, JSON_UNESCAPED_UNICODE);

    // Mostrar para verificar el JSON antes de enviarlo
    //print_r("Datos para el CRM: " . $data_CRM_JSON . PHP_EOL);

    //print_r("JSON con los datos a actualizar: " . json_encode($data_CRM) . PHP_EOL);
    //log_message("JSON con los datos a actualizar: " . json_encode($data_CRM) . PHP_EOL);

    $logMessage = "JSON con los datos a actualizar: " . json_encode($data_CRM) . PHP_EOL;
    log_message($logMessage);

    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data_CRM));
    $logMessage = "prueba setopt" . PHP_EOL;
    log_message($logMessage);

    $response = curl_exec($ch);
    log_message($logMessage);


    if (curl_errno($ch)) {
        print_r('Error al realizar la solicitud cURL: ' . curl_error($ch) . PHP_EOL);
        $logMessage = 'Error al realizar la solicitud cURL: ' . curl_error($ch) . PHP_EOL;
        log_message($logMessage);
        return false;
    }
    //print_r("Response Patch CallBell: " . $response . PHP_EOL);
    $logMessage = "Response Patch CallBell: " . $response . PHP_EOL;
    log_message($logMessage);
    curl_close($ch);
    // usleep(1000000);
    return true;
}



function getContactWhatsapp($cellphone_number, $CallBellAPIToken): string
{
    // URL de la API REST
    $apiUrl = 'https://api.callbell.eu/v1/contacts/phone/' . $cellphone_number;

    // Inicializar cURL
    $ch = curl_init();

    // Configurar las opciones de cURL
    curl_setopt($ch, CURLOPT_URL, $apiUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $CallBellAPIToken,
        'Content-Type: application/json'
    ]);

    // Ejecutar la solicitud y obtener la respuesta
    $response = curl_exec($ch);


    // Verificar si hay errores en la solicitud cURL
    if (curl_errno($ch)) {
        $logMessage = 'Error al realizar la solicitud cURL: ' . curl_error($ch) . PHP_EOL;
        log_message($logMessage);
        return '';
    } else {
        // Cerrar la sesión cURL
        // curl_close($ch);
        // $response_json = json_decode($response, true);
        // if ($response_json !== null) {
        //     $uuid = $response_json['contact']['uuid'];
        //     //echo "UUID: " . $uuid;
        // } else {
        //     //echo "Error al decodificar el JSON.";
        //     $uuid = '';
        // }

        // $logMessage = $uuid . PHP_EOL;
        // log_message($logMessage);
        // return $uuid;
        return $response;
    }
}

function ajustarPrefijoTelefono($numeroTelefono)
{
    // Limpiar el número de teléfono, eliminando espacios, guiones y otros caracteres no numéricos
    $numeroTelefono = preg_replace('/\D/', '', $numeroTelefono);

    // Verificar si el número pertenece a México (sin prefijo) y no tiene el formato correcto (521)
    if (strlen($numeroTelefono) === 10 && substr($numeroTelefono, 0, 2) !== '52') {
        // Si es un número de 10 dígitos (México sin prefijo), agregar '521'
        return '521' . $numeroTelefono;
    }

    // Verificar si ya tiene el prefijo 52 pero falta el '1' (debe ser 521)
    if (strlen($numeroTelefono) > 10 && substr($numeroTelefono, 0, 2) === '52' && substr($numeroTelefono, 2, 1) !== '1') {
        // Si tiene 52 pero falta el '1', agregarlo después del 52
        return '521' . substr($numeroTelefono, 2);
    }

    // Si el número es de Estados Unidos (empieza con 1), no modificarlo
    if (strlen($numeroTelefono) > 10 && substr($numeroTelefono, 0, 1) === '1') {
        return $numeroTelefono;
    }

    // Retornar el número de teléfono tal como está si no se ajusta a ninguna de las condiciones
    return $numeroTelefono;
}

function getCRMWhatsAppContact($clientCRMContacts): array
{


    $arrayPhones = [];
    foreach ($clientCRMContacts as $contact) {
        if (!empty($contact['phone'])) {
            if (isset($contact['types']) && is_array($contact['types'])) {
                foreach ($contact['types'] as $type) {
                    if (in_array($type['name'], ['WhatsApp', 'WhatsNotifica'])) {
                        // Almacena varios números bajo el mismo tipo
                        $arrayPhones[$type['name']][] = $contact['phone'];
                    }
                }
            }
        }
    }

    return $arrayPhones;  // Devolver el arreglo de teléfonos por tipo

}

function validarEmail($email)
{
    // 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 '';
    }
}



// Función para buscar el ID por la clave "key"
function findIdByKey($json, $searchKey)
{
    // Decodificar el JSON a un array de PHP
    $data = json_decode($json, true);

    // Verificar si la decodificación fue exitosa
    if (json_last_error() === JSON_ERROR_NONE) {
        foreach ($data as $item) {
            if (isset($item['key']) && $item['key'] === $searchKey) {
                return $item['id']; // Retorna el ID si encuentra la clave
            }
        }
    } else {
        return "Error al decodificar el JSON.";
    }

    return null; // Retorna null si no encuentra la clave
}

/**
 * Recibe el cuerpo de la respuesta (string JSON) y retorna un array
 * con las variables requeridas:
 *   - clienteNota
 *   - nombreCompleto
 *   - direccionCompleta
 *   - sistemaURL
 *   - clabeInterbancaria
 *
 * @param $jsonResponse El JSON retornado por el CRM
 * @return string
 */
function extraerDatosCliente($jsonResponse): string
{
    // Decodificamos el JSON a un array asociativo
    $decodedData = json_decode($jsonResponse, true);
    //print_r("Datos Cliente CRM: ".json_encode($decodedData).PHP_EOL);

    // 1. Construimos $clienteNota como un array en lugar de JSON
    $clienteNota = [
        'site' => '', // Valor vacío para 'site'
        'sectorial' => '', // Valor vacío para 'sectorial'
        'nota' => $decodedData['note'] ?? '' // El valor de 'nota'
    ];

    // 2. Obtenemos el nombre completo
    $nombreCompleto = trim(
        ($decodedData['firstName'] ?? '') . ' ' . ($decodedData['lastName'] ?? '')
    );

    // 3. Obtenemos la dirección completa (fullAddress)
    $direccionCompleta = $decodedData['fullAddress'] ?? '';

    // 4. Construimos la URL con el ID del cliente
    $idCliente = $decodedData['id'] ?? '';
    $sistemaURL = 'https://sistema.siip.mx/crm/client/' . $idCliente;

    // 5. Buscamos la clabeInterbancaria en "attributes"
    $clabeInterbancaria = '';
    $site = '';
    $antena_sectorial = '';
    if (!empty($decodedData['attributes']) && is_array($decodedData['attributes'])) {
        foreach ($decodedData['attributes'] as $attribute) {
            if (isset($attribute['key']) && $attribute['key'] === 'clabeInterbancaria') {
                $clabeInterbancaria = $attribute['value'] ?? '';
                break; // dejamos de buscar apenas la encontramos
            }
        }

        foreach ($decodedData['attributes'] as $attribute) {
            if (isset($attribute['key']) && $attribute['key'] === 'site') {
                $site = $attribute['value'] ?? '';
                break; // dejamos de buscar apenas la encontramos
            }
        }

        foreach ($decodedData['attributes'] as $attribute) {
            if (isset($attribute['key']) && $attribute['key'] === 'antenaSectorial') {
                $antena_sectorial = $attribute['value'] ?? '';
                break; // dejamos de buscar apenas la encontramos
            }
        }
    }

    $saldo = $decodedData['accountBalance'];
    $estadoServicio = $decodedData['isActive'];

    // Creamos el array con todos los datos a retornar
    $result = [
        'clientId' => $idCliente,
        'clienteNota' => $clienteNota, // Dejamos el campo como array
        'nombreCompleto' => $nombreCompleto,
        'domicilio' => $direccionCompleta,
        'sistemaURL' => $sistemaURL,
        'clabeInterbancaria' => $clabeInterbancaria,
        'saldo' => $saldo,
        'estadoServicio' => $estadoServicio,
        'site' => $site,
        'antenaSectorial' => $antena_sectorial
    ];

    // Convertimos todo el array a JSON antes de retornarlo
    return json_encode($result);
}

function getClientDataNetwork($clientId, $authToken): array
{
    $networkData = array();
    $unmsBaseUri = 'https://172.16.5.120/v2.1/';
    $ucrmBaseUri = 'https://172.16.5.120/crm/api/v1.0/';
    // $authToken = '23c44853-74f0-4e50-88ac-3dbe8ec41783'; // Reemplaza con tu token de autenticación f405c538-55ab-4048-b004-c1d8616b204c



    // Crear una instancia del cliente Guzzle
    $clientUnms = new Client([
        'base_uri' => $unmsBaseUri,
        'verify' => false // Deshabilitar la verificación del certificado SSL
    ]);

    $clientUcrm = new Client([
        'base_uri' => $ucrmBaseUri,
        'verify' => false // Deshabilitar la verificación del certificado SSL
    ]);


    $currentSite = 'Sin SITE';
    $currentDevice = 'REPETIDOR';

    try {
        // Fetch current attributes from CRM to avoid destructive overwrites
        $responseClient = $clientUcrm->get('clients/' . $clientId, [
            'headers' => [
                'X-Auth-Token' => $authToken,
                'Content-Type: application/json'
            ]
        ]);
        if ($responseClient->getStatusCode() === 200) {
            $clientInfo = json_decode($responseClient->getBody()->getContents(), true);
            foreach ($clientInfo['attributes'] ?? [] as $attr) {
                if ($attr['key'] === 'site') {
                    $val = trim((string)$attr['value']);
                    if (!empty($val)) $currentSite = $val;
                }
                if ($attr['key'] === 'antenaSectorial') {
                    $val = trim((string)$attr['value']);
                    if (!empty($val)) $currentDevice = $val;
                }
            }
        }
    } catch (\Exception $e) {
        // Ignore fallback fetch error
    }

    try {
        //Obtener id del sitio por medio del servicio
        $responseServices = $clientUcrm->get('clients/services?clientId=' . $clientId, [
            'headers' => [
                'X-Auth-Token' => $authToken,
                'Content-Type: application/json'
            ]
        ]);

        if ($responseServices->getStatusCode() === 200) {

            $dataServices = json_decode($responseServices->getBody(), true);
            //verificar si existe esta clave $dataServices[0]['unmsClientSiteId']
            if (isset($dataServices[0]['unmsClientSiteId'])) {
                $unmsSiteID = $dataServices[0]['unmsClientSiteId'];
            } else {
                echo "No se encontró la clave 'unmsClientSiteId' en la respuesta." . PHP_EOL;
                $logMessage = "No se encontró la clave 'unmsClientSiteId' en la respuesta." . PHP_EOL;
                log_message($logMessage);
                return array(
                    "siteName" => $currentSite,
                    "device" => $currentDevice,
                    "ipDevice" => 'Sin IP de cliente'
                );
            }
            //print_r('responseServices: ' . json_encode($dataServices) . PHP_EOL);

        } else {
            echo "Error en la solicitud. Código de estado HTTP: " . $responseServices->getStatusCode() . PHP_EOL;
            $logMessage = "Error en la solicitud. Código de estado HTTP: " . $responseServices->getStatusCode() . PHP_EOL;
            log_message($logMessage);
            return array(
                "siteName" => $currentSite,
                "device" => $currentDevice,
                "ipDevice" => 'Sin IP de cliente'
            );
        }

        $responseDevicesBySite = $clientUnms->request('GET', 'devices?siteId=' . $unmsSiteID, [
            'headers' => [
                'X-Auth-Token' => $authToken
            ]
        ]);



        if ($responseDevicesBySite->getStatusCode() === 200) {

            $dataDevices = json_decode($responseDevicesBySite->getBody(), true);

            if (isset($dataDevices[0]['attributes']['apDevice']['name']) && isset($dataDevices[0]['identification']['site']['parent']['name']) && isset($dataDevices[0]['attributes']['apDevice']['id'])) {
                $clientDeviceName = $dataDevices[0]['attributes']['apDevice']['name'];
                $clientSiteName = $dataDevices[0]['identification']['site']['parent']['name'];
                $deviceId = $dataDevices[0]['attributes']['apDevice']['id'];
            } else {
                echo "No se encontró la clave 'apDevice' o 'site' en la respuesta." . PHP_EOL;
                $logMessage = "No se encontró la clave 'apDevice' o 'site' en la respuesta." . PHP_EOL;
                log_message($logMessage);

                $networkData = array(
                    "siteName" => $currentSite,
                    "device" => $currentDevice,
                    "ipDevice" => 'Sin IP de cliente'
                );

                return $networkData;
            }

            // print_r('Nombre del Site del cliente: ' . $clientSiteName . PHP_EOL);
            // print_r('Nombre del Device al que está conectado el cliente: ' . $clientDeviceName . PHP_EOL);


        } else {
            echo "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            $logMessage = "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            log_message($logMessage);
            return $networkData;
        }

        $responseDevicesBySite = $clientUnms->request('GET', 'devices/' . $deviceId, [
            'headers' => [
                'X-Auth-Token' => $authToken
            ]
        ]);

        if ($responseDevicesBySite->getStatusCode() === 200) {

            $dataDevices = json_decode($responseDevicesBySite->getBody(), true);

            $deviceIPAddress = $dataDevices['ipAddress'];

            // print_r('IP del device al que está conectado el cliente: ' . $deviceIPAddress . PHP_EOL);


        } else {
            echo "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            $logMessage = "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            log_message($logMessage);
            return $networkData;
        }
        $networkData = array(
            "siteName" => $clientSiteName,
            "device" => $clientDeviceName,
            "ipDevice" => $deviceIPAddress
        );

        return $networkData;
    } catch (RequestException $requestException) {
        // Manejar errores de la solicitud
        if ($requestException->hasResponse()) {
            $response = $requestException->getResponse();
            $statusCode = $response->getStatusCode();
            $reason = $response->getReasonPhrase();
            echo "Error: {$statusCode} - {$reason}" . PHP_EOL;
            $logMessage = "Error: {$statusCode} - {$reason}" . PHP_EOL;
            log_message($logMessage);
            echo $response->getBody();
            $logMessage = $response->getBody();
            log_message($logMessage);
        } else {
            echo "Error: " . $requestException->getMessage() . PHP_EOL;
            $logMessage = "Error: " . $requestException->getMessage() . PHP_EOL;
            log_message($logMessage);
        }
        return $networkData;
    }
}

function getVaultCredentials($dataToSearch, $authToken, $ucrmBaseUri, $unmsBaseUri): string
{
    // $logger = \Ubnt\UcrmPluginSdk\Service\PluginLogManager::create();
    // $configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
    // $config = $configManager->loadConfig();
    // $ucrmBaseUri = $config['ipserver'];
    // $authToken = $config['apitoken'];


    // $unmsBaseUri = 'https://' . $ucrmBaseUri . '/nms/api/v2.1/';
    // $ucrmBaseUri = 'https://' . $ucrmBaseUri . '/crm/api/v1.0/';
    //$authToken = '7adc9198-50b1-41d0-9bfa-d4946902ed89';

    // Crear una instancia del cliente Guzzle
    $clientUnms = new Client([
        'base_uri' => $unmsBaseUri,
        'verify' => false // Deshabilitar la verificación del certificado SSL
    ]);

    $clientUcrm = new Client([
        'base_uri' => $ucrmBaseUri,
        'verify' => false // Deshabilitar la verificación del certificado SSL
    ]);


    //validar si dataToSearch es una dirección IP o una dirección MAC
    if (filter_var($dataToSearch, FILTER_VALIDATE_IP)) {
        // La variable es una dirección IP válida
        // $logger->appendLog('Consulta por dirección IP: ' . $dataToSearch);
        print('Consulta por dirección IP: ' . $dataToSearch . PHP_EOL);

        $IpAddressClientId = filter_var($dataToSearch, FILTER_VALIDATE_IP);

        try {
            $responseSitesByIP = $clientUnms->request('GET', 'sites/search?query=' . $dataToSearch . '&count=1&page=1', [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responseSitesByIP->getStatusCode() === 200) {

                $datasSitesByIP = json_decode($responseSitesByIP->getBody(), true);
                $jsonDevicesBySite = json_encode($datasSitesByIP, JSON_PRETTY_PRINT);
                //print_r($jsonDevicesBySite . PHP_EOL); //Devices por ID del sitio

                if (isset($datasSitesByIP[0])) {
                    $siteId = $datasSitesByIP[0]['id'];
                    // print_r('ID DEL SITIO: ' . $siteId . PHP_EOL); // ID del sitio
                } else {
                    // $logger->appendLog('No se encontró ningún sitio para la IP proporcionada: ' . $dataToSearch);
                    print_r('No se encontró ningún sitio para la IP proporcionada: ' . $dataToSearch . PHP_EOL);
                    return 'Error: No se encontró ningún sitio para la IP proporcionada: ' . $dataToSearch; // Return early if no site is found
                }
            } else {
                //echo "Error en la solicitud. Código de estado HTTP: " . $responseSitesByIP->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseSitesByIP->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responseSitesByIP->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseSitesByIP->getStatusCode(); // Return early if the request fails
            }

            $devicesBySiteId = $clientUnms->request('GET', 'devices?siteId=' . $siteId, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($devicesBySiteId->getStatusCode() === 200) {
                $dataDevicesBySite = json_decode($devicesBySiteId->getBody(), true);
                $jsonDevicesBySite = json_encode($dataDevicesBySite, JSON_PRETTY_PRINT);
                //print_r($jsonDevicesBySite . PHP_EOL); //Devices por ID del sitio
                $deviceID = null;

                foreach ($dataDevicesBySite as $device) {
                    if (isset($device['ipAddress'])) {
                        $ipAddress = explode('/', $device['ipAddress'])[0]; // Obtener solo la IP sin la máscara
                        if ($ipAddress === $IpAddressClientId) {
                            $deviceID = $device['identification']['id'];
                            break; // Salir del ciclo si se encuentra la IP
                        }
                    } else {
                        // $logger->appendLog('No se encontró la IP del dispositivo en la respuesta de la API.');
                        print_r('No se encontró la IP del dispositivo en la respuesta de la API.' . PHP_EOL);
                        return 'Error: No se encontró la IP del dispositivo en la respuesta de la API.'; // Return early if the IP is not found
                    }
                }

                if ($deviceID == null) {
                    //echo "No se encontró el dispositivo con la IP proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró el dispositivo con la IP proporcionada: ' . $IpAddressClientId);
                    print_r('No se encontró el dispositivo con la IP proporcionada: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el dispositivo con la IP proporcionada: ' . $IpAddressClientId; // Return early if no device is found 
                }
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $devicesBySiteId->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $devicesBySiteId->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $devicesBySiteId->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $devicesBySiteId->getStatusCode(); // Return early if the request fails
            }

            $responsePasswordVault = $clientUnms->request('GET', 'vault/' . $deviceID . '/credentials', [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responsePasswordVault->getStatusCode() === 200) {
                $dataPasswordVault = json_decode($responsePasswordVault->getBody(), true);
                // $jsonPasswordVault = json_encode($dataPasswordVault, JSON_PRETTY_PRINT);
                //print_r($jsonPasswordVault . PHP_EOL); //Credenciales del dispositivo

                if (isset($dataPasswordVault['credentials']['password'])) {
                    $dataPasswordVault = $dataPasswordVault['credentials']['password'];
                } else {
                    // echo "No se encontró la contraseña en la respuesta de la API." . PHP_EOL;
                    // $logger->appendLog('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.');
                    print_r('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
                    return "Error: No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
                }
                return $dataPasswordVault;
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $responsePasswordVault->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode(); // Return early if the request fails
            }
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud, si hay error 404 entonces responder que no se encontró niguna IP asociada a alguna antena o dispositivo de red
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                // echo "Error: {$statusCode} - {$reason}" . PHP_EOL;
                // echo $response->getBody();
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con la dirección IP proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con la dirección IP proporcionada: ' . $IpAddressClientId);
                    print_r('No se encontró el cliente con la dirección IP proporcionada: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el cliente con la dirección IP proporcionada: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails
            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }
    } else if (preg_match('/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/', $dataToSearch)) {
        // La variable es una dirección MAC válida
        // $logger->appendLog('Consulta por dirección MAC: ' . $dataToSearch);
        print('Consulta por dirección MAC: ' . $dataToSearch . PHP_EOL);

        try {
            // //para mandarla al endpoint de dispositivos por MAC se necesita convertir la cadena de la direccion mac en un formato como el siguiente ejemplo: para la dirección mac 60:22:32:c8:b2:c3 quedaría como 60%3A22%3A32%3Ac8%3Ab2%3Ac3
            // $dataToSearch = str_replace(':', '%3A', $dataToSearch);
            // $logger->appendLog('Consulta por dirección MAC: ' . $dataToSearch );
            $responseDeviceByMAC = $clientUnms->request('GET', 'devices/mac/' . $dataToSearch, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responseDeviceByMAC->getStatusCode() === 200) {

                $dataDeviceByMAC = json_decode($responseDeviceByMAC->getBody(), true);
                $jsonDeviceByMac = json_encode($dataDeviceByMAC, JSON_PRETTY_PRINT);
                // print_r($jsonDeviceByMac . PHP_EOL); //Devices por ID del sitio
                //$logger->appendLog($jsonDeviceByMac.PHP_EOL);

                //Ejemplo de $responseDeviceByMac en json: {"id":"84c8a581-154c-41db-81d5-a1b1c9ede411","type":"airMax","series":"AC"}
                //obtener el id del dispositivo y si no existe el id del dispositivo entonces devolver un mensaje de error
                if (isset($dataDeviceByMAC['id'])) {
                    $deviceId = $dataDeviceByMAC['id'];
                    // print_r('ID DEL DISPOSITIVO: ' . $deviceId . PHP_EOL); // ID del dispositivo
                } else {
                    // echo "No se encontró el dispositivo con la dirección MAC proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró el dispositivo con la dirección MAC proporcionada: ' . $dataToSearch);
                    print_r('No se encontró el dispositivo con la dirección MAC proporcionada: ' . $dataToSearch . PHP_EOL);
                    return 'Error: No se encontró el dispositivo con la dirección MAC proporcionada: ' . $dataToSearch; // Return early if no device is found
                }
            }

            $responsePasswordVault = $clientUnms->request('GET', 'vault/' . $deviceId . '/credentials', [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responsePasswordVault->getStatusCode() === 200) {
                $dataPasswordVault = json_decode($responsePasswordVault->getBody(), true);
                // $jsonPasswordVault = json_encode($dataPasswordVault, JSON_PRETTY_PRINT);
                //print_r($jsonPasswordVault . PHP_EOL); //Credenciales del dispositivo

                if (isset($dataPasswordVault['credentials']['password'])) {
                    $dataPasswordVault = $dataPasswordVault['credentials']['password'];
                } else {
                    // echo "No se encontró la contraseña en la respuesta de la API." . PHP_EOL;
                    // $logger->appendLog('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.');
                    print_r('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
                    return "Error: No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
                }
                return $dataPasswordVault;
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $responsePasswordVault->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode(); // Return early if the request fails
            }
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud, si hay error 404 entonces responder que no se encontró niguna MAC asociada a alguna antena o dispositivo de red
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                // echo "Error: {$statusCode} - {$reason}" . PHP_EOL;
                // echo $response->getBody();
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con la dirección MAC proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró ninguna antena de cliente o dispositivo en la red con la dirección MAC proporcionada: ' . $dataToSearch);
                    print_r('No se encontró ninguna antena de cliente o dispositivo en la red con la dirección MAC proporcionada: ' . $dataToSearch . PHP_EOL);
                    return 'Error: No se encontró ninguna antena de cliente o dispositivo en la red con la dirección MAC proporcionada: ' . $dataToSearch; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails
            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }
    } else {
        // La variable no es una dirección IP válida, se asume que es un ID
        $IpAddressClientId = filter_var($dataToSearch, FILTER_SANITIZE_NUMBER_INT);
        //print ('Consulta por ID: ' . $dataToSearch . PHP_EOL);

        try {
            //Obtener id del sitio por medio del servicio   
            $responseServices = $clientUcrm->get('clients/services?clientId=' . $IpAddressClientId, [
                'headers' => [
                    'X-Auth-Token' => $authToken,
                    'Content-Type: application/json'
                ]
            ]);
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                //si el statusCode es 404 significa que no se encontró el cliente
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                    print_r('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails

            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }

        if ($responseServices->getStatusCode() === 200) {

            $dataServices = json_decode($responseServices->getBody(), true);
            // $jsonServices = json_encode($dataServices, JSON_PRETTY_PRINT);
            // print_r($jsonServices . PHP_EOL);
            if (isset($dataServices[0])) {
                $unmsSiteID = $dataServices[0]['unmsClientSiteId']; // Example: 9c6798f3-0254-4e5b-bc3b-9da82fe16e46
            } else {
                // echo "No se encontraron servicios para el cliente proporcionado." . PHP_EOL;
                // $logger->appendLog('No se encontraron servicios para el cliente proporcionado: ' . $IpAddressClientId);
                print_r('No se encontraron servicios para el cliente proporcionado: ' . $IpAddressClientId . PHP_EOL);
                return "Error: No se encontraron servicios para el cliente proporcionado: " . $IpAddressClientId; // Return early if no services are found
            }
        } else {
            // echo "Error en la solicitud. Código de estado HTTP: " . $responseServices->getStatusCode() . PHP_EOL;
            // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseServices->getStatusCode());
            print_r('Error en la solicitud. Código de estado HTTP: ' . $responseServices->getStatusCode() . PHP_EOL);
            return "Error: En la solicitud. Código de estado HTTP: " . $responseServices->getStatusCode();
        }

        try {
            $responseDevicesBySite = $clientUnms->request('GET', 'devices?siteId=' . $unmsSiteID, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                //si el statusCode es 404 significa que no se encontró el cliente
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                    print_r('No se encontró el devicie con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el devicie con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails

            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }


        if ($responseDevicesBySite->getStatusCode() === 200) {

            $dataDevicesBySite = json_decode($responseDevicesBySite->getBody(), true);
            $jsonDevicesBySite = json_encode($dataDevicesBySite, JSON_PRETTY_PRINT);
            //print_r($jsonDevicesBySite . PHP_EOL); //Devices por ID del sitio

            //id del device al que está conectado el cliente
            if (isset($dataDevicesBySite[0])) {
                //verificar con iiset si existe la clave 'identification' y 'apDevice' en el primer elemento del array
                if (isset($dataDevicesBySite[0]['identification']) && isset($dataDevicesBySite[0]['attributes']['apDevice'])) {
                    $idClientDevice = $dataDevicesBySite[0]['identification']['id'];
                    $deviceID = $dataDevicesBySite[0]['attributes']['apDevice']['id'];
                } else {
                    // echo "No se encontró la clave 'identification' o 'apDevice' en la respuesta." . PHP_EOL;
                    // $logger->appendLog('No se encontró la clave \'identification\' o \'apDevice\' en la respuesta.');
                    print_r('Este cliente es un repetidor.' . PHP_EOL);
                    return "Este cliente es un repetidor."; // Return early if the key is not found
                }
            } else {
                // echo "No se encontraron dispositivos para el sitio proporcionado." . PHP_EOL;
                // $logger->appendLog('No se encontraron dispositivos para el sitio proporcionado: ' . $unmsSiteID);
                print_r('No se encontraron dispositivos para el sitio proporcionado: ' . $unmsSiteID . PHP_EOL);
                return "Error: No se encontraron dispositivos para el sitio proporcionado."; // Return early if no devices are found
            }
        } else {
            // echo "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode());
            print_r('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode() . PHP_EOL);
            return "Error: Falla en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode();
        }

        try {
            $responseDevicesBySite = $clientUnms->request('GET', 'devices/' . $deviceID, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                //si el statusCode es 404 significa que no se encontró el cliente
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                    print_r('No se encontró el device con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el device con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails

            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }

        if ($responseDevicesBySite->getStatusCode() === 200) {

            $dataDevices = json_decode($responseDevicesBySite->getBody(), true);
            $jsonDevices = json_encode($dataDevices, JSON_PRETTY_PRINT);
            //print_r($jsonDevices . PHP_EOL);


            try {
                //print_r('ID del device al que está conectado el cliente: ' . $idDevice . PHP_EOL);
                $responsePasswordVault = $clientUnms->request('GET', 'vault/' . $idClientDevice . '/credentials', [
                    'headers' => [
                        'X-Auth-Token' => $authToken
                    ]
                ]);
            } catch (RequestException $requestException) {
                // Manejar errores de la solicitud
                if ($requestException->hasResponse()) {
                    $response = $requestException->getResponse();
                    $statusCode = $response->getStatusCode();
                    $reason = $response->getReasonPhrase();
                    //si el statusCode es 404 significa que no se encontró el cliente
                    if ($statusCode == 404) {
                        // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                        // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                        print_r('No se encontró el device con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                        return 'Error: No se encontró el device con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                    }
                    return 'Error: ' . $reason; // Return early if the request fails

                } else {
                    // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                    // $logger->appendLog('Error: ' . $requestException->getMessage());
                    print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                    return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
                }
            }


            if ($responsePasswordVault->getStatusCode() === 200) {
                $dataPasswordVault = json_decode($responsePasswordVault->getBody(), true);
                $jsonPasswordVault = json_encode($dataPasswordVault, JSON_PRETTY_PRINT);
                if (isset($dataPasswordVault['credentials']['password'])) {
                    $passwordVault = $dataPasswordVault['credentials']['password'];
                    return $passwordVault;
                } else {
                    // echo "No se encontró la contraseña en la respuesta de la API." . PHP_EOL;
                    // $logger->appendLog('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.');
                    print_r('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
                    return "Error: No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
                }
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $responsePasswordVault->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode(); // Return early if the request fails
            }
        } else {
            // echo "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode());
            print_r('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode() . PHP_EOL);
            return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode(); // Return early if the request fails

        }
    }
}

function generateVaultCredentials($dataToSearch, $authToken, $ucrmBaseUri, $unmsBaseUri): string
{
    // $logger = \Ubnt\UcrmPluginSdk\Service\PluginLogManager::create();
    // $configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
    // $config = $configManager->loadConfig();
    // $ucrmBaseUri = $config['ipserver'];
    // $authToken = $config['apitoken'];


    // $unmsBaseUri = 'https://' . $ucrmBaseUri . '/nms/api/v2.1/';
    // $ucrmBaseUri = 'https://' . $ucrmBaseUri . '/crm/api/v1.0/';
    //$authToken = '7adc9198-50b1-41d0-9bfa-d4946902ed89';

    // Crear una instancia del cliente Guzzle
    $clientUnms = new Client([
        'base_uri' => $unmsBaseUri,
        'verify' => false // Deshabilitar la verificación del certificado SSL
    ]);

    $clientUcrm = new Client([
        'base_uri' => $ucrmBaseUri,
        'verify' => false // Deshabilitar la verificación del certificado SSL
    ]);


    //validar si dataToSearch es una dirección IP o una dirección MAC
    if (filter_var($dataToSearch, FILTER_VALIDATE_IP)) {
        // La variable es una dirección IP válida
        // $logger->appendLog('Consulta por dirección IP: ' . $dataToSearch);
        print('Consulta por dirección IP: ' . $dataToSearch . PHP_EOL);

        $IpAddressClientId = filter_var($dataToSearch, FILTER_VALIDATE_IP);

        try {
            $responseSitesByIP = $clientUnms->request('GET', 'sites/search?query=' . $dataToSearch . '&count=1&page=1', [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responseSitesByIP->getStatusCode() === 200) {

                $datasSitesByIP = json_decode($responseSitesByIP->getBody(), true);
                $jsonDevicesBySite = json_encode($datasSitesByIP, JSON_PRETTY_PRINT);
                //print_r($jsonDevicesBySite . PHP_EOL); //Devices por ID del sitio

                if (isset($datasSitesByIP[0])) {
                    $siteId = $datasSitesByIP[0]['id'];
                    // print_r('ID DEL SITIO: ' . $siteId . PHP_EOL); // ID del sitio
                } else {
                    // $logger->appendLog('No se encontró ningún sitio para la IP proporcionada: ' . $dataToSearch);
                    print_r('No se encontró ningún sitio para la IP proporcionada: ' . $dataToSearch . PHP_EOL);
                    return 'Error: No se encontró ningún sitio para la IP proporcionada: ' . $dataToSearch; // Return early if no site is found
                }
            } else {
                //echo "Error en la solicitud. Código de estado HTTP: " . $responseSitesByIP->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseSitesByIP->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responseSitesByIP->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseSitesByIP->getStatusCode(); // Return early if the request fails
            }

            $devicesBySiteId = $clientUnms->request('GET', 'devices?siteId=' . $siteId, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($devicesBySiteId->getStatusCode() === 200) {
                $dataDevicesBySite = json_decode($devicesBySiteId->getBody(), true);
                $jsonDevicesBySite = json_encode($dataDevicesBySite, JSON_PRETTY_PRINT);
                //print_r($jsonDevicesBySite . PHP_EOL); //Devices por ID del sitio
                $deviceID = null;

                foreach ($dataDevicesBySite as $device) {
                    if (isset($device['ipAddress'])) {
                        $ipAddress = explode('/', $device['ipAddress'])[0]; // Obtener solo la IP sin la máscara
                        if ($ipAddress === $IpAddressClientId) {
                            $deviceId = $device['identification']['id'];
                            break; // Salir del ciclo si se encuentra la IP
                        }
                    } else {
                        // $logger->appendLog('No se encontró la IP del dispositivo en la respuesta de la API.');
                        print_r('No se encontró la IP del dispositivo en la respuesta de la API.' . PHP_EOL);
                        return 'Error: No se encontró la IP del dispositivo en la respuesta de la API.'; // Return early if the IP is not found
                    }
                }

                if ($deviceId == null) {
                    //echo "No se encontró el dispositivo con la IP proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró el dispositivo con la IP proporcionada: ' . $IpAddressClientId);
                    print_r('No se encontró el dispositivo con la IP proporcionada: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el dispositivo con la IP proporcionada: ' . $IpAddressClientId; // Return early if no device is found 
                }
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $devicesBySiteId->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $devicesBySiteId->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $devicesBySiteId->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $devicesBySiteId->getStatusCode(); // Return early if the request fails
            }

            $responseGeneratePasswordVault = $clientUnms->request('GET', 'vault/' . $deviceId . '/credentials/regenerate', [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responseGeneratePasswordVault->getStatusCode() === 200) {
                $dataNewPasswordVault = json_decode($responseGeneratePasswordVault->getBody(), true);
                // $jsonPasswordVault = json_encode($dataPasswordVault, JSON_PRETTY_PRINT);
                //print_r($jsonPasswordVault . PHP_EOL); //Credenciales del dispositivo

                if (isset($dataNewPasswordVault['password'])) {
                    $newPasswordVault = $dataNewPasswordVault['password'];
                } else {
                    // echo "No se encontró la contraseña en la respuesta de la API." . PHP_EOL;
                    // $logger->appendLog('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.');
                    print_r('No se pudo generar una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
                    return "Error: No se pudo generar una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
                }
                return $newPasswordVault;
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $responsePasswordVault->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responseGeneratePasswordVault->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseGeneratePasswordVault->getStatusCode(); // Return early if the request fails
            }
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud, si hay error 404 entonces responder que no se encontró niguna IP asociada a alguna antena o dispositivo de red
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                // echo "Error: {$statusCode} - {$reason}" . PHP_EOL;
                // echo $response->getBody();
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con la dirección IP proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con la dirección IP proporcionada: ' . $IpAddressClientId);
                    print_r('No se encontró el cliente con la dirección IP proporcionada: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el cliente con la dirección IP proporcionada: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails
            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }
    } else if (preg_match('/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/', $dataToSearch)) {
        // La variable es una dirección MAC válida
        // $logger->appendLog('Consulta por dirección MAC: ' . $dataToSearch);
        print('Consulta por dirección MAC: ' . $dataToSearch . PHP_EOL);

        try {
            // //para mandarla al endpoint de dispositivos por MAC se necesita convertir la cadena de la direccion mac en un formato como el siguiente ejemplo: para la dirección mac 60:22:32:c8:b2:c3 quedaría como 60%3A22%3A32%3Ac8%3Ab2%3Ac3
            // $dataToSearch = str_replace(':', '%3A', $dataToSearch);
            // $logger->appendLog('Consulta por dirección MAC: ' . $dataToSearch );
            $responseDeviceByMAC = $clientUnms->request('GET', 'devices/mac/' . $dataToSearch, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responseDeviceByMAC->getStatusCode() === 200) {

                $dataDeviceByMAC = json_decode($responseDeviceByMAC->getBody(), true);
                $jsonDeviceByMac = json_encode($dataDeviceByMAC, JSON_PRETTY_PRINT);
                // print_r($jsonDeviceByMac . PHP_EOL); //Devices por ID del sitio
                //$logger->appendLog($jsonDeviceByMac.PHP_EOL);

                //Ejemplo de $responseDeviceByMac en json: {"id":"84c8a581-154c-41db-81d5-a1b1c9ede411","type":"airMax","series":"AC"}
                //obtener el id del dispositivo y si no existe el id del dispositivo entonces devolver un mensaje de error
                if (isset($dataDeviceByMAC['id'])) {
                    $deviceId = $dataDeviceByMAC['id'];
                    // print_r('ID DEL DISPOSITIVO: ' . $deviceId . PHP_EOL); // ID del dispositivo
                } else {
                    // echo "No se encontró el dispositivo con la dirección MAC proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró el dispositivo con la dirección MAC proporcionada: ' . $dataToSearch);
                    print_r('No se encontró el dispositivo con la dirección MAC proporcionada: ' . $dataToSearch . PHP_EOL);
                    return 'Error: No se encontró el dispositivo con la dirección MAC proporcionada: ' . $dataToSearch; // Return early if no device is found
                }
            }

            $responseGeneratePasswordVault = $clientUnms->request('GET', 'vault/' . $deviceId . '/credentials/regenerate', [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);

            if ($responseGeneratePasswordVault->getStatusCode() === 200) {
                $dataNewPasswordVault = json_decode($responseGeneratePasswordVault->getBody(), true);
                // $jsonPasswordVault = json_encode($dataPasswordVault, JSON_PRETTY_PRINT);
                //print_r($jsonPasswordVault . PHP_EOL); //Credenciales del dispositivo

                if (isset($dataNewPasswordVault['password'])) {
                    $newPasswordVault = $dataNewPasswordVault['password'];
                } else {
                    // echo "No se encontró la contraseña en la respuesta de la API." . PHP_EOL;
                    // $logger->appendLog('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.');
                    print_r('No se pudo generar una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
                    return "Error: No se pudo generar una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
                }
                return $newPasswordVault;
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $responsePasswordVault->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responseGeneratePasswordVault->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseGeneratePasswordVault->getStatusCode(); // Return early if the request fails
            }
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud, si hay error 404 entonces responder que no se encontró niguna MAC asociada a alguna antena o dispositivo de red
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                // echo "Error: {$statusCode} - {$reason}" . PHP_EOL;
                // echo $response->getBody();
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con la dirección MAC proporcionada." . PHP_EOL;
                    // $logger->appendLog('No se encontró ninguna antena de cliente o dispositivo en la red con la dirección MAC proporcionada: ' . $dataToSearch);
                    print_r('No se encontró ninguna antena de cliente o dispositivo en la red con la dirección MAC proporcionada: ' . $dataToSearch . PHP_EOL);
                    return 'Error: No se encontró ninguna antena de cliente o dispositivo en la red con la dirección MAC proporcionada: ' . $dataToSearch; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails
            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }
    } else {
        // La variable no es una dirección IP válida, se asume que es un ID
        $IpAddressClientId = filter_var($dataToSearch, FILTER_SANITIZE_NUMBER_INT);
        //print ('Consulta por ID: ' . $dataToSearch . PHP_EOL);

        try {
            //Obtener id del sitio por medio del servicio   
            $responseServices = $clientUcrm->get('clients/services?clientId=' . $IpAddressClientId, [
                'headers' => [
                    'X-Auth-Token' => $authToken,
                    'Content-Type: application/json'
                ]
            ]);
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                //si el statusCode es 404 significa que no se encontró el cliente
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                    print_r('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails

            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }

        if ($responseServices->getStatusCode() === 200) {

            $dataServices = json_decode($responseServices->getBody(), true);
            // $jsonServices = json_encode($dataServices, JSON_PRETTY_PRINT);
            // print_r($jsonServices . PHP_EOL);
            if (isset($dataServices[0])) {
                $unmsSiteID = $dataServices[0]['unmsClientSiteId']; // Example: 9c6798f3-0254-4e5b-bc3b-9da82fe16e46
            } else {
                // echo "No se encontraron servicios para el cliente proporcionado." . PHP_EOL;
                // $logger->appendLog('No se encontraron servicios para el cliente proporcionado: ' . $IpAddressClientId);
                print_r('No se encontraron servicios para el cliente proporcionado: ' . $IpAddressClientId . PHP_EOL);
                return "Error: No se encontraron servicios para el cliente proporcionado: " . $IpAddressClientId; // Return early if no services are found
            }
        } else {
            // echo "Error en la solicitud. Código de estado HTTP: " . $responseServices->getStatusCode() . PHP_EOL;
            // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseServices->getStatusCode());
            print_r('Error en la solicitud. Código de estado HTTP: ' . $responseServices->getStatusCode() . PHP_EOL);
            return "Error: En la solicitud. Código de estado HTTP: " . $responseServices->getStatusCode();
        }

        try {
            $responseDevicesBySite = $clientUnms->request('GET', 'devices?siteId=' . $unmsSiteID, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                //si el statusCode es 404 significa que no se encontró el cliente
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                    print_r('No se encontró el devicie con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el devicie con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails

            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }


        if ($responseDevicesBySite->getStatusCode() === 200) {

            $dataDevicesBySite = json_decode($responseDevicesBySite->getBody(), true);
            $jsonDevicesBySite = json_encode($dataDevicesBySite, JSON_PRETTY_PRINT);
            //print_r($jsonDevicesBySite . PHP_EOL); //Devices por ID del sitio

            //id del device al que está conectado el cliente
            if (isset($dataDevicesBySite[0])) {
                //verificar con iiset si existe la clave 'identification' y 'apDevice' en el primer elemento del array
                if (isset($dataDevicesBySite[0]['identification']) && isset($dataDevicesBySite[0]['attributes']['apDevice'])) {
                    $idClientDevice = $dataDevicesBySite[0]['identification']['id'];
                    $deviceID = $dataDevicesBySite[0]['attributes']['apDevice']['id'];
                } else {
                    // echo "No se encontró la clave 'identification' o 'apDevice' en la respuesta." . PHP_EOL;
                    // $logger->appendLog('No se encontró la clave \'identification\' o \'apDevice\' en la respuesta.');
                    print_r('Este cliente es un repetidor.' . PHP_EOL);
                    return "Este cliente es un repetidor."; // Return early if the key is not found
                }
            } else {
                // echo "No se encontraron dispositivos para el sitio proporcionado." . PHP_EOL;
                // $logger->appendLog('No se encontraron dispositivos para el sitio proporcionado: ' . $unmsSiteID);
                print_r('No se encontraron dispositivos para el sitio proporcionado: ' . $unmsSiteID . PHP_EOL);
                return "Error: No se encontraron dispositivos para el sitio proporcionado."; // Return early if no devices are found
            }
        } else {
            // echo "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode());
            print_r('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode() . PHP_EOL);
            return "Error: Falla en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode();
        }

        try {
            $responseDevicesBySite = $clientUnms->request('GET', 'devices/' . $deviceID, [
                'headers' => [
                    'X-Auth-Token' => $authToken
                ]
            ]);
        } catch (RequestException $requestException) {
            // Manejar errores de la solicitud
            if ($requestException->hasResponse()) {
                $response = $requestException->getResponse();
                $statusCode = $response->getStatusCode();
                $reason = $response->getReasonPhrase();
                //si el statusCode es 404 significa que no se encontró el cliente
                if ($statusCode == 404) {
                    // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                    // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                    print_r('No se encontró el device con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                    return 'Error: No se encontró el device con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                }
                return 'Error: ' . $reason; // Return early if the request fails

            } else {
                // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                // $logger->appendLog('Error: ' . $requestException->getMessage());
                print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
            }
        }

        if ($responseDevicesBySite->getStatusCode() === 200) {

            $dataDevices = json_decode($responseDevicesBySite->getBody(), true);
            $jsonDevices = json_encode($dataDevices, JSON_PRETTY_PRINT);
            //print_r($jsonDevices . PHP_EOL);


            try {
                //print_r('ID del device al que está conectado el cliente: ' . $idDevice . PHP_EOL);
                $responseGeneratePasswordVault = $clientUnms->request('POST', 'vault/' . $deviceID . '/credentials/regenerate', [
                    'headers' => [
                        'X-Auth-Token' => $authToken
                    ]
                ]);
            } catch (RequestException $requestException) {
                // Manejar errores de la solicitud
                if ($requestException->hasResponse()) {
                    $response = $requestException->getResponse();
                    $statusCode = $response->getStatusCode();
                    $reason = $response->getReasonPhrase();
                    //si el statusCode es 404 significa que no se encontró el cliente
                    if ($statusCode == 404) {
                        // echo "No se encontró el cliente con el ID proporcionado." . PHP_EOL;
                        // $logger->appendLog('No se encontró el cliente con el ID proporcionado: ' . $IpAddressClientId);
                        print_r('No se encontró el device con el ID proporcionado: ' . $IpAddressClientId . PHP_EOL);
                        return 'Error: No se encontró el device con el ID proporcionado: ' . $IpAddressClientId; // Return early if the client is not found
                    }
                    return 'Error: ' . $reason; // Return early if the request fails

                } else {
                    // echo "Error: " . $requestException->getMessage() . PHP_EOL;
                    // $logger->appendLog('Error: ' . $requestException->getMessage());
                    print_r('Error: ' . $requestException->getMessage() . PHP_EOL);
                    return 'Error: ' . $requestException->getMessage(); // Return early if the request fails
                }
            }




            if ($responseGeneratePasswordVault->getStatusCode() === 200) {
                $dataNewPasswordVault = json_decode($responseGeneratePasswordVault->getBody(), true);
                // $jsonPasswordVault = json_encode($dataPasswordVault, JSON_PRETTY_PRINT);
                //print_r($jsonPasswordVault . PHP_EOL); //Credenciales del dispositivo

                if (isset($dataNewPasswordVault['password'])) {
                    $newPasswordVault = $dataNewPasswordVault['password'];
                } else {
                    // echo "No se encontró la contraseña en la respuesta de la API." . PHP_EOL;
                    // $logger->appendLog('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.');
                    print_r('No se pudo generar una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
                    return "Error: No se pudo generar una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
                }
                return $newPasswordVault;
            } else {
                // echo "Error en la solicitud. Código de estado HTTP: " . $responsePasswordVault->getStatusCode() . PHP_EOL;
                // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responsePasswordVault->getStatusCode());
                print_r('Error en la solicitud. Código de estado HTTP: ' . $responseGeneratePasswordVault->getStatusCode() . PHP_EOL);
                return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseGeneratePasswordVault->getStatusCode(); // Return early if the request fails
            }
        } else {
            // echo "Error en la solicitud. Código de estado HTTP: " . $responseDevicesBySite->getStatusCode() . PHP_EOL;
            // $logger->appendLog('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode());
            print_r('Error en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode() . PHP_EOL);
            return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode(); // Return early if the request fails

        }
    }
}

function log_message($message, $logFileName = 'log_sincronizacionCRMPaswordVault_26-04-2025.txt')
{
    // Ruta del archivo en la raíz
    $filePath = __DIR__ . '/' . $logFileName;

    // Agregar una marca de tiempo al mensaje
    $formattedMessage = "[" . date('Y-m-d H:i:s') . "] " . $message . PHP_EOL;

    // Escribir el mensaje en el archivo de log
    file_put_contents($filePath, $formattedMessage, FILE_APPEND);
}
