<?php
/**
 * exe_depoimento.php - Processamento seguro de depoimentos enviados por clientes.
 * 
 * Funcionalidades:
 * - Proteção CSRF.
 * - Limite de envios por IP (Rate Limiting).
 * - Sanitização de inputs.
 * - Upload de imagem com validação de tipo MIME real.
 * - Suporte à coluna 'avaliacao' (opcional).
 */

session_start();
date_default_timezone_set('America/Sao_Paulo');

// helpers
function redirect($url) {
    header("Location: $url");
    exit;
}

function erro($msg) {
    $redirect = !empty($_POST['redirect_to']) ? $_POST['redirect_to'] : 'depoimento.php';
    $sep = (strpos($redirect, '?') === false) ? '?' : '&';
    redirect($redirect . $sep . 'erro=' . urlencode($msg));
}

// Verifica método
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    redirect('depoimento.php');
}

// CSRF check
if (empty($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf_token'])) {
    erro('Sessão expirada ou acesso inválido. Tente novamente.');
}
unset($_SESSION['csrf_token']);

// Login check
if (!isset($_SESSION['usuario_id'])) {
    erro('Você precisa estar logado para deixar um depoimento.');
}

// Rate Limit (3 por hora)
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
$limitKey = 'rate_dep_' . md5($ip);
if (!isset($_SESSION[$limitKey])) $_SESSION[$limitKey] = [];
$_SESSION[$limitKey] = array_filter($_SESSION[$limitKey], fn($t) => (time() - $t) < 3600);

if (count($_SESSION[$limitKey]) >= 3) {
    erro('Limite de envios atingido. Tente novamente em uma hora.');
}
$_SESSION[$limitKey][] = time();

// DB connection
require_once __DIR__ . '/../adm/config/db.php';
require_once __DIR__ . '/../adm/config/image_helper.php';

// Sanitização
$nome      = trim(filter_input(INPUT_POST, 'nome', FILTER_SANITIZE_SPECIAL_CHARS));
$texto     = trim(filter_input(INPUT_POST, 'texto', FILTER_SANITIZE_SPECIAL_CHARS));
$avaliacao = intval($_POST['avaliacao'] ?? 0);

if (empty($nome) || mb_strlen($nome) < 2) erro('Por favor, informe seu nome completo.');
if (empty($texto) || mb_strlen($texto) < 5) erro('O texto do depoimento está muito curto.');

// Upload Imagem
$nomeImagemFinal = '';
if (isset($_FILES['imagem']) && $_FILES['imagem']['error'] === UPLOAD_ERR_OK) {
    $file = $_FILES['imagem'];
    
    // Tamanho máx 2MB
    if ($file['size'] > 2 * 1024 * 1024) erro('A imagem deve ter no máximo 2MB.');

    // Validar tipo real
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);

    $allowed = MIME_TO_EXT;

    if (!array_key_exists($mime, $allowed)) {
        erro('Formato de imagem inválido. Use JPG, PNG, WEBP, GIF, AVIF, BMP ou TIFF.');
    }

    $ext = $allowed[$mime];
    $nomeArquivo = 'client_' . bin2hex(random_bytes(8)) . '.' . $ext;
    $pastaDestino = __DIR__ . '/../adm/uploads/depoimentos/';

    if (!is_dir($pastaDestino)) mkdir($pastaDestino, 0755, true);

    $nomeImagemFinal = uploadAndConvertToWebp($file['tmp_name'], $pastaDestino, $nomeArquivo);

    if (!$nomeImagemFinal) {
        erro('Erro ao salvar a imagem. Tente novamente.');
    }
}

// Inserção no banco
try {
    // Insere inicialmente com o que é garantido na tabela base
    $stmt = $conn->prepare("INSERT INTO depoimentos (nome, texto, status, imagem) VALUES (?, ?, 'Inativo', ?)");
    $stmt->bind_param("sss", $nome, $texto, $nomeImagemFinal);
    $stmt->execute();
    
    $novoId = $stmt->insert_id;

    // Se o usuário adicionou a coluna 'avaliacao' via SQL, atualiza o valor
    if ($novoId && $avaliacao >= 1 && $avaliacao <= 5) {
        $checkCol = $conn->query("SHOW COLUMNS FROM depoimentos LIKE 'avaliacao'");
        if ($checkCol && $checkCol->num_rows > 0) {
            $upd = $conn->prepare("UPDATE depoimentos SET avaliacao = ? WHERE id = ?");
            $upd->bind_param("ii", $avaliacao, $novoId);
            $upd->execute();
        }
    }

    $redirect = !empty($_POST['redirect_to']) ? $_POST['redirect_to'] : 'depoimento.php';
    $sep = (strpos($redirect, '?') === false) ? '?' : '&';
    redirect($redirect . $sep . 'sucesso=1');

} catch (Exception $e) {
    erro('Ocorreu um erro ao salvar seu depoimento. Tente novamente mais tarde.');
}
