<?php
require 'autoload_qr.php';

use Zxing\QrReader;

header('Content-Type: text/html; charset=utf-8');

$directos = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp', 'image/x-ms-bmp'];

$convertibles = ['image/avif', 'image/heic', 'image/heif', 'image/tiff'];

$erroresSubida = [
    UPLOAD_ERR_INI_SIZE => 'El archivo supera el límite configurado en el servidor.',
    UPLOAD_ERR_FORM_SIZE => 'El archivo supera el límite permitido por el formulario.',
    UPLOAD_ERR_PARTIAL => 'La imagen solo se subió parcialmente.',
    UPLOAD_ERR_NO_FILE => 'No se seleccionó ningún archivo.',
    UPLOAD_ERR_NO_TMP_DIR => 'Falta el directorio temporal del servidor.',
    UPLOAD_ERR_CANT_WRITE => 'No se pudo escribir el archivo en el disco.',
    UPLOAD_ERR_EXTENSION => 'Una extensión del servidor detuvo la subida.',
];

function responder(string $titulo, string $mensaje, bool $ok = false): void
{
    $clase = $ok ? 'ok' : 'err';
    echo <<<HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Leer codigo QR</title>
<style>
body{font-family:system-ui,sans-serif;max-width:42rem;margin:3rem auto;padding:0 1rem;color:#1f2328}
h2{margin-bottom:1rem}
.caja{padding:1rem 1.25rem;border-radius:8px;line-height:1.6}
.ok{background:#e6f4ea;border:1px solid #93c9a3}
.err{background:#fce8e6;border:1px solid #f2b8b5}
code{background:#f0f1f3;padding:.15em .4em;border-radius:4px;word-break:break-all}
a{color:#0b57d0}
</style>
</head>
<body>
<h2>{$titulo}</h2>
<div class="caja {$clase}">{$mensaje}</div>
<p><a href="formulario.php">Volver al formulario</a></p>
</body>
</html>
HTML;
    exit;
}

if (!isset($_FILES['imagenQR'])) {
    responder('Error al subir la imagen', 'No llegó ninguna imagen. Vuelve a intentarlo desde el <a href="formulario.php">formulario</a>.');
}

$subida = $_FILES['imagenQR'];

if ($subida['error'] !== UPLOAD_ERR_OK) {
    $detalle = $erroresSubida[$subida['error']] ?? 'Error desconocido al subir el archivo (código ' . (int) $subida['error'] . ').';
    responder('Error al subir la imagen', htmlspecialchars($detalle));
}

$info = @getimagesize($subida['tmp_name']);

if ($info === false || empty($info['mime'])) {
    responder('Imagen no válida', 'El archivo no es una imagen que el servidor pueda procesar.');
}

$mime = strtolower($info['mime']);

$directorio = __DIR__ . DIRECTORY_SEPARATOR . 'uploads';

if (!is_dir($directorio)) {
    @mkdir($directorio, 0777, true);
}

if (!is_writable($directorio)) {
    responder('Sin permisos de escritura', 'El directorio <code>uploads/</code> no permite escritura. Ejecuta:<br><code>chmod 777 uploads</code>');
}

$nombre = preg_replace('/[^A-Za-z0-9._-]+/', '_', pathinfo($subida['name'], PATHINFO_FILENAME));
$nombre = substr($nombre === '' ? 'qr' : $nombre, 0, 60);

$extension = strtolower(pathinfo($subida['name'], PATHINFO_EXTENSION));
if (!preg_match('/^[a-z0-9]{1,5}$/', $extension)) {
    $extension = 'img';
}

if (in_array($mime, $directos, true)) {
    $rutaFinal = $directorio . DIRECTORY_SEPARATOR . $nombre . '.' . $extension;
    if (!move_uploaded_file($subida['tmp_name'], $rutaFinal)) {
        responder('Error al subir la imagen', 'No se pudo guardar el archivo dentro de <code>uploads/</code>.');
    }
} elseif (in_array($mime, $convertibles, true)) {
    $rutaFinal = $directorio . DIRECTORY_SEPARATOR . $nombre . '.png';
    $salida = [];
    $codigo = 0;
    exec('convert ' . escapeshellarg($subida['tmp_name']) . ' -auto-orient ' . escapeshellarg($rutaFinal) . ' 2>&1', $salida, $codigo);
    if ($codigo !== 0 || !is_file($rutaFinal)) {
        $detalle = trim(implode("\n", $salida));
        $extra = $detalle !== '' ? '<br><code>' . htmlspecialchars($detalle) . '</code>' : '';
        responder('Formato no compatible', 'No se pudo convertir la imagen <strong>' . htmlspecialchars($mime) . '</strong>.' . $extra);
    }
} else {
    responder('Formato no compatible', 'El formato <strong>' . htmlspecialchars($mime) . '</strong> no está soportado. Usa JPG, PNG, GIF, WebP o BMP.');
}

if (!function_exists('mb_detect_encoding')) {
    responder(
        'Falta una extensión de PHP',
        'La extensión <code>mbstring</code> no está instalada y es necesaria para decodificar el texto del QR.<br><br>Instálala con:<br><code>sudo apt install -y php8.3-mbstring &amp;&amp; sudo systemctl restart php8.3-fpm</code>'
    );
}

try {
    $lector = new QrReader($rutaFinal);
    $texto = $lector->text();
} catch (Throwable $e) {
    $mensaje = $e->getMessage();

    if (str_contains($mensaje, 'mb_detect_encoding')) {
        responder(
            'Falta una extensión de PHP',
            'La extensión <code>mbstring</code> no está instalada y es necesaria para decodificar el texto del QR.<br><br>Instálala con:<br><code>sudo apt install -y php8.3-mbstring &amp;&amp; sudo systemctl restart php8.3-fpm</code>'
        );
    }

    if ($mensaje === 'Invalid image source.') {
        responder('No se pudo leer la imagen', 'El servidor no pudo abrir el archivo como imagen compatible. Prueba con un PNG o JPG.');
    }

    responder('No se pudo leer el código QR', htmlspecialchars($mensaje));
}

if (is_string($texto) && $texto !== '') {
    responder('Contenido del QR', htmlspecialchars($texto), true);
}

responder('No se encontró código QR', 'La imagen se subió correctamente, pero no contiene un código QR legible. Prueba con una foto más nítida y bien iluminada.');
