<?php

// LOG DE DEBUG - SEMPRE REGISTRA QUANDO CHAMADO
error_log('=== WEBHOOK CHAMADO ===');
error_log('Method: ' . $_SERVER['REQUEST_METHOD']);
error_log('Content-Type: ' . ($_SERVER['CONTENT_TYPE'] ?? 'none'));
error_log('Payload size: ' . strlen(file_get_contents('php://input')) . ' bytes');

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../helpers/response.php';

// ============================================
// RECEBE EVENTOS DO SENDGRID
// ============================================

// Pega payload do SendGrid
$payload = file_get_contents('php://input');

if (!$payload) {
    http_response_code(400);
    exit('No payload received');
}

// SendGrid manda array de eventos
$events = json_decode($payload, true);

if (!is_array($events)) {
    http_response_code(400);
    exit('Invalid payload format');
}

$db = Database::getConnection();

// Processa cada evento
foreach ($events as $event) {
    
    // Valida evento
    if (!isset($event['event']) || !isset($event['sg_message_id'])) {
        error_log('Webhook: Missing required fields in event');
        continue;
    }
    
    $eventType = $event['event'];
    $messageId = $event['sg_message_id'];
    $email = $event['email'] ?? null;
    $timestamp = $event['timestamp'] ?? time();
    $datetime = date('Y-m-d H:i:s', $timestamp);
    
    // Pega custom args (receivable_id, document_number)
    $receivableId = $event['receivable_id'] ?? null;
    $documentNumber = $event['document_number'] ?? null;
    
    // Log do evento
    error_log("Webhook: Event '{$eventType}' for message '{$messageId}'");
    
    // Busca email_send pelo sendgrid_message_id (usando LIKE pois SendGrid adiciona sufixo)
    $messageIdPattern = explode('.', $messageId)[0] . '%'; // Pega só a parte antes do ponto

    $stmt = $db->prepare(
        'SELECT id FROM email_sends 
         WHERE sendgrid_message_id LIKE ? 
         LIMIT 1'
    );
    $stmt->bind_param('s', $messageIdPattern);
    $stmt->execute();
    $result = $stmt->get_result();
    
    // Se não encontrou por message_id, tenta por receivable_id (do custom args)
    if ($result->num_rows === 0 && $receivableId) {
        $stmt = $db->prepare(
            'SELECT es.id 
             FROM email_sends es
             WHERE es.receivable_id = ?
             ORDER BY es.id DESC
             LIMIT 1'
        );
        $stmt->bind_param('i', $receivableId);
        $stmt->execute();
        $result = $stmt->get_result();
    }
    
    if ($result->num_rows === 0) {
        error_log("Webhook: email_send not found for message_id '{$messageId}'");
        continue;
    }
    
    $emailSendId = $result->fetch_assoc()['id'];
    
    // ============================================
    // REGISTRA EVENTO NO HISTÓRICO
    // ============================================
    
    $userAgent = $event['useragent'] ?? null;
    $ipAddress = $event['ip'] ?? null;
    $url = $event['url'] ?? null;
    $sgEventId = $event['sg_event_id'] ?? null;
    
    $stmt = $db->prepare(
        'INSERT INTO email_events 
         (email_send_id, event_type, event_timestamp, user_agent, ip_address, url, sendgrid_event_id, created_at)
         VALUES (?, ?, ?, ?, ?, ?, ?, NOW())'
    );
    $stmt->bind_param('issssss', 
        $emailSendId, 
        $eventType, 
        $datetime, 
        $userAgent, 
        $ipAddress, 
        $url,
        $sgEventId
    );
    $stmt->execute();
    
    // ============================================
    // ATUALIZA BANCO CONFORME O EVENTO
    // ============================================
    
    switch ($eventType) {
        
        case 'delivered':
            // Só atualiza status se ainda for 'sent'
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET status = IF(status = "sent", "delivered", status),
                     delivered_at = ?
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $datetime, $emailSendId);
            $stmt->execute();
            break;
        
        case 'open':
            // Atualiza status se for 'sent' ou 'delivered'
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET opened_at = COALESCE(opened_at, ?),
                     open_count = open_count + 1,
                     status = IF(status IN ("sent", "delivered"), "opened", status)
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $datetime, $emailSendId);
            $stmt->execute();
            break;
        
        case 'click':
            // Atualiza status se for 'sent', 'delivered' ou 'opened'
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET clicked_at = COALESCE(clicked_at, ?),
                     click_count = click_count + 1,
                     status = IF(status IN ("sent", "delivered", "opened"), "clicked", status)
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $datetime, $emailSendId);
            $stmt->execute();
            break;
        
        case 'bounce':
        case 'dropped':
            $reason = $event['reason'] ?? 'Unknown';
            
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET status = "failed", 
                     bounced_at = ?,
                     bounce_reason = ?
                 WHERE id = ?'
            );
            $stmt->bind_param('ssi', $datetime, $reason, $emailSendId);
            $stmt->execute();
            break;
        
        case 'spamreport':
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET spam_reported_at = ?,
                     status = "spam"
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $datetime, $emailSendId);
            $stmt->execute();
            break;
        
        case 'unsubscribe':
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET unsubscribed_at = ?,
                     status = "unsubscribed"
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $datetime, $emailSendId);
            $stmt->execute();
            break;
        
        default:
            error_log("Webhook: Unknown event type '{$eventType}'");
    }
}

// Responde pro SendGrid que recebeu OK
http_response_code(200);
echo json_encode(['success' => true, 'processed' => count($events)]);