<?php
// Configuração do banco de dados
$host = 'localhost';
$db = 'digupdog_FEED';
$user = 'digupdog_FEEDadmin';
$pass = 'Raimundinho1';
$charset = 'utf8mb4';
$batchSize = 1000; // Número de registros por lote para processar
$progressFile = 'progress.txt'; // Arquivo para registrar o progresso
$maxExecutionTime = 60; // Tempo máximo em segundos antes de reiniciar (1 minutos)

// Exibir erros para depuração
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Permitir tempo de execução ilimitado e aumentar a memória para 3 GB
set_time_limit(0);
ini_set('memory_limit', '3G');

// Função para verificar se o tempo de execução máximo foi atingido e reiniciar o script
$startTime = time();
function shouldRestart($startTime, $maxExecutionTime) {
    return (time() - $startTime) > $maxExecutionTime;
}

try {
    // Conectar ao banco de dados usando PDO
    $conn = new PDO("mysql:host=$host;dbname=$db;charset=$charset", $user, $pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Obter o total de registros na tabela pinfeeds
    $totalStmt = $conn->query("SELECT COUNT(*) FROM pinfeeds");
    $totalRecords = $totalStmt->fetchColumn();

    echo "Total de registros a processar: $totalRecords\n";

    // Ler o progresso anterior do arquivo, se existir
    $offset = file_exists($progressFile) ? (int)file_get_contents($progressFile) : 0;
    $processedRecords = $offset;

    // Loop de controle por lotes
    for (; $offset < $totalRecords; $offset += $batchSize) {
        // Reinicia o script automaticamente se o tempo limite foi atingido
        if (shouldRestart($startTime, $maxExecutionTime)) {
            file_put_contents($progressFile, $offset);
            echo "Reiniciando o script para evitar timeout...\n";
            echo "<script>window.location.reload();</script>";
            exit;
        }

        // Buscar um lote de registros
        $stmt = $conn->prepare("SELECT id, title, description FROM pinfeeds LIMIT :offset, :batchSize");
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->bindValue(':batchSize', $batchSize, PDO::PARAM_INT);
        $stmt->execute();
        $feeds = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // Processar cada registro do lote
        foreach ($feeds as $feed) {
            insertIntoIndex($conn, $feed['id'], $feed['title'], $feed['description']);
            $processedRecords++;
        }

        // Salvar o progresso no arquivo
        file_put_contents($progressFile, $offset + $batchSize);

        // Mostrar progresso atual
        echo sprintf(
            "Lote processado: %d de %d | Total processado: %d\n",
            min($offset + $batchSize, $totalRecords),
            $totalRecords,
            $processedRecords
        );
    }

    // Remover o arquivo de progresso ao concluir o processamento
    if (file_exists($progressFile)) {
        unlink($progressFile);
    }

    echo "Processamento concluído.\n";

} catch (PDOException $e) {
    echo 'Erro na conexão com o banco de dados: ' . $e->getMessage();
}

// Função para sanitizar palavras e garantir compatibilidade UTF-8
function sanitizeWord($word) {
    // Remove caracteres não imprimíveis e mantém apenas letras, números e espaços
    $word = mb_convert_encoding($word, 'UTF-8', 'UTF-8');
    $word = preg_replace('/[^\p{L}\p{N}\s]/u', '', $word);
    return trim($word);
}

// Função para inserir palavras no índice
function insertIntoIndex($conn, $feedId, $title, $description) {
    $insertQuery = "INSERT INTO title_description_index (feed_id, word, occurrence_count) 
                    VALUES (:feed_id, :word, 1) 
                    ON DUPLICATE KEY UPDATE occurrence_count = occurrence_count + 1";
    $insertStmt = $conn->prepare($insertQuery);

    // Processa título e descrição, separando por palavras e sanitizando cada uma
    $words = array_unique(array_merge(
        explode(' ', strtolower($title)),
        explode(' ', strtolower($description))
    ));

    foreach ($words as $word) {
        $word = sanitizeWord($word);
        if (!empty($word)) {
            $word = substr($word, 0, 255); // Limitar palavra a 255 caracteres
            try {
                $insertStmt->execute([':feed_id' => $feedId, ':word' => $word]);
            } catch (PDOException $e) {
                echo 'Erro ao inserir palavra no índice: ' . $e->getMessage();
            }
        }
    }
}
