<?php
/***************************************************************************
 *  WEBHOOK META – PHP 8.2 - VERSIÓN CON DEBUG DETALLADO
 *  Captura mensajes, comentarios Y message_reads + LOG COMPLETO
 ***************************************************************************/

error_reporting(E_ALL);
ini_set('display_errors', '1');

require_once __DIR__ . '/config.php';

define('META_VERIFY_TOKEN', 'netfan_webhook_2025');
define(
    'META_PAGE_ACCESS_TOKEN',
    'EAAHTdFCuZAP0BQP8Q9GVwa4f93ChvHIZBebyjHOikCYSwGCZCWM9nwODaL7PiU6C0vdWBpxUZCyyL9UNyZBtUyeuVvpe2IZBcxIvTaB5DVuXfmjLZC3KnmE1L50OOFxrNQ9a1CXty9vKK7f2D6PLFQrUy7dLttfkUer8OTOlxfgdZB4kzZCrPNzombhZBTQH6FHds9qVEZBkXSmCm8JGRkehEXyJgZDZD'
);

// ============================================================
// HELPERS DB
// ============================================================

function db_is_ready(): bool
{
    if (isset($GLOBALS['mysqli']) &&
        $GLOBALS['mysqli'] instanceof mysqli &&
        !$GLOBALS['mysqli']->connect_errno) {
        return true;
    }

    if (!class_exists('mysqli')) {
        return false;
    }

    $mysqli = @new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    if ($mysqli->connect_errno) {
        return false;
    }

    $mysqli->set_charset('utf8mb4');
    $GLOBALS['mysqli'] = $mysqli;
    return true;
}

function db_log_payload(string $payload): void
{
    if (!db_is_ready()) {
        return;
    }

    $mysqli = $GLOBALS['mysqli'];
    $sql    = 'INSERT INTO meta_webhook_log (payload) VALUES (?)';

    if ($stmt = $mysqli->prepare($sql)) {
        $stmt->bind_param('s', $payload);
        $stmt->execute();
        $stmt->close();
    }
}

function log_request(?string $rawBody): void
{
    $rawBody = ($rawBody === false) ? '' : (string)$rawBody;

    $payload = json_encode(
        [
            'time'   => date('Y-m-d H:i:s'),
            'method' => $_SERVER['REQUEST_METHOD'] ?? '',
            'get'    => $_GET,
            'post'   => $_POST,
            'raw'    => $rawBody,
        ],
        JSON_UNESCAPED_UNICODE
    );

    db_log_payload($payload);
}

// Helper para logging de debug
function debug_log(string $message): void
{
    $logEntry = json_encode([
        'time' => date('Y-m-d H:i:s'),
        'debug' => $message
    ], JSON_UNESCAPED_UNICODE);
    
    db_log_payload($logEntry);
}

// ============================================================
// LEO EL CUERPO Y LO LOGUEO
// ============================================================
$rawBody = file_get_contents('php://input');
log_request($rawBody);

// ============================================================
// MANEJO DE GET (verificación y test)
// ============================================================
if ($_SERVER['REQUEST_METHOD'] === 'GET') {

    $mode      = $_GET['hub_mode'] ?? ($_GET['hub.mode'] ?? '');
    $token     = $_GET['hub_verify_token'] ?? ($_GET['hub.verify_token'] ?? '');
    $challenge = $_GET['hub_challenge'] ?? ($_GET['hub.challenge'] ?? '');

    if ($mode === 'subscribe') {
        if ($token === META_VERIFY_TOKEN) {
            echo $challenge;
            exit;
        }

        http_response_code(403);
        echo 'Token inválido';
        exit;
    }

    if (isset($_GET['test'])) {
        if (db_is_ready()) {
            echo 'TEST_OK – BD conectada y request logueada en meta_webhook_log';
        } else {
            echo 'TEST_OK – PERO sin conexión a BD (revisar config.php / DB_* )';
        }
        exit;
    }

    echo 'WEBHOOK_OK';
    exit;
}

// ============================================================
// RECEPCIÓN DE EVENTOS (POST)
// ============================================================

if ($rawBody === '' || $rawBody === false) {
    http_response_code(200);
    echo 'EMPTY_BODY';
    exit;
}

$data = json_decode($rawBody, true);
if (!is_array($data)) {
    http_response_code(200);
    echo 'BAD_JSON';
    exit;
}

debug_log('Datos recibidos: ' . json_encode($data, JSON_UNESCAPED_UNICODE));

// ============================================================
// NORMALIZACIÓN DE TESTS DE META
// ============================================================

if (!isset($data['entry']) && isset($data['field']) && isset($data['value'])) {

    debug_log("Detectado test de Meta con field: {$data['field']}");

    // TEST 1: messages
    if ($data['field'] === 'messages') {
        $v = $data['value'];
        
        // Corrección: timestamp puede venir en segundos o milisegundos
        $timestamp = $v['timestamp'] ?? time();
        if (is_string($timestamp)) {
            $timestamp = (int)$timestamp;
        }
        // Si el timestamp es muy grande (milisegundos), lo dejamos. Si es pequeño (segundos), lo usamos tal cual
        
        $data = [
            'object' => 'page',
            'entry'  => [
                [
                    'id'        => $v['recipient']['id'] ?? '0',
                    'time'      => $timestamp,
                    'messaging' => [
                        [
                            'sender'    => $v['sender']    ?? [],
                            'recipient' => $v['recipient'] ?? [],
                            'timestamp' => $timestamp,
                            'message'   => $v['message']   ?? [],
                        ],
                    ],
                ],
            ],
        ];
        
        debug_log('Test messages convertido a estructura entry');
    }

    // TEST 2: message_reads
    elseif ($data['field'] === 'message_reads') {
        $v = $data['value'];
        
        $timestamp = $v['timestamp'] ?? time();
        if (is_string($timestamp)) {
            $timestamp = (int)$timestamp;
        }
        
        $data = [
            'object' => 'page',
            'entry'  => [
                [
                    'id'        => $v['recipient']['id'] ?? '0',
                    'time'      => $timestamp,
                    'messaging' => [
                        [
                            'sender'    => $v['sender']    ?? [],
                            'recipient' => $v['recipient'] ?? [],
                            'timestamp' => $timestamp,
                            'read'      => $v['read']      ?? [],
                        ],
                    ],
                ],
            ],
        ];
        
        debug_log('Test message_reads convertido a estructura entry');
    }

    // TEST 3: feed
    elseif ($data['field'] === 'feed') {
        $v = $data['value'];
        $data = [
            'object' => 'page',
            'entry'  => [
                [
                    'id'      => $v['from']['id'] ?? '0',
                    'time'    => isset($v['created_time']) ? (int)$v['created_time'] : time(),
                    'changes' => [
                        [
                            'field' => 'feed',
                            'value' => $v,
                        ],
                    ],
                ],
            ],
        ];
        
        debug_log('Test feed convertido a estructura entry');
    }
}

if (!isset($data['entry']) || !is_array($data['entry'])) {
    debug_log('ERROR: No hay entry en los datos');
    http_response_code(200);
    echo 'NO_ENTRY';
    exit;
}

debug_log('Procesando ' . count($data['entry']) . ' entries');

// ============================================================
// PROCESAR ENTRIES
// ============================================================

db_is_ready();
$mysqli = $GLOBALS['mysqli'] ?? null;

if (!$mysqli instanceof mysqli) {
    debug_log('ERROR: No hay conexión mysqli disponible');
    http_response_code(200);
    echo 'DB_ERROR';
    exit;
}

foreach ($data['entry'] as $entryIndex => $entry) {

    $pageId = $entry['id'] ?? null;
    debug_log("Procesando entry $entryIndex, pageId: $pageId");

    // --------------------------------------------------------
    // A) MENSAJES PRIVADOS (Messenger)
    // --------------------------------------------------------
    if (isset($entry['messaging']) && is_array($entry['messaging'])) {

        debug_log('Encontrados ' . count($entry['messaging']) . ' mensajes en messaging');

        foreach ($entry['messaging'] as $msgIndex => $msg) {

            $sender    = $msg['sender']['id']    ?? null;
            $recipient = $msg['recipient']['id'] ?? null;

            debug_log("Mensaje $msgIndex - sender: $sender, recipient: $recipient");

            // Manejo mejorado del timestamp
            $timestampValue = $msg['timestamp'] ?? time();
            if (is_string($timestampValue)) {
                $timestampValue = (int)$timestampValue;
            }
            
            // Si el timestamp tiene más de 10 dígitos, está en milisegundos
            if ($timestampValue > 9999999999) {
                $timestampUnix = (int)floor($timestampValue / 1000);
            } else {
                $timestampUnix = $timestampValue;
            }

            $createdAt = date('Y-m-d H:i:s', $timestampUnix);

            // Dirección por defecto
            $direction = 'in';
            $messageId = null;
            $text      = '';

            // CASO 1: Mensaje normal
            if (isset($msg['message'])) {
                $isEcho    = isset($msg['message']['is_echo']) ? (int)$msg['message']['is_echo'] : 0;
                $direction = $isEcho ? 'out' : 'in';
                $messageId = $msg['message']['mid']  ?? null;
                $text      = $msg['message']['text'] ?? '';
                
                debug_log("Tipo: mensaje, text: $text, direction: $direction");
            }
            // CASO 2: Evento de lectura (read)
            elseif (isset($msg['read'])) {
                $direction = 'in';
                $messageId = null;
                $watermark = $msg['read']['watermark'] ?? '';
                $text      = "READ_EVENT (watermark: $watermark)";
                
                debug_log("Tipo: read event, watermark: $watermark");
            }
            // CASO 3: Evento de entrega (delivery)
            elseif (isset($msg['delivery'])) {
                $direction = 'out';
                $messageId = null;
                $text      = 'DELIVERY_EVENT';
                
                debug_log("Tipo: delivery event");
            }
            // CASO 4: Reacción
            elseif (isset($msg['reaction'])) {
                $direction = 'in';
                $messageId = null;
                $text      = 'REACTION: ' . ($msg['reaction']['emoji'] ?? '');
                
                debug_log("Tipo: reaction");
            }

            $rawEvent = json_encode($msg, JSON_UNESCAPED_UNICODE);

            $sql = "
                INSERT INTO meta_messages
                (sender_id, recipient_id, message_id, text, direction, raw_json, created_at)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ";

            if ($stmt = $mysqli->prepare($sql)) {
                $stmt->bind_param(
                    'sssssss',
                    $sender,
                    $recipient,
                    $messageId,
                    $text,
                    $direction,
                    $rawEvent,
                    $createdAt
                );
                
                if ($stmt->execute()) {
                    $insertId = $mysqli->insert_id;
                    debug_log("✓ Mensaje guardado en meta_messages con ID: $insertId");
                } else {
                    debug_log("✗ ERROR al guardar mensaje: " . $stmt->error);
                }
                
                $stmt->close();
            } else {
                debug_log("✗ ERROR al preparar SQL: " . $mysqli->error);
            }
        }
    }

    // --------------------------------------------------------
    // B) COMENTARIOS / POSTS (feed)
    // --------------------------------------------------------
    if (isset($entry['changes']) && is_array($entry['changes'])) {

        debug_log('Encontrados ' . count($entry['changes']) . ' cambios en feed');

        foreach ($entry['changes'] as $ch) {

            if (($ch['field'] ?? '') !== 'feed') {
                continue;
            }

            $value = $ch['value'] ?? [];
            $item  = $value['item'] ?? '';

            if (!in_array($item, ['comment', 'post', 'status'], true)) {
                continue;
            }

            $commentId = $value['comment_id'] ?? ($value['post_id'] ?? null);
            $parentId  = $value['parent_id']  ?? null;
            $fromId    = $value['from']['id']   ?? null;
            $fromName  = $value['from']['name'] ?? null;
            $message   = $value['message'] ?? '';

            $ts        = isset($value['created_time']) ? (int)$value['created_time'] : time();
            $createdAt = date('Y-m-d H:i:s', $ts);

            $rawChange = json_encode($ch, JSON_UNESCAPED_UNICODE);

            $sql = "
                INSERT INTO meta_comments
                (comment_id, parent_id, from_id, from_name, message, raw_json, created_at)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ";

            if ($stmt = $mysqli->prepare($sql)) {
                $stmt->bind_param(
                    'sssssss',
                    $commentId,
                    $parentId,
                    $fromId,
                    $fromName,
                    $message,
                    $rawChange,
                    $createdAt
                );
                
                if ($stmt->execute()) {
                    $insertId = $mysqli->insert_id;
                    debug_log("✓ Comentario guardado en meta_comments con ID: $insertId");
                } else {
                    debug_log("✗ ERROR al guardar comentario: " . $stmt->error);
                }
                
                $stmt->close();
            }
        }
    }
}

debug_log('Procesamiento completado exitosamente');

http_response_code(200);
echo 'EVENT_RECEIVED';