<?php
include 'db.php';
include 'formulario_utils.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    die('Acesso inválido. Formulário deve ser enviado via POST.');
}

if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
    die('Formulário inválido!');
}
$formId = (int) $_GET['id'];

$stmt = $pdo->prepare('SELECT * FROM formularios WHERE id = :id');
$stmt->execute(['id' => $formId]);
$formulario = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$formulario) {
    die('Formulário não encontrado.');
}

$isOnboard = (string) ($formulario['categoria'] ?? '') === 'OnBoard';

$stmt = $pdo->prepare("SELECT * FROM formulario_campos WHERE formulario_id = :id ORDER BY id ASC");
$stmt->execute(['id' => $formId]);
$campos = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

$uploadDir = __DIR__ . '/uploads/';
if (!is_dir($uploadDir) && !mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) {
    die('Não foi possível preparar a pasta de uploads.');
}

$allowedExtensions = ['image' => ['jpg', 'jpeg', 'png', 'gif', 'webp'], 'file' => ['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png', 'gif', 'webp']];
$maxUploadBytes = 10 * 1024 * 1024;
$uploadedFiles = [];

try {
    $pdo->beginTransaction();

    $stmt = $pdo->prepare('INSERT INTO formulario_respostas (formulario_id, created_at) VALUES (:fid, NOW())');
    $stmt->execute(['fid' => $formId]);
    $respostaId = (int) $pdo->lastInsertId();

    foreach ($campos as $campo) {
        if ((int) ($campo['hidden'] ?? 0) === 1 || (string) ($campo['tipo'] ?? '') === 'warning') {
            continue;
        }

        $campoId = (int) $campo['id'];
        $fieldName = 'campo_' . $campoId;
        $tipo = (string) ($campo['tipo'] ?? 'text');
        $required = (int) ($campo['required'] ?? 0) === 1;
        $valor = null;
        $correto = null;

        if (in_array($tipo, ['image', 'file'], true)) {
            $file = $_FILES[$fieldName] ?? null;
            $hasUpload = is_array($file) && (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE);

            if (!$hasUpload) {
                if ($required) {
                    throw new RuntimeException('Envie o arquivo do campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
            } else {
                if (($file['error'] ?? UPLOAD_ERR_OK) !== UPLOAD_ERR_OK) {
                    throw new RuntimeException('Falha no upload do campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }

                $originalName = (string) ($file['name'] ?? 'arquivo');
                $ext = strtolower((string) pathinfo($originalName, PATHINFO_EXTENSION));
                $allowedForField = isset($allowedExtensions[$tipo]) ? $allowedExtensions[$tipo] : [];
                if (!in_array($ext, $allowedForField, true)) {
                    throw new RuntimeException('Extensão não permitida no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
                $fileSize = (int) ($file['size'] ?? 0);
                if ($fileSize <= 0 || $fileSize > $maxUploadBytes) {
                    throw new RuntimeException('Tamanho de arquivo inválido no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
                $tmpName = (string) ($file['tmp_name'] ?? '');
                if ($tmpName === '' || !is_uploaded_file($tmpName)) {
                    throw new RuntimeException('Upload inválido no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }

                $safeBase = preg_replace('/[^a-zA-Z0-9._-]/', '', $originalName) ?: ('arquivo.' . $ext);
                $newName = uniqid('upload_', true) . '_' . $safeBase;
                $destino = $uploadDir . $newName;

                if (!move_uploaded_file($tmpName, $destino)) {
                    throw new RuntimeException('Não foi possível salvar o arquivo do campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }

                $uploadedFiles[] = $destino;
                $valor = 'uploads/' . $newName;
            }
        } else {
            $rawValue = $_POST[$fieldName] ?? null;
            if (is_array($rawValue)) {
                                $rawArray = array();
                foreach ($rawValue as $item) {
                    $item = trim((string) $item);
                    if ($item !== '') {
                        $rawArray[] = $item;
                    }
                }
                if ($required && $rawArray === []) {
                    throw new RuntimeException('Preencha o campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }

                $options = splitOptions($campo['opcoes'] ?? null);
                foreach ($rawArray as $item) {
                    if ($options !== [] && !in_array($item, $options, true)) {
                        throw new RuntimeException('Opção inválida no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                    }
                }

                $valor = $rawArray !== [] ? implode(', ', $rawArray) : null;
            } else {
                $valor = trim((string) $rawValue);
                if ($valor === '') {
                    $valor = null;
                }

                if ($required && $valor === null) {
                    throw new RuntimeException('Preencha o campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }

                $options = splitOptions($campo['opcoes'] ?? null);
                if ($valor !== null && in_array($tipo, ['select', 'radio'], true) && $options !== [] && !in_array($valor, $options, true)) {
                    throw new RuntimeException('Opção inválida no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
            }

            if ($valor !== null) {
                if ($tipo === 'email' && filter_var($valor, FILTER_VALIDATE_EMAIL) === false) {
                    throw new RuntimeException('E-mail inválido no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
                if ($tipo === 'cpf' && !isValidCpf($valor)) {
                    throw new RuntimeException('CPF inválido no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
                if ($tipo === 'cnpj' && !isValidCnpj($valor)) {
                    throw new RuntimeException('CNPJ inválido no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                }
                if ($tipo === 'date') {
                    $normalizedDate = normalizeSubmittedDate($valor);
                    if ($normalizedDate === null) {
                        throw new RuntimeException('Data inválida no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                    }
                    $valor = $normalizedDate;
                }
                if ($tipo === 'porcentagem') {
                    $numeric = str_replace(',', '.', $valor);
                    if (!is_numeric($numeric) || (float) $numeric < 0 || (float) $numeric > 100) {
                        throw new RuntimeException('Porcentagem inválida no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                    }
                    $valor = (string) $numeric;
                }
                if ($tipo === 'number') {
                    $numeric = str_replace(',', '.', $valor);
                    if (!is_numeric($numeric)) {
                        throw new RuntimeException('Número inválido no campo ' . ($campo['label'] ?? ('#' . $campoId)) . '.');
                    }
                    $valor = (string) $numeric;
                }
            }

            if ($isOnboard && $valor !== null && array_key_exists('resposta_correta', $campo) && trim((string) $campo['resposta_correta']) !== '') {
                $correto = strcasecmp(trim((string) $valor), trim((string) $campo['resposta_correta'])) === 0 ? 1 : 0;
            }
        }

        if ($valor === null && $correto === null) {
            continue;
        }

        $stmtInsert = $pdo->prepare(
            'INSERT INTO formulario_respostas_campos (resposta_id, campo_id, valor, correto) VALUES (:rid, :cid, :valor, :correto)'
        );
        $stmtInsert->bindValue(':rid', $respostaId, PDO::PARAM_INT);
        $stmtInsert->bindValue(':cid', $campoId, PDO::PARAM_INT);
        if ($valor === null) {
            $stmtInsert->bindValue(':valor', null, PDO::PARAM_NULL);
        } else {
            $stmtInsert->bindValue(':valor', $valor, PDO::PARAM_STR);
        }
        if ($correto === null) {
            $stmtInsert->bindValue(':correto', null, PDO::PARAM_NULL);
        } else {
            $stmtInsert->bindValue(':correto', $correto, PDO::PARAM_INT);
        }
        $stmtInsert->execute();
    }

    $pdo->commit();

    if ($formId === 28) {
        header('Location: obrigado_denuncia.php?id=' . $formId);
    } else {
        header('Location: parabens.php?id=' . $formId);
    }
    exit;
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    deleteStoredFiles($uploadedFiles, __DIR__);

    error_log('Erro no formulário (#' . $formId . '): ' . $e->getMessage());
    die('Erro ao enviar o formulário: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'));
}
