<?php

// require "vendor/autoload.php";

header("Content-type: application/json; charset=utf-8");

$bot = $_GET["bot"];

$postData = file_get_contents("php://input");

// error_log("variables ".print_r($postData,true),0);
// error_log("variables ".print_r($_POST,true),0);

$postData = json_decode($postData, true);

$userId = explode("@", $postData["message_from"])[0];
$userMessage = $postData["message_body_text"];
$userMessage = mb_convert_encoding($userMessage, "UTF-8", "UTF-8");


// error_log("variables ".$postData,0);

print_r($bot);

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://dialogflow.cloud.google.com/v1/cx/locations/us-central1/integrations/messenger/webhook/projects/wischat/agents/'.$bot.'/sessions/'.$userId,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{"queryInput":{"text":{"text":"'.$userMessage.'"},"languageCode":"es"},"queryParams":{"channel":"DF_MESSENGER"}}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);

// print_r($response);

curl_close($curl);

$lines = explode("\n", $response);

// Eliminar la primera línea
array_shift($lines);

// Unir el resto de las líneas en un solo string
$cleanJson = implode("\n", $lines);

$data = json_decode($cleanJson, true);

// error_log(print_r($data,true),0);

file_put_contents("log.txt", $cleanJson, FILE_APPEND | LOCK_EX);

$respuesta = "";
// echo $response;

if(isset($data['queryResult']['responseMessages'][0]['text']['text'][0])) {
	$respuesta = $data['queryResult']['responseMessages'][0]['text']['text'][0];
}

if(isset($data['queryResult']['responseMessages'][1]['text']['text'][0])) {
	$respuesta = $respuesta."\n".$data['queryResult']['responseMessages'][1]['text']['text'][0];
}


echo json_encode(["mensajeResultado" => $respuesta]);

/*
// Configuración de la API de OpenAI
$apiKey = "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";
$client = OpenAI::client($apiKey);

// Configuración de la base de datos
$host = "localhost";
$db = "orderbot_db";
$user = "admin";
$pass = "6ycv7nzF7MC9dC4T";

// Conexión a la base de datos con manejo de errores
try {
    $pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die(json_encode(["error" => "Error de conexión a la base de datos: " . $e->getMessage()]));
}

// Función para obtener todas las funciones personalizadas
function obtenerFuncionesPersonalizadas($asistente_id)
{
    global $pdo;

    $stmt = $pdo->query("SELECT * FROM funciones_personalizadas where asistente_id = '".$asistente_id."'");
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}



// Función para ejecutar una función personalizada con control de errores
function ejecutarFuncionPersonalizada($funcion, $parametros, $userId)
{
    $url = $funcion['api_url'];
    $metodo = $funcion['api_method'];
    $headers = json_decode($funcion['api_headers'], true);
    $variables_template = json_decode($funcion['api_body_template'], true);

    $ch = curl_init();
    $variables = [];
    foreach ($variables_template as $key => $value) {
        $variables[$key] = $parametros[$value] ?? urlencode($value);
    }

    $variables['wischat_id'] = $userId;

    if ($metodo == 'GET') {
        if (!empty($variables)) {
            $url .= "?" . http_build_query($variables);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Agregar timeout para evitar esperas indefinidas

    if ($headers) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    if ($metodo === 'POST') {
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($variables));
    }

    error_log("url ".$url." funcion ".print_r($funcion,true),0);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if ($response === false) {
        $error = curl_error($ch);
        curl_close($ch);
        return json_encode(["error" => "Error en la petición cURL: " . $error]);
    }

    curl_close($ch);

    if ($httpCode !== 200) {
        return json_encode(["error" => "La API devolvió el código HTTP $httpCode"]);
    }

    return $response;
}

// Función para agregar un usuario
function agregarUsuario($nombre)
{
    global $pdo;

    $stmt = $pdo->prepare("INSERT INTO usuarios (nombre) VALUES (:nombre) ON DUPLICATE KEY UPDATE nombre = VALUES(nombre)");
    $stmt->execute(["nombre" => $nombre]);

    $stmt = $pdo->prepare("SELECT id FROM usuarios WHERE nombre = :nombre");
    $stmt->execute(["nombre" => $nombre]);
    return $stmt->fetchColumn();
}



// Función para manejar threads con control de errores y bucles limitados
function manejarThread($usuarioId, $mensaje, $bot, $userId, $funciones = [])
{
    global $pdo, $client;

    try {
        $stmt = $pdo->prepare(
            "SELECT thread_id FROM threads WHERE usuario_id = :usuario_id AND asistente_id = :asistente_id ORDER BY fecha_creacion DESC LIMIT 1"
        );
        $stmt->execute(["usuario_id" => $usuarioId, "asistente_id" => $bot]);
        $currentThread = $stmt->fetchColumn();

        if ($currentThread) {
            $client->threads()->messages()->create($currentThread, [
                "role" => "user",
                "content" => $mensaje
            ]);

            $respuesta = $client->threads()->runs()->create($currentThread, [
                "assistant_id" => $bot,
                "tools" => $funciones
            ]);
        } else {
            $respuesta = $client->threads()->createAndRun([
                "assistant_id" => $bot,
                "thread" => [
                    "messages" => [
                        [
                            "role" => "user",
                            "content" => $mensaje,
                        ],
                    ],
                ],
                "tools" => $funciones
            ]);

            $currentThread = $respuesta->threadId;

            $stmt = $pdo->prepare(
                "INSERT INTO threads (thread_id, usuario_id, asistente_id, fecha_creacion) VALUES (:thread_id, :usuario_id, :asistente_id, NOW())"
            );
            $stmt->execute([
                "thread_id" => $currentThread,
                "usuario_id" => $usuarioId,
                "asistente_id" => $bot,
            ]);
        }

        // Evitar bucle infinito: máximo 10 intentos
        $maxIntentos = 20;
        $intentos = 0;

        do {
            $run = $client->threads()->runs()->retrieve($currentThread, $respuesta->id);
            if (!$run) {
                echo json_encode(["error" => "No se pudo obtener la respuesta del asistente"]);
                return;
            }

	    error_log("run ".$run->status." + ".$intentos." + ".$userId,0);

            if ($run->status === "requires_action") {
                $toolOutputs = [];

                foreach ($run->requiredAction->submitToolOutputs->toolCalls as $toolCall) {
                    $functionName = $toolCall->function->name;
                    $args = json_decode($toolCall->function->arguments, true);
                    $callId = $toolCall->id;

                    $funcionesPersonalizadas = obtenerFuncionesPersonalizadas($bot);

                    // error_log(" lista_funciones ".print_r( $funcionesPersonalizadas, true),0 );
                    error_log("funcion ".$functionName,0);

                    $funcion = array_filter($funcionesPersonalizadas, fn($f) => $f['nombre_funcion'] === $functionName);

                    

                    if ($funcion) {
                        $funcion = array_shift($funcion);
                        $result = ejecutarFuncionPersonalizada($funcion, $args, $userId);

                    error_log("resultado ".$result,0);
                        $toolOutputs[] = [
                            "tool_call_id" => $callId,
                            "output" => $result,
                        ];
                    }
                }

                $client->threads()->runs()->submitToolOutputs($currentThread, $respuesta->id, [
                    "tool_outputs" => $toolOutputs,
                ]);
            }

            sleep(1);
            $intentos++;
        } while ($run->status != "completed" && $intentos < $maxIntentos);

        if ($intentos >= $maxIntentos) {
            echo json_encode(["error" => "El asistente no pudo completar la solicitud en el tiempo esperado"]);
            return;
        }

        $response = $client->threads()->messages()->list($currentThread, ["limit" => 1]);
        echo json_encode(["mensajeResultado" => $response["data"][0]["content"][0]["text"]["value"]]);
error_log(" respuesta ".$response["data"][0]["content"][0]["text"]["value"],0 );
    } catch (Exception $e) {
        echo json_encode(["error" => "Error en la ejecución: " . $e->getMessage()]);
    }
}


// Cargar funciones personalizadas
$funciones = [];
$funcionesPersonalizadas = obtenerFuncionesPersonalizadas($bot);

// error_log("funciones ".print_r($funcionesPersonalizadas,true),0);

foreach ($funcionesPersonalizadas as $funcion) {
    $funciones[] = json_decode($funcion['parametros'], true);
}



// Manejar el mensaje del usuario
try {
    $usuarioId = agregarUsuario($userId);
    manejarThread($usuarioId, $userMessage, $bot, $userId, $funciones);
} catch (Exception $e) {
    echo json_encode(["error" => "Error: " . $e->getMessage()]);
}
*/
?>

