<?php
// test_jingle.php - PHP 8.2
// Chat de prueba para entrenar / ajustar el prompt del bot de ventas (JINGLE).
// - Conversación + memoria en SESSION
// - Prompt editable desde UI
// - OpenAI via config.php (OPENAI_API_KEY)
// - Modelo por defecto: gpt-4o-mini (fallbacks a gpt-3.5-turbo)
// - Parche: si dice "acá está la letra" pero no pega letra, regenera automáticamente
// - Regla: evitar terminar en "?"

if (session_status() === PHP_SESSION_NONE) session_start();
if (!ob_get_level()) ob_start();
@date_default_timezone_set('America/Argentina/Buenos_Aires');

require_once __DIR__ . '/config.php';

error_reporting(0);
ini_set('display_errors', '0');

function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }

function default_prompt_jingle(): string {
    return trim(<<<'PROMPT'
Actuás como asistente de ventas de NetFan, especializado en jingles (canciones publicitarias).

Objetivo
- Guiar al cliente con pocas vueltas hasta obtener la información necesaria.
- Crear una letra de jingle SIEMPRE de 4 estrofas, no muy larga, con los datos del cliente.
- Pedir correcciones y reenviar la letra hasta que el cliente diga que le gusta.
- Cuando la letra gusta: ofrecer pago por transferencia al alias netfan2 (a nombre de Laura Pizorno).
- Si pide demo: responder “Dale, ya te la envío, dame un momento” y no explicar procesos internos ni mencionar humanos.

Estilo
- Español rioplatense, directo, sin hablar de más.
- No inventes datos. Si falta algo, pedilo.
- Si el cliente manda mensajes cortos tipo “estas?”, “ok”, “dale”: respondé breve y retomá el paso pendiente sin repetir todo.
- No uses emojis.
- Evitá cerrar los mensajes con preguntas. Si necesitás pedir datos, hacelo con una sola pregunta y no termines con “?”.

Qué info pedir (según caso)
- Negocio / servicio: nombre del negocio, rubro, qué vende o qué hace, 2 o 3 puntos fuertes, promos u oferta si tiene, ubicación (barrio/ciudad), teléfono/WhatsApp si quiere.
- Regalo a persona: nombre, motivo, 2 o 3 rasgos o cosas que le gusten, a qué se dedica o hobby (ej: fútbol), estilo musical que le gusta.
- Club / evento / grupo: nombre, actividad, ciudad, mensaje que quieren transmitir, a quién va dirigido, alguna frase/slogan.

Regla clave para la letra
- Cuando generes la letra: debe venir completa en el mismo mensaje, en 4 estrofas separadas por una línea en blanco.
- No escribas “a continuación” si no pegás la letra en el mismo mensaje.

Cierre demo / pago
- Si el cliente dice “ok me gusta”: ofrecer pago.
- Si el cliente dice “mandame la demo”: responder exactamente con este estilo: “Dale, ya te la envío, dame un momento.” y detener ahí (no más explicación).

PROMPT);
}

function session_init() {
    if (!isset($_SESSION['tj_prompt']) || trim((string)$_SESSION['tj_prompt']) === '') {
        $_SESSION['tj_prompt'] = default_prompt_jingle();
    }
    if (!isset($_SESSION['tj_messages']) || !is_array($_SESSION['tj_messages'])) {
        $_SESSION['tj_messages'] = [];
    }
    if (!isset($_SESSION['tj_memory']) || !is_array($_SESSION['tj_memory'])) {
        $_SESSION['tj_memory'] = [
            'tipo' => '',
            'nombre_comercio' => '',
            'rubro' => '',
            'ubicacion' => '',
            'telefono' => '',
            'promos' => '',
            'horarios' => '',
            'nombre_persona' => '',
            'gustos' => '',
            'motivo' => '',
            'estilo_musical' => '',
            'estado' => 'inicio', // inicio|recolectando|letra_enviada|ajustes|cierre
        ];
    }
    if (!isset($_SESSION['tj_last_raw'])) $_SESSION['tj_last_raw'] = '';
    if (!isset($_SESSION['tj_last_err'])) $_SESSION['tj_last_err'] = '';
    if (!isset($_SESSION['tj_last_http'])) $_SESSION['tj_last_http'] = 0;
    if (!isset($_SESSION['tj_last_model'])) $_SESSION['tj_last_model'] = '';
    if (!isset($_SESSION['tj_last_stage'])) $_SESSION['tj_last_stage'] = '';
    if (!isset($_SESSION['tj_last_needs']) || !is_array($_SESSION['tj_last_needs'])) $_SESSION['tj_last_needs'] = [];
}

function merge_memory(array $old, array $new): array {
    foreach ($new as $k => $v) {
        if (is_array($v)) {
            $old[$k] = merge_memory(isset($old[$k]) && is_array($old[$k]) ? $old[$k] : [], $v);
        } else {
            if ($v === null) continue;
            if (is_string($v) && trim($v) === '') continue;
            $old[$k] = $v;
        }
    }
    return $old;
}

function try_extract_json(string $s): ?array {
    $s = trim($s);
    $j = json_decode($s, true);
    if (is_array($j)) return $j;

    $p1 = strpos($s, '{');
    $p2 = strrpos($s, '}');
    if ($p1 !== false && $p2 !== false && $p2 > $p1) {
        $sub = substr($s, $p1, $p2 - $p1 + 1);
        $j2 = json_decode($sub, true);
        if (is_array($j2)) return $j2;
    }
    return null;
}

function openai_call_chat(array $payload, string &$raw, string &$err, int &$httpCode): bool {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => 'https://api.openai.com/v1/chat/completions',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 45,
        CURLOPT_CONNECTTIMEOUT => 12,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . (defined('OPENAI_API_KEY') ? OPENAI_API_KEY : ''),
        ],
        // mismo criterio que venís usando en tu server
        CURLOPT_SSL_VERIFYHOST => 0,
        CURLOPT_SSL_VERIFYPEER => 0,
    ]);
    $raw = (string)curl_exec($ch);
    $err = (string)curl_error($ch);
    $httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($err) return false;
    if ($httpCode < 200 || $httpCode >= 300) return false;
    return true;
}

function normalize_reply_no_question_end(string $txt): string {
    $t = trim($txt);
    if ($t === '') return $t;

    // si termina en "?" lo convertimos a punto
    $t = preg_replace('/\?\s*$/u', '.', $t);

    // recorte mínimo de espacios
    $t = preg_replace("/[ \t]+\n/u", "\n", $t);
    $t = preg_replace("/\n{4,}/u", "\n\n\n", $t);

    return trim($t);
}

function reply_parece_letra(string $txt): bool {
    $txt = trim((string)$txt);
    if ($txt === '') return false;

    // debe tener varias líneas, y preferentemente saltos de estrofa
    $lines = preg_split("/\R/u", $txt);
    $nonEmpty = 0;
    foreach ($lines as $l) if (trim($l) !== '') $nonEmpty++;

    $hasBreaks = (substr_count($txt, "\n\n") >= 2); // estrofas separadas
    $longEnough = ($nonEmpty >= 8); // mínimo razonable para 3-4 estrofas cortas

    // evitar falsos positivos tipo "acá tenés la letra"
    $tooShort = (mb_strlen($txt, 'UTF-8') < 120);

    return (($hasBreaks || $longEnough) && !$tooShort);
}

function openai_sales_jingle(
    string $prompt,
    array $messages,
    array $memory,
    string &$rawOut,
    string &$errorOut,
    int &$httpOut,
    string &$modelUsed
): ?array {
    if (!defined('OPENAI_API_KEY') || trim((string)OPENAI_API_KEY) === '') {
        $errorOut = 'Falta OPENAI_API_KEY en config.php';
        return null;
    }

    // Modelos: recomendado (estable) + fallbacks
    $models = [
        'gpt-4o-mini',
        'gpt-3.5-turbo',
        'gpt-3.5-turbo-0125',
    ];

    $rules = trim(<<<'RULES'
Respondé SIEMPRE en JSON válido, sin texto extra, con estas claves:
- reply: string (respuesta al cliente)
- stage: string (inicio|recolectando|letra_enviada|ajustes|cierre)
- needs: array de strings (datos que faltan o próximos pasos)
- memory: object con datos recordables. No inventes.

Restricciones obligatorias
- Sin emojis.
- Máximo 1 pregunta por mensaje y nunca termines con "?".
- Si stage es "letra_enviada" o "ajustes", el campo reply DEBE incluir la letra completa (3-4 estrofas) dentro del mismo reply.
- No escribas "a continuación te envío" si no pegás la letra en el mismo mensaje.
RULES);

    $sys = $prompt . "\n\n" . $rules;
    $memorySys = "MEMORIA_ACTUAL_JSON:\n" . json_encode($memory, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

    $baseMsgs = [];
    $baseMsgs[] = ['role'=>'system','content'=>$sys];
    $baseMsgs[] = ['role'=>'system','content'=>$memorySys];

    foreach ($messages as $m) {
        if (!isset($m['role'], $m['content'])) continue;
        $role = ($m['role'] === 'assistant') ? 'assistant' : 'user';
        $baseMsgs[] = ['role'=>$role,'content'=>(string)$m['content']];
    }

    if (count($messages) === 0) {
        $baseMsgs[] = ['role'=>'user','content'=>'INICIO_CONVERSACION'];
    }

    $lastErr = '';
    $lastRaw = '';
    $lastHttp = 0;
    $lastModel = '';

    foreach ($models as $model) {
        $payload = [
            'model' => $model,
            'temperature' => 0.35,
            'max_tokens' => 650,
            'messages' => $baseMsgs,
            'response_format' => ['type' => 'json_object'],
        ];

        $raw = ''; $err = ''; $code = 0;
        $ok = openai_call_chat($payload, $raw, $err, $code);

        // fallback si response_format rompe
        if (!$ok && $code === 400) {
            unset($payload['response_format']);
            $raw = ''; $err = ''; $code = 0;
            $ok = openai_call_chat($payload, $raw, $err, $code);
        }

        $lastErr = $err ? $err : ("HTTP ".$code." (OpenAI)");
        $lastRaw = $raw;
        $lastHttp = $code;
        $lastModel = $model;

        if (!$ok) {
            continue;
        }

        $data = json_decode($raw, true);
        $content = (string)($data['choices'][0]['message']['content'] ?? '');
        $json = try_extract_json($content);

        if (!$json) {
            $lastErr = 'La IA no devolvió JSON válido.';
            continue;
        }

        $out = [
            'reply' => (string)($json['reply'] ?? ''),
            'stage' => (string)($json['stage'] ?? ''),
            'needs' => is_array($json['needs'] ?? null) ? $json['needs'] : [],
            'memory' => is_array($json['memory'] ?? null) ? $json['memory'] : [],
        ];

        $out['reply'] = normalize_reply_no_question_end($out['reply']);

        if (trim($out['reply']) === '') {
            $lastErr = 'JSON sin reply.';
            continue;
        }

        // Parche: si dice "acá está la letra" pero no hay letra real, regeneramos
        $replyLower = mb_strtolower($out['reply'], 'UTF-8');
        $prometeLetra = (
            strpos($replyLower, 'a continuación') !== false ||
            strpos($replyLower, 'te envío la letra') !== false ||
            strpos($replyLower, 'te envio la letra') !== false ||
            strpos($replyLower, 'aquí tienes la letra') !== false ||
            strpos($replyLower, 'aca tenes la letra') !== false ||
            strpos($replyLower, 'acá tenés la letra') !== false
        );

        $stageLetra = in_array($out['stage'], ['letra_enviada','ajustes'], true);

        if (($prometeLetra || $stageLetra) && !reply_parece_letra($out['reply'])) {
            // Forzamos regeneración y la hacemos SIEMPRE con gpt-4o-mini si está disponible
            $regenModel = 'gpt-4o-mini';

            $regenMsgs = $baseMsgs;
            $regenMsgs[] = [
                'role' => 'user',
                'content' => "REGENERAR. Pegá ahora la letra completa del jingle en el campo reply. 3 o 4 estrofas. Sin encabezados. Sin prometer nada. Sin emojis. No termines en signo de pregunta."
            ];

            $regenPayload = [
                'model' => $regenModel,
                'temperature' => 0.25,
                'max_tokens' => 650,
                'messages' => $regenMsgs,
                'response_format' => ['type' => 'json_object'],
            ];

            $raw2 = ''; $err2 = ''; $code2 = 0;
            $ok2 = openai_call_chat($regenPayload, $raw2, $err2, $code2);

            if (!$ok2 && $code2 === 400) {
                unset($regenPayload['response_format']);
                $raw2 = ''; $err2 = ''; $code2 = 0;
                $ok2 = openai_call_chat($regenPayload, $raw2, $err2, $code2);
            }

            // guardamos raw/hhtp/model del reintento para debug
            $rawOut = $raw2 ?: $raw;
            $httpOut = $code2 ?: $code;
            $modelUsed = $regenModel;

            if ($ok2) {
                $data2 = json_decode($raw2, true);
                $content2 = (string)($data2['choices'][0]['message']['content'] ?? '');
                $json2 = try_extract_json($content2);

                if (is_array($json2) && !empty($json2['reply'])) {
                    $out['reply'] = normalize_reply_no_question_end((string)$json2['reply']);
                    $out['stage'] = (string)($json2['stage'] ?? $out['stage']);
                    $out['needs'] = is_array($json2['needs'] ?? null) ? $json2['needs'] : $out['needs'];
                    $out['memory'] = is_array($json2['memory'] ?? null) ? $json2['memory'] : $out['memory'];
                }
            } else {
                $errorOut = $err2 ? $err2 : ("HTTP ".$code2." (OpenAI)");
                // devolvemos lo anterior igual, pero ya con aviso (el front lo muestra)
            }

            // si sigue sin parecer letra, bajamos stage para que el flujo no “avance”
            if (!reply_parece_letra($out['reply'])) {
                $out['stage'] = 'recolectando';
                if (!is_array($out['needs'])) $out['needs'] = [];
                $out['needs'][] = 'Faltó pegar la letra completa; volver a generar letra';
            }
        }

        // normalización final
        $out['reply'] = normalize_reply_no_question_end($out['reply']);

        // debug del intento exitoso (si no hubo reintento)
        if ($rawOut === '') $rawOut = $raw;
        if ($httpOut === 0) $httpOut = $code;
        if ($modelUsed === '') $modelUsed = $model;

        return $out;
    }

    // si no hubo éxito
    $rawOut = $lastRaw;
    $httpOut = $lastHttp;
    $modelUsed = $lastModel;
    $errorOut = $lastErr;

    return null;
}

// ---------- init ----------
session_init();

$action = $_POST['action'] ?? '';

if ($action === 'reset') {
    $_SESSION['tj_messages'] = [];
    $_SESSION['tj_memory'] = [
        'tipo' => '',
        'nombre_comercio' => '',
        'rubro' => '',
        'ubicacion' => '',
        'telefono' => '',
        'promos' => '',
        'horarios' => '',
        'nombre_persona' => '',
        'gustos' => '',
        'motivo' => '',
        'estilo_musical' => '',
        'estado' => 'inicio',
    ];
    $_SESSION['tj_last_raw'] = '';
    $_SESSION['tj_last_err'] = '';
    $_SESSION['tj_last_http'] = 0;
    $_SESSION['tj_last_model'] = '';
    $_SESSION['tj_last_stage'] = '';
    $_SESSION['tj_last_needs'] = [];
    header('Location: test_jingle.php');
    exit;
}

if ($action === 'save_prompt') {
    $p = trim((string)($_POST['prompt'] ?? ''));
    if ($p !== '') $_SESSION['tj_prompt'] = $p;
    header('Location: test_jingle.php');
    exit;
}

if ($action === 'send') {
    $txt = trim((string)($_POST['text'] ?? ''));
    if ($txt !== '') {
        $_SESSION['tj_messages'][] = ['role'=>'user','content'=>$txt,'ts'=>time()];

        $raw = ''; $err = ''; $http = 0; $model = '';
        $res = openai_sales_jingle(
            (string)$_SESSION['tj_prompt'],
            (array)$_SESSION['tj_messages'],
            (array)$_SESSION['tj_memory'],
            $raw,
            $err,
            $http,
            $model
        );

        // guardar debug (limitamos raw para no explotar)
        $_SESSION['tj_last_raw'] = (mb_strlen($raw, 'UTF-8') > 12000) ? (mb_substr($raw, 0, 12000, 'UTF-8') . "\n...[TRUNCADO]") : $raw;
        $_SESSION['tj_last_err'] = $err;
        $_SESSION['tj_last_http'] = $http;
        $_SESSION['tj_last_model'] = $model;

        if ($res) {
            $_SESSION['tj_messages'][] = ['role'=>'assistant','content'=>$res['reply'],'ts'=>time()];
            $_SESSION['tj_memory'] = merge_memory((array)$_SESSION['tj_memory'], (array)$res['memory']);
            $_SESSION['tj_last_stage'] = (string)$res['stage'];
            $_SESSION['tj_last_needs'] = is_array($res['needs']) ? $res['needs'] : [];
        } else {
            $_SESSION['tj_messages'][] = [
                'role'=>'assistant',
                'content'=>"No pude responder por un error. HTTP ".$http." Modelo ".$model.". " . ($err ? "Detalle: ".$err : ''),
                'ts'=>time()
            ];
        }
    }
    header('Location: test_jingle.php');
    exit;
}

$messages = (array)$_SESSION['tj_messages'];
if (count($messages) === 0) {
    $messages[] = [
        'role'=>'assistant',
        'content'=>'Hola, soy el asistente de NetFan. Decime para qué querés la canción (negocio, regalo u otro) y sigo con eso.',
        'ts'=>time()
    ];
}

$prompt = (string)$_SESSION['tj_prompt'];
$memory = (array)$_SESSION['tj_memory'];
$lastErr = (string)$_SESSION['tj_last_err'];
$lastHttp = (int)($_SESSION['tj_last_http'] ?? 0);
$lastModel = (string)($_SESSION['tj_last_model'] ?? '');
$stage = (string)$_SESSION['tj_last_stage'];
$needs = (array)$_SESSION['tj_last_needs'];
$lastRaw = (string)$_SESSION['tj_last_raw'];

if (ob_get_level()) @ob_clean();
?>
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test_jingle</title>
<style>
*{box-sizing:border-box}
body{margin:0;font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;background:#0b1220;color:#e5e7eb}
.top{position:sticky;top:0;z-index:20;background:rgba(2,6,23,0.92);backdrop-filter:blur(10px);border-bottom:1px solid rgba(255,255,255,0.08);padding:12px 14px;display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.pill{background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.10);padding:8px 12px;border-radius:999px;font-weight:900;font-size:13px}
.btn{display:inline-block;text-decoration:none;color:#e5e7eb;background:rgba(59,130,246,0.18);border:1px solid rgba(59,130,246,0.35);padding:8px 12px;border-radius:999px;font-weight:900;font-size:13px;cursor:pointer}
.btn:hover{background:rgba(59,130,246,0.28)}
.btn2{background:rgba(34,197,94,0.18);border-color:rgba(34,197,94,0.35)}
.btn2:hover{background:rgba(34,197,94,0.28)}
.btn3{background:rgba(239,68,68,0.18);border-color:rgba(239,68,68,0.35)}
.btn3:hover{background:rgba(239,68,68,0.28)}
.wrap{padding:16px;max-width:1400px;margin:0 auto}
.grid{display:grid;grid-template-columns:1fr 420px;gap:14px}
@media(max-width:1100px){.grid{grid-template-columns:1fr}}
.card{background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.08);border-radius:16px;overflow:hidden}
.card h3{margin:0;padding:14px 14px;border-bottom:1px solid rgba(255,255,255,0.08);font-size:14px;letter-spacing:0.2px}
.card .body{padding:14px}
.chat{display:flex;flex-direction:column;gap:10px;min-height:520px}
.bubble{max-width:900px;padding:10px 12px;border-radius:14px;border:1px solid rgba(255,255,255,0.10);white-space:pre-wrap;line-height:1.45;font-size:14px}
.me{align-self:flex-end;background:rgba(59,130,246,0.14)}
.bot{align-self:flex-start;background:rgba(255,255,255,0.05)}
.meta{opacity:.7;font-size:12px;margin-top:4px}
.formRow{display:flex;gap:10px;margin-top:12px}
.input{flex:1;background:rgba(0,0,0,0.18);border:1px solid rgba(255,255,255,0.12);border-radius:14px;padding:10px 12px;color:#e5e7eb;font-size:14px;outline:none}
.input:focus{border-color:rgba(59,130,246,0.55)}
.small{color:rgba(229,231,235,0.75);font-size:12px;line-height:1.5}
.pre{white-space:pre-wrap;background:rgba(0,0,0,0.18);border:1px solid rgba(255,255,255,0.08);border-radius:14px;padding:10px;min-height:180px;font-size:12px;line-height:1.45;overflow:auto;max-height:320px}
.tagRow{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.tag{background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.10);padding:6px 10px;border-radius:999px;font-weight:900;font-size:12px}
.err{color:#fca5a5;font-weight:900}
textarea{width:100%;min-height:220px;resize:vertical;background:rgba(0,0,0,0.18);border:1px solid rgba(255,255,255,0.12);border-radius:14px;padding:10px 12px;color:#e5e7eb;font-size:13px;outline:none}
textarea:focus{border-color:rgba(34,197,94,0.55)}
hr{border:none;border-top:1px solid rgba(255,255,255,0.08);margin:12px 0}
</style>
</head>
<body>

<div class="top">
  <span class="pill">test_jingle.php</span>
  <span class="pill">Stage: <?= h($stage ?: '—') ?></span>
  <span class="pill">Modelo: <?= h($lastModel ?: '—') ?></span>
  <span class="pill">HTTP: <?= (int)$lastHttp ?></span>
  <?php if ($lastErr): ?>
    <span class="pill err">Error: <?= h($lastErr) ?></span>
  <?php endif; ?>
  <form method="post" style="margin:0;">
    <input type="hidden" name="action" value="reset">
    <button class="btn btn3" type="submit">Reset chat</button>
  </form>
</div>

<div class="wrap">
  <div class="grid">

    <div class="card">
      <h3>Chat (simulás al cliente)</h3>
      <div class="body">
        <div class="chat" id="chat">
          <?php foreach ($messages as $m): ?>
            <?php $isMe = (($m['role'] ?? '') === 'user'); ?>
            <div class="bubble <?= $isMe ? 'me' : 'bot' ?>">
              <?= h((string)($m['content'] ?? '')) ?>
              <div class="meta"><?= $isMe ? 'Cliente' : 'Asistente' ?></div>
            </div>
          <?php endforeach; ?>
        </div>

        <form method="post" class="formRow" autocomplete="off">
          <input type="hidden" name="action" value="send">
          <input class="input" name="text" placeholder="Escribí como cliente..." autofocus>
          <button class="btn btn2" type="submit">Enviar</button>
        </form>

        <div class="small" style="margin-top:10px;">
          Si la IA vuelve a “prometer” letra sin pegarla, el sistema regenera automáticamente con gpt-4o-mini.
        </div>
      </div>
    </div>

    <div class="card">
      <h3>Prompt + Debug</h3>
      <div class="body">

        <div class="tagRow">
          <span class="tag">Memoria</span>
          <span class="tag">Needs</span>
          <span class="tag">Raw</span>
        </div>

        <div class="small">Prompt actual (podés editarlo y guardar):</div>
        <form method="post" style="margin-top:8px;">
          <input type="hidden" name="action" value="save_prompt">
          <textarea name="prompt"><?= h($prompt) ?></textarea>
          <div style="display:flex;gap:10px;margin-top:10px;">
            <button class="btn btn2" type="submit">Guardar prompt</button>
          </div>
        </form>

        <hr>

        <div class="small">Memoria actual (lo que el bot “recuerda”):</div>
        <div class="pre"><?= h(json_encode($memory, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) ?></div>

        <div style="height:10px;"></div>

        <div class="small">Needs (lo que falta / próximos pasos):</div>
        <div class="pre"><?= h(json_encode($needs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) ?></div>

        <div style="height:10px;"></div>

        <div class="small">Última respuesta cruda de OpenAI (debug):</div>
        <div class="pre"><?= h($lastRaw ?: '(vacío)') ?></div>

      </div>
    </div>

  </div>
</div>

<script>
(function(){
  var chat = document.getElementById('chat');
  if (chat) chat.scrollTop = chat.scrollHeight;
})();
</script>

</body>
</html>
