<?php
session_start();

// === CSRF helper (multi-token, one-time use) ===
if (!isset($_SESSION['csrf_tokens']) || !is_array($_SESSION['csrf_tokens'])) {
    $_SESSION['csrf_tokens'] = [];
}
function csrf_gc($ttl = 7200) {
    $now = time();
    foreach ($_SESSION['csrf_tokens'] as $t => $ts) {
        if ($now - (int)$ts > $ttl) {
            unset($_SESSION['csrf_tokens'][$t]);
        }
    }
}
function csrf_issue($ttl = 7200) {
    csrf_gc($ttl);
    $token = bin2hex(random_bytes(32));
    $_SESSION['csrf_tokens'][$token] = time();
    return $token;
}
function csrf_validate($token, $ttl = 7200, $consume = true) {
    csrf_gc($ttl);
    if (!$token) return false;
    if (!isset($_SESSION['csrf_tokens'][$token])) return false;
    $age = time() - (int)$_SESSION['csrf_tokens'][$token];
    $ok = $age <= $ttl;
    // One-time use by default; if $consume is false, leave token for reuse until TTL
    if ($consume) {
        unset($_SESSION['csrf_tokens'][$token]);
    }
    return $ok && $age >= 0;
}
function csrf_header_token() {
    $headers = function_exists('getallheaders') ? getallheaders() : [];
    $token = $headers['X-CSRF-Token'] ?? $headers['X-Csrf-Token'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? null);
    return $token;
}
// ================================================
require_once 'conexao.php';

// Sempre retornar JSON
header('Content-Type: application/json');

// Verifica se o usuário está logado
if (empty($_SESSION['logado'])) {
    echo json_encode(['status' => 'erro', 'mensagem' => 'Não autorizado']);
    exit;
}

// Verifica a existência do tenant_id
$tenant_id = $_SESSION['tenant_id'] ?? null;
if (!$tenant_id || !is_numeric($tenant_id)) {
    echo json_encode(['status' => 'erro', 'mensagem' => 'Tenant não identificado']);
    exit;
}

// Verificação de token CSRF via header
$headers = function_exists('getallheaders') ? getallheaders() : [];
$token_header = $headers['X-CSRF-Token'] ?? $headers['X-Csrf-Token'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? null);
if (!csrf_validate($token_header)) {
    echo json_encode(['status' => 'erro', 'mensagem' => 'Token CSRF inválido']);
    exit;
}

// Recebe o corpo da requisição
$json = file_get_contents('php://input');
$data = json_decode($json, true);

// Verifica se o ID foi enviado e é válido
if (!isset($data['id']) || !is_numeric($data['id'])) {
    echo json_encode(['status' => 'erro', 'mensagem' => 'ID do formulário inválido']);
    exit;
}

$formulario_id = (int)$data['id'];

try {
    // Inicia a transação
    $conn->begin_transaction();

    // Busca o formulário original
    $stmt = $conn->prepare("SELECT nome FROM formularios WHERE id = ? AND tenant_id = ?");
    $stmt->bind_param("ii", $formulario_id, $tenant_id);
    $stmt->execute();
    $result = $stmt->get_result();
    $formulario = $result->fetch_assoc();
    $stmt->close();

    if (!$formulario) {
        throw new Exception('Formulário não encontrado');
    }

    // Gera o novo nome
    $novoNome = 'Cópia de ' . $formulario['nome'];

    // Insere a cópia do formulário
    $stmt = $conn->prepare("INSERT INTO formularios (tenant_id, nome, criado_em) VALUES (?, ?, NOW())");
    $stmt->bind_param("is", $tenant_id, $novoNome);
    $stmt->execute();
    $novoId = $stmt->insert_id;
    $stmt->close();

    // Mapeamento de IDs antigos para novos
    $perguntaMap = array(); // Mapeia id_pergunta_antiga => id_pergunta_nova
    $respostaMap = array(); // Mapeia id_resposta_antiga => id_resposta_nova

    // Buscar todas as perguntas do formulário original
    $stmt = $conn->prepare("SELECT id, texto, tipo, parent_resposta_id, obrigatoria 
                           FROM perguntas 
                           WHERE formulario_id = ?");
    $stmt->bind_param("i", $formulario_id);
    $stmt->execute();
    $perguntas = $stmt->get_result();
    $stmt->close();

    // Primeiro, inserir perguntas que não têm parent_resposta_id (perguntas principais)
    while ($pergunta = $perguntas->fetch_assoc()) {
        if ($pergunta['parent_resposta_id'] === null) {
            $stmt = $conn->prepare("INSERT INTO perguntas 
                                   (formulario_id, texto, tipo, parent_resposta_id, obrigatoria) 
                                   VALUES (?, ?, ?, ?, ?)");
            $stmt->bind_param("issii", 
                $novoId, 
                $pergunta['texto'], 
                $pergunta['tipo'], 
                $pergunta['parent_resposta_id'],
                $pergunta['obrigatoria']
            );
            $stmt->execute();
            $perguntaMap[$pergunta['id']] = $stmt->insert_id;
            $stmt->close();
        }
    }

    // Agora, inserir perguntas que têm parent_resposta_id (perguntas condicionais)
    // Precisamos re-executar a consulta para percorrer novamente
    $stmt = $conn->prepare("SELECT id, texto, tipo, parent_resposta_id, obrigatoria 
                           FROM perguntas 
                           WHERE formulario_id = ?");
    $stmt->bind_param("i", $formulario_id);
    $stmt->execute();
    $perguntas = $stmt->get_result();
    $stmt->close();

    while ($pergunta = $perguntas->fetch_assoc()) {
        if ($pergunta['parent_resposta_id'] !== null) {
            // Precisamos mapear o parent_resposta_id antigo para o novo
            // Primeiro, precisamos buscar a resposta original para encontrar a pergunta associada
            $stmt = $conn->prepare("SELECT pergunta_id FROM opcoes_resposta WHERE id = ?");
            $stmt->bind_param("i", $pergunta['parent_resposta_id']);
            $stmt->execute();
            $resposta_original = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            
            if ($resposta_original) {
                $pergunta_original_id = $resposta_original['pergunta_id'];
                $nova_pergunta_id = $perguntaMap[$pergunta_original_id] ?? null;
                
                if ($nova_pergunta_id) {
                    // Agora precisamos encontrar o ID da nova resposta correspondente
                    // Buscar a resposta original
                    $stmt = $conn->prepare("SELECT texto FROM opcoes_resposta WHERE id = ?");
                    $stmt->bind_param("i", $pergunta['parent_resposta_id']);
                    $stmt->execute();
                    $resposta_original_texto = $stmt->get_result()->fetch_assoc();
                    $stmt->close();
                    
                    if ($resposta_original_texto) {
                        // Buscar a nova resposta com o mesmo texto na nova pergunta
                        $stmt = $conn->prepare("SELECT id FROM opcoes_resposta 
                                              WHERE pergunta_id = ? AND texto = ?");
                        $stmt->bind_param("is", $nova_pergunta_id, $resposta_original_texto['texto']);
                        $stmt->execute();
                        $nova_resposta = $stmt->get_result()->fetch_assoc();
                        $stmt->close();
                        
                        if ($nova_resposta) {
                            $novo_parent_resposta_id = $nova_resposta['id'];
                            
                            // Agora podemos inserir a pergunta condicional
                            $stmt = $conn->prepare("INSERT INTO perguntas 
                                                  (formulario_id, texto, tipo, parent_resposta_id, obrigatoria) 
                                                  VALUES (?, ?, ?, ?, ?)");
                            $stmt->bind_param("issii", 
                                $novoId, 
                                $pergunta['texto'], 
                                $pergunta['tipo'], 
                                $novo_parent_resposta_id,
                                $pergunta['obrigatoria']
                            );
                            $stmt->execute();
                            $perguntaMap[$pergunta['id']] = $stmt->insert_id;
                            $stmt->close();
                        }
                    }
                }
            }
        }
    }

    // Agora, inserir as opções de resposta para cada pergunta
    foreach ($perguntaMap as $pergunta_antiga_id => $pergunta_nova_id) {
        $stmt = $conn->prepare("SELECT id, texto FROM opcoes_resposta WHERE pergunta_id = ?");
        $stmt->bind_param("i", $pergunta_antiga_id);
        $stmt->execute();
        $respostas = $stmt->get_result();
        $stmt->close();
        
        while ($resposta = $respostas->fetch_assoc()) {
            $stmt = $conn->prepare("INSERT INTO opcoes_resposta (pergunta_id, texto) VALUES (?, ?)");
            $stmt->bind_param("is", $pergunta_nova_id, $resposta['texto']);
            $stmt->execute();
            $respostaMap[$resposta['id']] = $stmt->insert_id;
            $stmt->close();
        }
    }

    // Finaliza a transação
    $conn->commit();

    echo json_encode([
        'status' => 'sucesso',
        'mensagem' => 'Formulário duplicado com sucesso',
        'formulario_id' => $novoId,
        'csrf_token' => csrf_issue()
    ]);

} catch (Exception $e) {
    // Rollback em caso de erro
    $conn->rollback();

    echo json_encode([
        'status' => 'erro',
        'mensagem' => 'Erro ao duplicar formulário: ' . $e->getMessage()
    ]);
}
?>