<?php
/**
 * Webhook para recibir notificaciones de Pagopar
 * Este archivo será llamado por Pagopar cuando se realice un pago
 * También maneja las redirecciones del usuario después del pago
 * 
 * IMPORTANTE: Debes configurar esta URL en tu panel de Pagopar
 */

require_once 'includes/db.php';
require_once 'includes/whatsapp_sender.php';

// Verificar si es una redirección del usuario (GET con hash) o notificación (POST)
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    // Obtener hash de diferentes formas posibles
    $hash = '';
    
    // Primer intento: desde parámetro GET
    if (isset($_GET['hash'])) {
        $hash = $_GET['hash'];
    }
    // Segundo intento: desde la URL completa (por si el hash está concatenado)
    elseif (preg_match('/webhook_pagopar\.php([a-zA-Z0-9]+)/', $_SERVER['REQUEST_URI'], $matches)) {
        $hash = $matches[1];
    }
    
    if (!empty($hash)) {
        // Redirigir al resultado del pago con HTTPS forzado
        $https_url = "https://" . $_SERVER['HTTP_HOST'] . "/resultado_pago_pagopar.php?hash=" . urlencode($hash);
        header("Location: " . $https_url);
        exit();
    } else {
        $https_url = "https://" . $_SERVER['HTTP_HOST'] . "/carrito.php?error=hash_invalido";
        header("Location: " . $https_url);
        exit();
    }
}

// Si no es GET con hash, procesar como notificación webhook
$input = file_get_contents('php://input');
$data = json_decode($input, true);

// Validar que se recibieron datos
if (empty($data)) {
    http_response_code(400);
    echo json_encode(['error' => 'No se recibieron datos']);
    exit();
}

// Cargar configuración de Pagopar
$pagoparConfig = require 'pagopar_config.php';

// Validar token de seguridad (si Pagopar lo envía)
// Esto depende de cómo Pagopar envíe la notificación, ajustar según documentación

$db = new Database();

try {
    // Crear directorio de logs si no existe
    if (!is_dir('logs')) {
        mkdir('logs', 0755, true);
    }
    
    // Log de debug para ver qué datos está enviando PagoPar
    $log_entry = date('Y-m-d H:i:s') . " - Webhook PagoPar - Datos recibidos: " . json_encode($data) . "\n";
    file_put_contents('logs/pagopar_webhook.log', $log_entry, FILE_APPEND | LOCK_EX);
    error_log("Webhook PagoPar - Datos recibidos: " . json_encode($data));
    
    // Detectar si los datos vienen en formato de PagoPar (con estructura 'resultado')
    $resultado_data = null;
    if (isset($data['respuesta']) && $data['respuesta'] === true && isset($data['resultado']) && is_array($data['resultado'])) {
        // Formato oficial de PagoPar
        $resultado_data = $data['resultado'][0] ?? null;
        $es_respuesta_pagopar = true;
    } else {
        // Formato directo (simulaciones o tests)
        $resultado_data = $data;
        $es_respuesta_pagopar = false;
    }
    
    if (!$resultado_data) {
        throw new Exception('No se encontraron datos de resultado en la notificación');
    }
    
    // Extraer información del pedido según el formato de PagoPar
    if ($es_respuesta_pagopar) {
        // Formato oficial de PagoPar
        $id_pedido_comercio = $resultado_data['numero_pedido'] ?? null;
        $hash_pagopar = $resultado_data['hash_pedido'] ?? $resultado_data['token'] ?? null;
        $monto_pagado = $resultado_data['monto'] ?? 0;
        $forma_pago = $resultado_data['forma_pago'] ?? null;
        $fecha_pago = $resultado_data['fecha_pago'] ?? null;
        $cancelado = $resultado_data['cancelado'] ?? false;
        $pagado = $resultado_data['pagado'] ?? false;
        
        // Determinar estado
        if ($cancelado) {
            $estado = 'cancelado';
        } elseif ($pagado) {
            $estado = 'pagado';
        } else {
            $estado = 'pendiente';
        }
    } else {
        // Formato de simulación o test
        $id_pedido_comercio = $resultado_data['id_pedido_comercio'] ?? $resultado_data['pedido_comercio_id'] ?? $resultado_data['order_id'] ?? null;
        $estado = $resultado_data['estado'] ?? $resultado_data['status'] ?? $resultado_data['state'] ?? null;
        $monto_pagado = $resultado_data['monto'] ?? $resultado_data['amount'] ?? $resultado_data['total'] ?? 0;
        $hash_pagopar = $resultado_data['hash'] ?? $resultado_data['token'] ?? $resultado_data['transaction_id'] ?? null;
        $forma_pago = $resultado_data['forma_pago'] ?? $resultado_data['payment_method'] ?? null;
        $fecha_pago = $resultado_data['fecha_pago'] ?? $resultado_data['payment_date'] ?? null;
    }
    
    // Para simulaciones de PagoPar, ser más flexivo con los datos requeridos
    $es_simulacion = isset($data['test']) || isset($data['simulation']) || 
                     (isset($data['environment']) && $data['environment'] === 'test') ||
                     !$es_respuesta_pagopar;
    
    if (!$fecha_pago) {
        $fecha_pago = date('Y-m-d H:i:s');
    }
    
    // Si no hay ID de pedido comercio, buscar el último pedido (para simulaciones)
    if (!$id_pedido_comercio && $es_simulacion) {
        $stmt = $db->prepare("SELECT id_pedido_comercio, hash_pagopar FROM pedidos_pagopar ORDER BY fecha_creacion DESC LIMIT 1");
        $stmt->execute();
        $ultimo_pedido = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($ultimo_pedido) {
            $id_pedido_comercio = $ultimo_pedido['id_pedido_comercio'];
            $hash_pagopar = $hash_pagopar ?: $ultimo_pedido['hash_pagopar'];
        }
    }
    
    // Si tenemos número de pedido de PagoPar, buscar por hash
    if (!$id_pedido_comercio && $hash_pagopar) {
        $stmt = $db->prepare("SELECT id_pedido_comercio FROM pedidos_pagopar WHERE hash_pagopar = ? ORDER BY fecha_creacion DESC LIMIT 1");
        $stmt->execute([$hash_pagopar]);
        $pedido_encontrado = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($pedido_encontrado) {
            $id_pedido_comercio = $pedido_encontrado['id_pedido_comercio'];
        }
    }
    
    // Validar datos mínimos requeridos
    if (!$id_pedido_comercio) {
        throw new Exception('ID del pedido comercio no encontrado en la notificación');
    }
    
    if (!$hash_pagopar && !$es_simulacion) {
        throw new Exception('Hash de PagoPar no encontrado en la notificación');
    }
    
    // Buscar el pedido en la base de datos - múltiples estrategias
    $pedido = null;
    
    // Estrategia 1: Buscar por ID de pedido comercio y hash (método preferido)
    if ($id_pedido_comercio && $hash_pagopar) {
        $stmt = $db->prepare("
            SELECT * FROM pedidos_pagopar 
            WHERE id_pedido_comercio = ? AND hash_pagopar = ?
        ");
        $stmt->execute([$id_pedido_comercio, $hash_pagopar]);
        $pedido = $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    // Estrategia 2: Buscar solo por hash (si el ID no coincide)
    if (!$pedido && $hash_pagopar) {
        $stmt = $db->prepare("
            SELECT * FROM pedidos_pagopar 
            WHERE hash_pagopar = ?
        ");
        $stmt->execute([$hash_pagopar]);
        $pedido = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($pedido) {
            // Actualizar el ID de pedido comercio con el encontrado
            $id_pedido_comercio = $pedido['id_pedido_comercio'];
        }
    }
    
    // Estrategia 3: Buscar solo por ID de pedido comercio
    if (!$pedido && $id_pedido_comercio) {
        $stmt = $db->prepare("
            SELECT * FROM pedidos_pagopar 
            WHERE id_pedido_comercio = ?
        ");
        $stmt->execute([$id_pedido_comercio]);
        $pedido = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($pedido) {
            $hash_pagopar = $pedido['hash_pagopar'];
        }
    }
    
    // Estrategia 4: Para simulaciones, usar el último pedido creado
    if (!$pedido && $es_simulacion) {
        $stmt = $db->prepare("
            SELECT * FROM pedidos_pagopar 
            ORDER BY fecha_creacion DESC LIMIT 1
        ");
        $stmt->execute();
        $pedido = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($pedido) {
            $id_pedido_comercio = $pedido['id_pedido_comercio'];
            $hash_pagopar = $pedido['hash_pagopar'];
        }
    }
    
    if (!$pedido) {
        throw new Exception('Pedido no encontrado en la base de datos con ID: ' . $id_pedido_comercio);
    }
    
    // Log de la estrategia usada para encontrar el pedido
    $log_strategy = date('Y-m-d H:i:s') . " - Pedido encontrado: ID={$pedido['id']}, Comercio={$pedido['id_pedido_comercio']}, Hash=" . substr($pedido['hash_pagopar'], 0, 20) . "...\n";
    file_put_contents('logs/pagopar_webhook.log', $log_strategy, FILE_APPEND | LOCK_EX);
    
    // Actualizar estado del pedido
    if ($hash_pagopar) {
        // Actualización normal con hash
        $stmt = $db->prepare("
            UPDATE pedidos_pagopar 
            SET estado = ?, 
                monto_pagado = ?, 
                forma_pago = ?,
                fecha_pago = ?,
                datos_notificacion = ?,
                fecha_actualizacion = NOW()
            WHERE id_pedido_comercio = ? AND hash_pagopar = ?
        ");
        
        $stmt->execute([
            $estado,
            $monto_pagado,
            $forma_pago,
            $fecha_pago,
            json_encode($data),
            $id_pedido_comercio,
            $hash_pagopar
        ]);
    } else {
        // Para simulaciones, actualizar solo por ID de pedido comercio
        $stmt = $db->prepare("
            UPDATE pedidos_pagopar 
            SET estado = ?, 
                monto_pagado = ?, 
                forma_pago = ?,
                fecha_pago = ?,
                datos_notificacion = ?,
                fecha_actualizacion = NOW()
            WHERE id_pedido_comercio = ?
        ");
        
        $stmt->execute([
            $estado,
            $monto_pagado,
            $forma_pago,
            $fecha_pago,
            json_encode($data),
            $id_pedido_comercio
        ]);
    }
    
    // Si el pago fue exitoso, realizar acciones adicionales
    if ($estado === 'pagado' || $estado === 'confirmado' || $estado === 'PAGADO' || $estado === 'CONFIRMADO' || $estado === 'completed' || $estado === 'success') {
        // Aquí puedes:
        // 1. Registrar la venta en tu sistema
        // 2. Enviar email de confirmación
        // 3. Actualizar stock
        // 4. Generar factura
        
        // Ejemplo: Registrar en tabla de ventas
        $datos_comprador = json_decode($pedido['datos_comprador'], true);
        $datos_productos = json_decode($pedido['datos_productos'], true);
        
        // Insertar venta (ajustar según tu estructura de BD)
        // $stmt = $db->prepare("INSERT INTO ventas ...");
        // $stmt->execute([...]);
        
        // NUEVO: Enviar notificación por WhatsApp al administrador
        $pedido_para_notificacion = [
            'id_pedido_comercio' => $id_pedido_comercio,
            'monto_total' => $monto_pagado,
            'forma_pago' => $forma_pago,
            'datos_comprador' => $pedido['datos_comprador'],
            'datos_productos' => $pedido['datos_productos']
        ];
        
        $resultado_whatsapp = notificarPedidoAdmin($pedido_para_notificacion);
        
    }
    
    // Responder a Pagopar con éxito
    http_response_code(200);
    
    // Respuesta JSON en el formato EXACTO que PagoPar espera según su documentación
    header('Content-Type: application/json; charset=utf-8');
    
    // Detectar si es una validación de PagoPar (sin datos reales de pedido)
    $es_validacion = !$pedido || empty($pedido) || $es_simulacion;
    
    // Construir respuesta en el formato requerido por PagoPar
    $pagopar_response = [
        [
            "pagado" => $es_validacion ? true : ($estado === 'pagado' || $estado === 'confirmado'),
            "numero_comprobante_interno" => strval($pedido['id'] ?? rand(1000000, 9999999)),
            "ultimo_mensaje_error" => null,
            "forma_pago" => $forma_pago ?? "Tarjetas de crédito/débito",
            "fecha_pago" => $fecha_pago,
            "monto" => strval(floatval($monto_pagado)),
            "fecha_maxima_pago" => $pedido['fecha_maxima_pago'] ?? date('Y-m-d H:i:s', strtotime('+7 days')),
            "hash_pedido" => $hash_pagopar ?? "hash_" . md5(time()),
            "numero_pedido" => strval($id_pedido_comercio ?? "VALIDACION-001"),
            "cancelado" => false, // Nunca cancelado en validaciones
            "forma_pago_identificador" => "1", // ID para tarjetas según ejemplo de documentación
            "token" => $hash_pagopar ?? "token_" . md5(time())
        ]
    ];
    
    echo json_encode($pagopar_response);
    
} catch (Exception $e) {
    // Log del error para debugging
    error_log("Webhook PagoPar Error: " . $e->getMessage() . " - Datos: " . json_encode($data));
    
    http_response_code(500);
    $error_response = [
        'error' => 'Error al procesar la notificación: ' . $e->getMessage(),
        'received_data' => $data, // Incluir datos recibidos para debugging
        'timestamp' => date('Y-m-d H:i:s')
    ];
    
    echo json_encode($error_response);
}
