<?php
/**
 * Script para extrair imagens Base64 de arquivos HTML
 * Salva em pasta dedicada e substitui referências no HTML
 * 
 * USO: php extrair_base64.php [arquivo.html] [--all]
 * 
 * Exemplos:
 *   php extrair_base64.php index.html
 *   php extrair_base64.php --all   (processa todos os .html)
 */

// Configurações
$PASTA_IMAGENS = 'assets/images';
$PREFIXO_ARQUIVO = 'img';

// Cores para terminal
function cor($texto, $cor) {
    $cores = [
        'verde' => "\033[32m",
        'vermelho' => "\033[31m",
        'amarelo' => "\033[33m",
        'azul' => "\033[34m",
        'reset' => "\033[0m"
    ];
    return ($cores[$cor] ?? '') . $texto . $cores['reset'];
}

function log_info($msg) { echo cor("[INFO] ", 'azul') . $msg . "\n"; }
function log_ok($msg) { echo cor("[OK] ", 'verde') . $msg . "\n"; }
function log_erro($msg) { echo cor("[ERRO] ", 'vermelho') . $msg . "\n"; }
function log_aviso($msg) { echo cor("[AVISO] ", 'amarelo') . $msg . "\n"; }

/**
 * Extrai a extensão do tipo MIME
 */
function getMimeExtensao($mimeType) {
    $extensoes = [
        'image/png' => 'png',
        'image/jpeg' => 'jpg',
        'image/jpg' => 'jpg',
        'image/gif' => 'gif',
        'image/webp' => 'webp',
        'image/svg+xml' => 'svg',
        'image/x-icon' => 'ico',
        'image/bmp' => 'bmp',
        'image/tiff' => 'tiff'
    ];
    return $extensoes[$mimeType] ?? 'bin';
}

/**
 * Gera nome único para o arquivo de imagem
 */
function gerarNomeArquivo($arquivoOrigem, $indice, $extensao, $contexto = '') {
    global $PREFIXO_ARQUIVO;
    
    // Remove extensão do arquivo de origem
    $nomeBase = pathinfo($arquivoOrigem, PATHINFO_FILENAME);
    
    // Limpa o contexto (classe, id, alt, etc)
    $contexto = preg_replace('/[^a-zA-Z0-9_-]/', '', $contexto);
    $contexto = substr($contexto, 0, 30); // Limita tamanho
    
    if (!empty($contexto)) {
        return "{$PREFIXO_ARQUIVO}_{$nomeBase}_{$contexto}_{$indice}.{$extensao}";
    }
    
    return "{$PREFIXO_ARQUIVO}_{$nomeBase}_{$indice}.{$extensao}";
}

/**
 * Tenta extrair contexto da tag (class, id, alt, aria-label)
 */
function extrairContexto($tagCompleta) {
    // Tenta pegar alt
    if (preg_match('/alt=["\']([^"\']+)["\']/', $tagCompleta, $m)) {
        return $m[1];
    }
    // Tenta pegar aria-label
    if (preg_match('/aria-label=["\']([^"\']+)["\']/', $tagCompleta, $m)) {
        return $m[1];
    }
    // Tenta pegar class
    if (preg_match('/class=["\']([^"\']+)["\']/', $tagCompleta, $m)) {
        $classes = explode(' ', $m[1]);
        return $classes[0] ?? '';
    }
    // Tenta pegar id
    if (preg_match('/id=["\']([^"\']+)["\']/', $tagCompleta, $m)) {
        return $m[1];
    }
    return '';
}

/**
 * Processa um arquivo HTML
 */
function processarArquivo($arquivo, $pastaImagens) {
    if (!file_exists($arquivo)) {
        log_erro("Arquivo não encontrado: $arquivo");
        return false;
    }
    
    log_info("Processando: $arquivo");
    
    $conteudo = file_get_contents($arquivo);
    $conteudoOriginal = $conteudo;
    
    // Regex para encontrar base64 em src, href, url()
    $patterns = [
        // src="data:image/..."
        '/(src=["\'])(data:image\/([^;]+);base64,([^"\']+))(["\'])/i',
        // href="data:image/..."
        '/(href=["\'])(data:image\/([^;]+);base64,([^"\']+))(["\'])/i',
        // url(data:image/...)
        '/(url\(["\']?)(data:image\/([^;]+);base64,([^"\')\s]+))(["\']?\))/i',
    ];
    
    $imagensExtraidas = [];
    $indice = 1;
    $nomeArquivo = basename($arquivo);
    
    // Criar pasta de imagens se não existir
    $pastaDestino = dirname($arquivo) . '/' . $pastaImagens;
    if (!is_dir($pastaDestino)) {
        mkdir($pastaDestino, 0755, true);
        log_ok("Pasta criada: $pastaDestino");
    }
    
    foreach ($patterns as $pattern) {
        // Encontra todas as ocorrências
        preg_match_all($pattern, $conteudo, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
        
        foreach ($matches as $match) {
            $prefixo = $match[1][0];      // src=" ou url(" etc
            $dataUri = $match[2][0];      // data:image/png;base64,...
            $mimeType = $match[3][0];     // png, jpeg, etc
            $base64Data = $match[4][0];   // dados base64
            $sufixo = $match[5][0];       // " ou ) etc
            $posicao = $match[0][1];      // posição no texto
            
            // Pega um trecho maior para contexto
            $inicio = max(0, $posicao - 200);
            $trecho = substr($conteudoOriginal, $inicio, 500);
            $contexto = extrairContexto($trecho);
            
            // Determina extensão
            $extensao = getMimeExtensao("image/$mimeType");
            
            // Gera nome do arquivo
            $nomeImagem = gerarNomeArquivo($nomeArquivo, $indice, $extensao, $contexto);
            $caminhoImagem = $pastaDestino . '/' . $nomeImagem;
            
            // Verifica se já não foi processado (mesmo base64)
            $hash = md5($base64Data);
            if (isset($imagensExtraidas[$hash])) {
                // Já extraiu essa imagem, só substitui a referência
                $caminhoRelativo = $pastaImagens . '/' . $imagensExtraidas[$hash];
                $conteudo = str_replace($dataUri, $caminhoRelativo, $conteudo);
                log_aviso("  Imagem duplicada, reutilizando: {$imagensExtraidas[$hash]}");
                continue;
            }
            
            // Decodifica e salva
            $dadosImagem = base64_decode($base64Data);
            if ($dadosImagem === false) {
                log_erro("  Falha ao decodificar base64 #$indice");
                continue;
            }
            
            // Salva arquivo
            if (file_put_contents($caminhoImagem, $dadosImagem)) {
                $tamanho = strlen($dadosImagem);
                $tamanhoKB = round($tamanho / 1024, 2);
                log_ok("  Extraído: $nomeImagem ($tamanhoKB KB)");
                
                // Substitui no HTML
                $caminhoRelativo = $pastaImagens . '/' . $nomeImagem;
                $conteudo = str_replace($dataUri, $caminhoRelativo, $conteudo);
                
                // Guarda hash para evitar duplicatas
                $imagensExtraidas[$hash] = $nomeImagem;
                $indice++;
            } else {
                log_erro("  Falha ao salvar: $caminhoImagem");
            }
        }
    }
    
    // Salva HTML modificado
    if ($conteudo !== $conteudoOriginal) {
        // Backup do original
        $backup = $arquivo . '.backup_' . date('Ymd_His');
        copy($arquivo, $backup);
        log_info("  Backup criado: " . basename($backup));
        
        // Salva modificado
        file_put_contents($arquivo, $conteudo);
        log_ok("  HTML atualizado com " . (count($imagensExtraidas)) . " imagens extraídas");
        
        return count($imagensExtraidas);
    } else {
        log_aviso("  Nenhuma imagem base64 encontrada");
        return 0;
    }
}

/**
 * Gera arquivo de mapeamento JSON
 */
function gerarMapeamento($arquivo, $pastaImagens) {
    $pasta = dirname($arquivo) . '/' . $pastaImagens;
    if (!is_dir($pasta)) return;
    
    $imagens = glob($pasta . '/*.*');
    $mapeamento = [];
    
    foreach ($imagens as $img) {
        $nome = basename($img);
        // Extrai info do nome: img_origem_contexto_numero.ext
        if (preg_match('/^img_([^_]+)_(.+)_(\d+)\.(\w+)$/', $nome, $m)) {
            $mapeamento[] = [
                'arquivo' => $nome,
                'origem' => $m[1] . '.html',
                'contexto' => $m[2],
                'indice' => (int)$m[3],
                'extensao' => $m[4],
                'caminho' => $pastaImagens . '/' . $nome
            ];
        }
    }
    
    $jsonFile = $pasta . '/mapeamento.json';
    file_put_contents($jsonFile, json_encode($mapeamento, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
    log_ok("Mapeamento salvo: $jsonFile");
}

// ==================== EXECUÇÃO ====================

echo "\n";
echo cor("╔════════════════════════════════════════════╗\n", 'azul');
echo cor("║  EXTRATOR DE IMAGENS BASE64 DE HTML        ║\n", 'azul');
echo cor("╚════════════════════════════════════════════╝\n", 'azul');
echo "\n";

// Processa argumentos
$args = array_slice($argv, 1);

if (empty($args)) {
    echo "USO:\n";
    echo "  php extrair_base64.php arquivo.html     - Processa um arquivo\n";
    echo "  php extrair_base64.php --all            - Processa todos os .html\n";
    echo "  php extrair_base64.php --pasta=imgs     - Define pasta de destino\n";
    echo "\n";
    exit(0);
}

// Verifica argumentos
$processarTodos = in_array('--all', $args);
$arquivos = [];

// Verifica se tem pasta customizada
foreach ($args as $arg) {
    if (strpos($arg, '--pasta=') === 0) {
        $PASTA_IMAGENS = substr($arg, 8);
    }
}

if ($processarTodos) {
    // Encontra todos os .html no diretório atual
    $arquivos = glob('*.html');
    if (empty($arquivos)) {
        log_erro("Nenhum arquivo .html encontrado no diretório atual");
        exit(1);
    }
} else {
    // Pega arquivos específicos
    foreach ($args as $arg) {
        if (strpos($arg, '--') !== 0 && file_exists($arg)) {
            $arquivos[] = $arg;
        }
    }
}

if (empty($arquivos)) {
    log_erro("Nenhum arquivo válido para processar");
    exit(1);
}

log_info("Pasta de destino: $PASTA_IMAGENS");
echo "\n";

$totalExtraidas = 0;

foreach ($arquivos as $arquivo) {
    $extraidas = processarArquivo($arquivo, $PASTA_IMAGENS);
    if ($extraidas !== false) {
        $totalExtraidas += $extraidas;
    }
    echo "\n";
}

// Gera mapeamento
if ($totalExtraidas > 0) {
    gerarMapeamento($arquivos[0], $PASTA_IMAGENS);
}

echo cor("═══════════════════════════════════════════\n", 'azul');
echo cor("RESUMO: ", 'verde') . "$totalExtraidas imagens extraídas de " . count($arquivos) . " arquivo(s)\n";
echo cor("═══════════════════════════════════════════\n", 'azul');
echo "\n";
