<?php

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

// ============================================
// WORKER DE PROCESSAMENTO
// ============================================

$db = Database::getConnection();

// Busca configurações do banco
$stmt = $db->prepare('SELECT setting_key, setting_value FROM system_settings WHERE setting_key IN ("batch_process_delay_ms", "batch_timeout_seconds")');
$stmt->execute();
$settings = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);

$processDelay = 500000; // padrão 0.5s
$timeoutSeconds = 300; // padrão 5min

foreach ($settings as $setting) {
    if ($setting['setting_key'] === 'batch_process_delay_ms') {
        $processDelay = (int)$setting['setting_value'] * 1000;
    }
    if ($setting['setting_key'] === 'batch_timeout_seconds') {
        $timeoutSeconds = (int)$setting['setting_value'];
    }
}

set_time_limit($timeoutSeconds);

// Busca jobs pendentes
$stmt = $db->prepare(
    'SELECT id, job_uuid, company_id 
     FROM batch_jobs 
     WHERE status = "pending" 
     ORDER BY created_at ASC 
     LIMIT 1'
);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows === 0) {
    exit('No pending jobs');
}

$job = $result->fetch_assoc();
$jobId = $job['id'];
$jobUuid = $job['job_uuid'];
$companyId = $job['company_id'];

// ============================================
// MARCA COMO PROCESSANDO
// ============================================

$stmt = $db->prepare(
    'UPDATE batch_jobs 
     SET status = "processing", started_at = NOW() 
     WHERE id = ?'
);
$stmt->bind_param('i', $jobId);
$stmt->execute();

// ============================================
// BUSCA ITENS PENDENTES
// ============================================

$stmt = $db->prepare(
    'SELECT id, payload 
     FROM batch_items 
     WHERE batch_job_id = ? AND status = "pending"'
);
$stmt->bind_param('i', $jobId);
$stmt->execute();
$items = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);

// ============================================
// AGRUPA ITENS POR PEDIDO
// ============================================

$groups = [];

foreach ($items as $item) {
    $payload = json_decode($item['payload'], true);
    
    $groupedEmail = $payload['grouped_email'] ?? null;
    $groupedOrder = $payload['grouped_order'] ?? null;
    
    if (!$groupedEmail || !$groupedOrder) {
        // Item sem agrupamento, processa individual (fallback)
        $groupKey = 'individual_' . $item['id'];
    } else {
        $groupKey = $groupedEmail . '|' . $groupedOrder;
    }
    
    if (!isset($groups[$groupKey])) {
        $groups[$groupKey] = [];
    }
    
    $groups[$groupKey][] = $item;
}

// ============================================
// PROCESSA CADA GRUPO
// ============================================

$successCount = 0;
$errorCount = 0;

foreach ($groups as $groupKey => $groupItems) {
    
    try {
        
        // Processa grupo de itens (pedido completo)
        $result = processOrderGroup($groupItems, $companyId, $db);
        
        if ($result['success']) {
            
            // Sucesso! Marca todos os itens do grupo
            foreach ($groupItems as $item) {
                $itemId = $item['id'];
                
                $stmt = $db->prepare(
                    'UPDATE batch_items 
                     SET status = "success", 
                         processed_at = NOW()
                     WHERE id = ?'
                );
                $stmt->bind_param('i', $itemId);
                $stmt->execute();
                
                $successCount++;
            }
            
        } else {
            throw new Exception($result['error']);
        }
        
    } catch (Exception $e) {
        
        // Erro! Marca todos os itens do grupo como erro
        $errorMessage = $e->getMessage();
        
        foreach ($groupItems as $item) {
            $itemId = $item['id'];
            
            $stmt = $db->prepare(
                'UPDATE batch_items 
                 SET status = "error", 
                     error_message = ?,
                     processed_at = NOW()
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $errorMessage, $itemId);
            $stmt->execute();
            
            $errorCount++;
        }
    }
    
    // Atualiza contador do job
    $stmt = $db->prepare(
        'UPDATE batch_jobs 
         SET processed_items = processed_items + ?,
             success_count = ?,
             error_count = ?
         WHERE id = ?'
    );
    $groupSize = count($groupItems);
    $stmt->bind_param('iiii', $groupSize, $successCount, $errorCount, $jobId);
    $stmt->execute();
    
    // Delay entre grupos
    usleep($processDelay);
}

// ============================================
// CHAMA WEBHOOK INTERNO
// ============================================

$ch = curl_init(BASE_URL . '/api/batch/webhook.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['job_id' => $jobUuid]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$webhookResponse = curl_exec($ch);
$webhookError = curl_error($ch);
curl_close($ch);

error_log("Webhook called for job {$jobUuid}");
error_log("Webhook response: {$webhookResponse}");
if ($webhookError) {
    error_log("Webhook error: {$webhookError}");
}

// ============================================
// ENVIA EMAIL SE HOUVER ERROS
// ============================================

if ($errorCount > 0) {
    
    // Busca os erros
    $stmt = $db->prepare(
        'SELECT document_number, error_message 
         FROM batch_items 
         WHERE batch_job_id = ? AND status = "error"'
    );
    $stmt->bind_param('i', $jobId);
    $stmt->execute();
    $errors = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    
    // Monta HTML bonito
    $errorRows = "";
    foreach ($errors as $error) {
        $errorRows .= "<tr>
            <td style='padding: 10px; border: 1px solid #ddd;'>{$error['document_number']}</td>
            <td style='padding: 10px; border: 1px solid #ddd; color: #d9534f;'>{$error['error_message']}</td>
        </tr>";
    }
    
    $htmlContent = "
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='UTF-8'>
        <style>
            body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
            .container { max-width: 600px; margin: 0 auto; padding: 20px; }
            .header { background: #d9534f; color: white; padding: 20px; text-align: center; }
            .content { padding: 20px; background: #f9f9f9; }
            .summary { background: white; padding: 15px; margin: 15px 0; border-left: 4px solid #d9534f; }
            table { width: 100%; border-collapse: collapse; margin: 20px 0; background: white; }
            th { background: #d9534f; color: white; padding: 10px; text-align: left; }
            .footer { text-align: center; padding: 20px; color: #666; font-size: 12px; }
        </style>
    </head>
    <body>
        <div class='container'>
            <div class='header'>
                <h1>⚠️ Erro no Processamento de Lote</h1>
            </div>
            <div class='content'>
                <div class='summary'>
                    <p><strong>Job UUID:</strong> {$jobUuid}</p>
                    <p><strong>Data/Hora:</strong> " . date('d/m/Y H:i:s') . "</p>
                    <p><strong>Total de itens:</strong> " . count($items) . "</p>
                    <p style='color: #5cb85c;'><strong>✅ Sucessos:</strong> {$successCount}</p>
                    <p style='color: #d9534f;'><strong>❌ Erros:</strong> {$errorCount}</p>
                </div>
                
                <h3>Detalhes dos Erros:</h3>
                <table>
                    <thead>
                        <tr>
                            <th>Documento</th>
                            <th>Erro</th>
                        </tr>
                    </thead>
                    <tbody>
                        {$errorRows}
                    </tbody>
                </table>
            </div>
            <div class='footer'>
                <p>Email automático do sistema de processamento em lote</p>
                <p>MailSender Centre - NewEra Solutions</p>
            </div>
        </div>
    </body>
    </html>
    ";
    
    // Envia via SendGrid
    require_once __DIR__ . '/../vendor/autoload.php';
    
    $email = new \SendGrid\Mail\Mail();
    $email->setFrom("noreply@mailsendercentre.newerasolutions.com.br", "MailSender Centre");
    $email->setSubject("[BATCH ERROR] Job com {$errorCount} erro(s) - " . date('d/m/Y H:i'));
    $email->addTo("leandro.santiago.rosa@gmail.com", "Leandro Santiago");
    $email->addContent("text/html", $htmlContent);
    
    $sendgrid = new \SendGrid(SENDGRID_API_KEY);
    
    try {
        $response = $sendgrid->send($email);
        error_log("Error notification sent via SendGrid for job {$jobUuid} - Status: " . $response->statusCode());
    } catch (Exception $e) {
        error_log("Failed to send error notification: " . $e->getMessage());
    }
}

echo "Job {$jobUuid} processed: {$successCount} success, {$errorCount} errors\n";


// ============================================
// FUNÇÃO: PROCESSA GRUPO DE PEDIDO
// ============================================

function processOrderGroup($groupItems, $companyId, $db) {
    
    // Pega primeiro item pra extrair dados do cliente
    $firstPayload = json_decode($groupItems[0]['payload'], true);
    $customerData = $firstPayload['customer'];
    
    // Busca API Key da empresa
    $apiKey = getCompanyApiKey($companyId, $db);
    
    if (!$apiKey) {
        return [
            'success' => false,
            'error' => 'Company API key not found'
        ];
    }
    
    // Array de receivables criados
    $receivableIds = [];
    $receivablesData = [];
    
    // Cria cada receivable individualmente
    foreach ($groupItems as $item) {
        $payload = json_decode($item['payload'], true);
        
        // Chama send.php pra criar receivable
        $result = createReceivable($payload, $apiKey);
        
        if (!$result['success']) {
            return $result; // Falhou, retorna erro
        }
        
        $receivableIds[] = $result['receivable_id'];
        $receivablesData[] = $result;
    }
    
    // Agora envia 1 EMAIL com todos os receivables
    $emailResult = sendGroupedEmail($receivablesData, $customerData, $companyId, $db);
    
    return $emailResult;
}


// ============================================
// FUNÇÃO: CRIA RECEIVABLE INDIVIDUAL
// ============================================

function createReceivable($payload, $apiKey) {
    
    // ADICIONA FLAG PRA NÃO ENVIAR EMAIL
    $payload['skip_email'] = true;
    
    error_log("=== CREATE RECEIVABLE DEBUG ===");
    error_log("Document: " . ($payload['receivable']['document_number'] ?? 'N/A'));
    error_log("Skip Email: true");
    
    $ch = curl_init(BASE_URL . '/api/receivables/send.php');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $apiKey
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    error_log("HTTP Code: {$httpCode}");
    error_log("Response: {$response}");
    error_log("cURL Error: {$curlError}");
    error_log("===============================");
    
    if ($httpCode === 201) {
        $result = json_decode($response, true);
        return [
            'success' => true,
            'receivable_id' => $result['receivable_id'],
            'customer_id' => $result['customer_id'],
            'access_url' => $result['access_url'],
            'token' => $result['token']
        ];
    } else {
        $error = json_decode($response, true);
        $errorMsg = $error['error'] ?? 'Unknown error';
        
        // Se tem mensagem detalhada, usa ela
        if (isset($error['message'])) {
            $errorMsg .= ': ' . $error['message'];
        }
        
        return [
            'success' => false,
            'error' => "HTTP {$httpCode}: {$errorMsg}"
        ];
    }
}


// ============================================
// FUNÇÃO: ENVIA EMAIL AGRUPADO
// ============================================

function sendGroupedEmail($receivablesData, $customerData, $companyId, $db) {
    
    require_once __DIR__ . '/../vendor/autoload.php';
    
    // ============================================
    // BUSCA CONFIGURAÇÕES DE EMAIL DA EMPRESA
    // ============================================
    
    $stmt = $db->prepare(
        'SELECT primary_color, primary_text_color, button_color, button_text_color, sender_name, email_footer
         FROM company_email_settings 
         WHERE company_id = ?'
    );
    $stmt->bind_param('i', $companyId);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows > 0) {
        $emailSettings = $result->fetch_assoc();
    } else {
        // Fallback para cores padrão se não tiver configuração
        $emailSettings = [
            'primary_color' => '#0066cc',
            'primary_text_color' => '#ffffff',
            'button_color' => '#0066cc',
            'button_text_color' => '#ffffff',
            'sender_name' => 'MailSender Centre',
            'email_footer' => null
        ];
    }
    
    // ============================================
    // PREPARA DADOS
    // ============================================
    
    $customerName = $customerData['name'];
    $customerEmail = $customerData['email'];
    $customerId = $receivablesData[0]['customer_id'];
    
    // Pega primeiro token pra usar como link único
    $mainToken = $receivablesData[0]['token'];
	$accessUrl = BASE_URL . '/api/receivables/' . $mainToken;
    
    // Calcula total
    $totalAmount = 0;
    foreach ($receivablesData as $r) {
        // Busca amount do banco
        $stmt = $db->prepare('SELECT amount FROM receivables WHERE id = ?');
        $stmt->bind_param('i', $r['receivable_id']);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result->num_rows > 0) {
            $totalAmount += $result->fetch_assoc()['amount'];
        }
    }
    
    // ============================================
    // MONTA TABELA DE PARCELAS
    // ============================================
    
    $parcelasRows = "";
    
    foreach ($receivablesData as $index => $r) {
        
        // Busca dados completos do receivable
        $stmt = $db->prepare(
            'SELECT document_number, due_date, amount, invoice_number 
             FROM receivables 
             WHERE id = ?'
        );
        $stmt->bind_param('i', $r['receivable_id']);
        $stmt->execute();
        $receivable = $stmt->get_result()->fetch_assoc();
        
        $docNumber = $receivable['document_number'];
        $dueDate = date('d/m/Y', strtotime($receivable['due_date']));
        $amount = number_format($receivable['amount'], 2, ',', '.');
        $invoiceNumber = $receivable['invoice_number'] ?? '-';
        
        $parcelasRows .= "
        <tr>
            <td style='padding: 12px; border: 1px solid #ddd;'>{$docNumber}</td>
            <td style='padding: 12px; border: 1px solid #ddd; text-align: center;'>{$invoiceNumber}</td>
            <td style='padding: 12px; border: 1px solid #ddd; text-align: center;'>{$dueDate}</td>
            <td style='padding: 12px; border: 1px solid #ddd; text-align: right;'>R$ {$amount}</td>
        </tr>";
    }
    
    $totalFormatted = number_format($totalAmount, 2, ',', '.');
    
    // ============================================
    // CORES CUSTOMIZADAS
    // ============================================
    
    $primaryColor = $emailSettings['primary_color'];
    $primaryTextColor = $emailSettings['primary_text_color'];
    $buttonColor = $emailSettings['button_color'];
    $buttonTextColor = $emailSettings['button_text_color'];
    $senderName = $emailSettings['sender_name'];
    
    // Rodapé customizado ou padrão
    $footerContent = $emailSettings['email_footer'] ?? "
        <p>Este é um email automático, por favor não responda.</p>
        <p>Em caso de dúvidas, entre em contato com nosso suporte.</p>
    ";
    
    // ============================================
    // MONTA EMAIL HTML COM CORES CUSTOMIZADAS
    // ============================================
    
    $htmlContent = "
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='UTF-8'>
        <style>
			body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 0; }
			.container { max-width: 600px; margin: 0 auto; padding: 0; }
			.header { background: {$primaryColor}; color: {$primaryTextColor}; padding: 30px 20px; text-align: center; }
			.content { padding: 30px 20px; background: #ffffff; }
			.greeting { font-size: 18px; margin-bottom: 20px; }
			.summary { background: #f0f8ff; padding: 20px; margin: 20px 0; border-left: 4px solid {$primaryColor}; }
			table { width: 100%; border-collapse: collapse; margin: 20px 0; }
			th { background: {$primaryColor}; color: {$primaryTextColor}; padding: 12px; text-align: left; }
			.total-row { background: #f9f9f9; font-weight: bold; font-size: 16px; }
			.cta-button { 
				display: inline-block; 
				background: {$buttonColor}; 
				color: {$buttonTextColor} !important; 
				padding: 15px 40px; 
				text-decoration: none !important; 
				border-radius: 5px; 
				margin: 20px 0; 
				font-size: 16px; 
				font-weight: bold;
				transition: all 0.3s ease;
			}
			.cta-button:hover { 
				opacity: 0.9; 
				transform: translateY(-2px); 
				box-shadow: 0 4px 8px rgba(0,0,0,0.2);
			}
			.cta-button:active { 
				transform: translateY(0); 
				box-shadow: 0 2px 4px rgba(0,0,0,0.2);
			}
			.cta-button:visited { 
				color: {$buttonTextColor} !important; 
			}
			.footer { text-align: center; padding: 20px; color: #666; font-size: 12px; background: #f9f9f9; }
		</style>
    </head>
    <body>
        <div class='container'>
            <div class='header'>
                <h1>📋 Documentos Fiscais Disponíveis</h1>
            </div>
            <div class='content'>
                <p class='greeting'>Olá <strong>{$customerName}</strong>,</p>
                
                <p>Você possui <strong>" . count($receivablesData) . " documento(s)</strong> disponível(is) para consulta:</p>
                
                <table>
                    <thead>
                        <tr>
                            <th>Documento</th>
                            <th style='text-align: center;'>NF-e</th>
                            <th style='text-align: center;'>Vencimento</th>
                            <th style='text-align: right;'>Valor</th>
                        </tr>
                    </thead>
                    <tbody>
                        {$parcelasRows}
                        <tr class='total-row'>
                            <td colspan='3' style='padding: 12px; border: 1px solid #ddd; text-align: right;'>TOTAL:</td>
                            <td style='padding: 12px; border: 1px solid #ddd; text-align: right;'>R$ {$totalFormatted}</td>
                        </tr>
                    </tbody>
                </table>
                
                <div style='text-align: center;'>
                    <a href='{$accessUrl}' class='cta-button'>VER TODOS OS DOCUMENTOS</a>
                </div>
                
                <div class='summary'>
                    <p style='margin: 0; font-size: 14px;'>
                        💡 <strong>Dica:</strong> Clique no botão acima para visualizar todos os documentos, 
                        boletos e notas fiscais em um só lugar.
                    </p>
                </div>
            </div>
            <div class='footer'>
                {$footerContent}
            </div>
        </div>
    </body>
    </html>
    ";
    
    // ============================================
    // CRIA EMAIL_SEND AGRUPADO
    // ============================================
    
    $subject = "Documentos Fiscais Disponíveis - " . count($receivablesData) . " documento(s)";
    
    $stmt = $db->prepare(
        'INSERT INTO email_sends (customer_id, subject, sent_at, status, created_at)
         VALUES (?, ?, NOW(), "sent", NOW())'
    );
    $stmt->bind_param('is', $customerId, $subject);
    $stmt->execute();
    $emailSendId = $stmt->insert_id;
    
    // ============================================
    // RELACIONA COM TODOS OS RECEIVABLES
    // ============================================
    
    $stmt = $db->prepare(
        'INSERT INTO email_send_receivables (email_send_id, receivable_id)
         VALUES (?, ?)'
    );
    
    foreach ($receivablesData as $r) {
        $stmt->bind_param('ii', $emailSendId, $r['receivable_id']);
        $stmt->execute();
    }
	
	// ============================================
// ATUALIZA TOKENS DOS RECEIVABLES
// ============================================

// Para cada receivable desse email, atualiza os tokens órfãos
foreach ($receivablesData as $r) {
    $receivableId = $r['receivable_id'];
    
    // Busca tokens sem email_send_id desse receivable
    $stmt = $db->prepare(
        'SELECT at.id, at.token
         FROM access_tokens at
         INNER JOIN receivables rec ON rec.id = ?
         WHERE at.email_send_id IS NULL
         AND at.created_at >= rec.created_at
         ORDER BY at.created_at DESC
         LIMIT 1'
    );
    $stmt->bind_param('i', $receivableId);
    $stmt->execute();
    $tokenResult = $stmt->get_result();
    
    if ($tokenResult->num_rows > 0) {
        $tokenData = $tokenResult->fetch_assoc();
        $tokenId = $tokenData['id'];
        
        // Atualiza com o email_send_id agrupado
        $stmt = $db->prepare(
            'UPDATE access_tokens 
             SET email_send_id = ? 
             WHERE id = ?'
        );
        $stmt->bind_param('ii', $emailSendId, $tokenId);
        $stmt->execute();
        
        error_log("Updated token {$tokenData['token']} with email_send_id: {$emailSendId}");
    }
}
    
    // ============================================
    // ENVIA VIA SENDGRID
    // ============================================
    
    $email = new \SendGrid\Mail\Mail();
    $email->setFrom("noreply@mailsendercentre.newerasolutions.com.br", $senderName);
    $email->setSubject($subject);
    $email->addTo($customerEmail, $customerName);
    $email->addContent("text/html", $htmlContent);
    
    // Custom Args pro webhook
    $email->addCustomArg("email_send_id", (string)$emailSendId);
    $email->addCustomArg("customer_id", (string)$customerId);
    
    $sendgrid = new \SendGrid(SENDGRID_API_KEY);
    
    try {
        $response = $sendgrid->send($email);
        
        // Pega message_id do header
        $messageId = null;
        foreach ($response->headers() as $header) {
            if (strpos($header, 'X-Message-Id') !== false) {
                $messageId = trim(str_replace('X-Message-Id:', '', $header));
                break;
            }
        }
        
        if ($messageId) {
            $stmt = $db->prepare(
                'UPDATE email_sends 
                 SET sendgrid_message_id = ? 
                 WHERE id = ?'
            );
            $stmt->bind_param('si', $messageId, $emailSendId);
            $stmt->execute();
        }
        
        error_log("Grouped email sent! email_send_id: {$emailSendId}, receivables: " . count($receivablesData));
        
        return [
            'success' => true,
            'email_send_id' => $emailSendId
        ];
        
    } catch (Exception $e) {
        error_log("Failed to send grouped email: " . $e->getMessage());
        
        $stmt = $db->prepare(
            'UPDATE email_sends 
             SET status = "failed" 
             WHERE id = ?'
        );
        $stmt->bind_param('i', $emailSendId);
        $stmt->execute();
        
        return [
            'success' => false,
            'error' => 'Failed to send email: ' . $e->getMessage()
        ];
    }
}


// ============================================
// FUNÇÃO: BUSCA API KEY
// ============================================

function getCompanyApiKey($companyId, $db) {
    $stmt = $db->prepare('SELECT api_key FROM api_companies WHERE id = ?');
    $stmt->bind_param('i', $companyId);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows === 0) {
        return null;
    }
    
    return $result->fetch_assoc()['api_key'];
}