<?php
declare(strict_types=1);

require_once 'conexao.php';
require_once 'os_publico_helpers.php';

date_default_timezone_set('America/Sao_Paulo');

if ($mysqli instanceof mysqli) {
    $mysqli->set_charset('utf8mb4');
}

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_start();
}

function responder(array $dados, int $status = 200): never
{
    http_response_code($status);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($dados, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    responder(['ok' => false, 'message' => 'Método não permitido.'], 405);
}

$token = strtolower(trim((string) ($_POST['token'] ?? '')));
$csrf = (string) ($_POST['csrf_token'] ?? '');
$nota = (int) ($_POST['nota'] ?? 0);
$resolvido = (int) ($_POST['resolvido'] ?? -1);
$comentario = trim((string) ($_POST['comentario'] ?? ''));

if (preg_match('/^[a-f0-9]{48,64}$/', $token) !== 1) {
    responder(['ok' => false, 'message' => 'Link inválido.'], 422);
}

$hash = hash('sha256', $token);

if (
    !isset($_SESSION['csrf_os_publico']) ||
    !is_array($_SESSION['csrf_os_publico'])
) {
    $_SESSION['csrf_os_publico'] = [];
}

$csrfSessao = (string) ($_SESSION['csrf_os_publico'][$hash] ?? '');

if ($csrfSessao === '' || $csrf === '' || !hash_equals($csrfSessao, $csrf)) {
    responder(['ok' => false, 'message' => 'A sessão expirou. Atualize a página.'], 419);
}

if ($nota < 1 || $nota > 4) {
    responder(['ok' => false, 'message' => 'Selecione uma avaliação válida.'], 422);
}

if (!in_array($resolvido, [0, 1], true)) {
    responder(['ok' => false, 'message' => 'Informe se o problema foi resolvido.'], 422);
}

if (function_exists('mb_strlen') ? mb_strlen($comentario, 'UTF-8') > 500 : strlen($comentario) > 500) {
    responder(['ok' => false, 'message' => 'O comentário deve possuir até 500 caracteres.'], 422);
}

$stmt = $mysqli->prepare("
    SELECT id, status
    FROM ordens_servico
    WHERE token_acompanhamento = ?
      AND acompanhamento_ativo = 1
    LIMIT 1
");

if (!$stmt) {
    responder(['ok' => false, 'message' => 'Não foi possível consultar a OS.'], 500);
}

$stmt->bind_param('s', $token);
$stmt->execute();
$os = $stmt->get_result()->fetch_assoc();
$stmt->close();

if (!$os) {
    responder(['ok' => false, 'message' => 'Ordem de serviço não encontrada.'], 404);
}

if (osPublicoStatusCodigo((string) $os['status']) !== 'entregue') {
    responder(['ok' => false, 'message' => 'A avaliação é liberada somente após a entrega do equipamento.'], 409);
}

$osId = (int) $os['id'];

$stmt = $mysqli->prepare("
    INSERT INTO os_avaliacoes (
        os_id,
        nota,
        resolvido,
        comentario
    ) VALUES (?, ?, ?, NULLIF(?, ''))
    ON DUPLICATE KEY UPDATE
        nota = VALUES(nota),
        resolvido = VALUES(resolvido),
        comentario = VALUES(comentario),
        criado_em = CURRENT_TIMESTAMP
");

if (!$stmt) {
    responder(['ok' => false, 'message' => 'Não foi possível preparar a avaliação.'], 500);
}

$stmt->bind_param('iiis', $osId, $nota, $resolvido, $comentario);

if (!$stmt->execute()) {
    $mensagem = $stmt->error;
    $stmt->close();
    responder(['ok' => false, 'message' => 'Erro ao registrar avaliação: ' . $mensagem], 500);
}

$stmt->close();

responder(['ok' => true, 'message' => 'Avaliação registrada. Obrigado pela participação.']);
