<?php
ob_start();
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    ob_clean();
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'error' => "PHP Error [{$errno}]: {$errstr} en {$errfile}:{$errline}"]);
    exit;
});
set_exception_handler(function($e) {
    ob_clean();
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
    exit;
});
header('Content-Type: application/json');
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/GoogleClient.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['success' => false, 'error' => 'Método no permitido']); exit;
}
if (empty($_POST['cliente'])) {
    echo json_encode(['success' => false, 'error' => 'El campo cliente es obligatorio']); exit;
}
if (empty($_FILES['files']['name'][0])) {
    echo json_encode(['success' => false, 'error' => 'Debes subir al menos un archivo']); exit;
}

$cliente    = trim(strip_tags($_POST['cliente']));
$fecha      = $_POST['fecha'] ?? date('Y-m-d');
$notas      = $_POST['notas'] ?? '';
$timestamp  = date('Ymd_His');
$folderName = $cliente;

// ─── Guardar archivos temporales ──────────────────────────────────────────
$savedFiles = [];
$fileCount  = count($_FILES['files']['name']);

for ($i = 0; $i < $fileCount; $i++) {
    $err      = $_FILES['files']['error'][$i];
    $size     = $_FILES['files']['size'][$i];
    $mime     = $_FILES['files']['type'][$i];
    $tmpPath  = $_FILES['files']['tmp_name'][$i];
    $origName = basename($_FILES['files']['name'][$i]);

    if ($err !== UPLOAD_ERR_OK) continue;
    if ($size > MAX_FILE_SIZE_MB * 1024 * 1024) continue;

    // Re-validar MIME real con finfo
    $finfo    = new finfo(FILEINFO_MIME_TYPE);
    $realMime = $finfo->file($tmpPath);
    if (!in_array($realMime, ALLOWED_MIME_TYPES, true)) continue;

    $safeName = $timestamp . '_' . preg_replace('/[^a-zA-Z0-9._-]/', '_', $origName);
    $dest     = COARCA_UPLOADS_TMP . '/' . $safeName;
    move_uploaded_file($tmpPath, $dest);
    $savedFiles[] = ['path' => $dest, 'name' => $safeName, 'mime' => $realMime];
}

if (empty($savedFiles)) {
    echo json_encode(['success' => false, 'error' => 'Ningún archivo válido recibido']); exit;
}

// ─── Generar PDF ─────────────────────────────────────────────────────────
$pdfPath = COARCA_UPLOADS_TMP . "/{$timestamp}_{$cliente}_registro.pdf";
$pdfMime = 'application/pdf';

try {
    $pdfPath = generatePdf($savedFiles, $cliente, $fecha, $notas, $pdfPath, $timestamp);
} catch (Throwable $e) {
    // Si falla generación de PDF, subir archivos originales directamente
    $pdfPath = null;
}

// ─── Subir a Drive ────────────────────────────────────────────────────────
$driveLink = '';
$sheetRow  = [];

try {
    $gc     = new GoogleClient(COARCA_ROOT . '/config/google-token.json');
    $rootId = GOOGLE_DRIVE_ROOT_FOLDER;

    // Carpeta del cliente
    $clientFolderId = $gc->getOrCreateFolder($folderName, $rootId);

    // Subcarpeta por fecha
    $dateFolderId = $gc->getOrCreateFolder($fecha, $clientFolderId);

    if ($pdfPath && file_exists($pdfPath)) {
        $up = $gc->uploadFile($pdfPath, basename($pdfPath), 'application/pdf', $dateFolderId);
        $driveLink = $up['webViewLink'] ?? '';
    } else {
        // Subir archivos sueltos si no hay PDF
        foreach ($savedFiles as $f) {
            $up = $gc->uploadFile($f['path'], $f['name'], $f['mime'], $dateFolderId);
            if (empty($driveLink)) $driveLink = $up['webViewLink'] ?? '';
        }
    }

} catch (Throwable $e) {
    // Limpiar temporales
    cleanupTmp($savedFiles, $pdfPath);
    echo json_encode(['success' => false, 'error' => 'Error Google: ' . $e->getMessage()]); exit;
}

// ─── Limpiar temporales ───────────────────────────────────────────────────
cleanupTmp($savedFiles, $pdfPath);

echo json_encode([
    'success'    => true,
    'drive_link' => $driveLink,
    'pdf_url'    => $pdfPath ? basename($pdfPath) : null,
]);

// ─── Funciones ────────────────────────────────────────────────────────────

function cleanupTmp(array $files, ?string $pdfPath): void
{
    foreach ($files as $f) {
        if (file_exists($f['path'])) @unlink($f['path']);
    }
    if ($pdfPath && file_exists($pdfPath)) @unlink($pdfPath);
}

function generatePdf(array $files, string $cliente, string $fecha, string $notas, string $outPath): string
{
    // A4 en píxeles a 150 DPI — buena calidad sin ser demasiado pesado
    $pxW = 1240;
    $pxH = 1754;

    // A4 en puntos PDF
    $ptW = 595;
    $ptH = 842;

    $nextId  = 3;
    $objects = [];
    $newObj  = function(string $body) use (&$objects, &$nextId): int {
        $id = $nextId++;
        $objects[$id] = $body;
        return $id;
    };

    $pageIds    = [];
    $imageFiles = array_values(array_filter($files, fn($f) => str_starts_with($f['mime'], 'image/')));

    if (empty($imageFiles)) throw new RuntimeException('No hay imágenes para generar el PDF');

    foreach ($imageFiles as $f) {
        $src = @imagecreatefromstring(@file_get_contents($f['path']));
        if (!$src) continue;

        $origW = imagesx($src);
        $origH = imagesy($src);

        // Decidir orientación de página según la imagen
        $landscape = $origW > $origH;
        $canvasW   = $landscape ? $pxH  : $pxW;
        $canvasH   = $landscape ? $pxW  : $pxH;
        $pageW     = $landscape ? $ptH  : $ptW;
        $pageH     = $landscape ? $ptW  : $ptH;

        // Cover scale: recortar el origen para llenar el canvas sin barras (sin offsets negativos en destino)
        $scale = max($canvasW / $origW, $canvasH / $origH);
        $srcW  = (int)round($canvasW / $scale);
        $srcH  = (int)round($canvasH / $scale);
        $srcX  = (int)(($origW - $srcW) / 2);
        $srcY  = (int)(($origH - $srcH) / 2);

        $canvas = imagecreatetruecolor($canvasW, $canvasH);
        imagefill($canvas, 0, 0, imagecolorallocate($canvas, 255, 255, 255));
        imagecopyresampled($canvas, $src, 0, 0, $srcX, $srcY, $canvasW, $canvasH, $srcW, $srcH);
        imagedestroy($src);

        // Exportar canvas a JPEG en memoria
        ob_start();
        imagejpeg($canvas, null, 92);
        $imgData = ob_get_clean();
        imagedestroy($canvas);

        if (!$imgData) continue;

        $imgId = $newObj(
            "<< /Type /XObject /Subtype /Image\n" .
            "  /Width {$canvasW} /Height {$canvasH}\n" .
            "  /ColorSpace /DeviceRGB /BitsPerComponent 8\n" .
            "  /Filter /DCTDecode /Length " . strlen($imgData) . " >>\n" .
            "stream\n" . $imgData . "\nendstream"
        );

        // Imagen ocupa toda la página PDF (0,0 → pageW, pageH)
        $stream = "q {$pageW} 0 0 {$pageH} 0 0 cm /Img{$imgId} Do Q\n";
        $sid    = $newObj("<< /Length " . strlen($stream) . " >>\nstream\n{$stream}\nendstream");
        $pageIds[] = $newObj(
            "<< /Type /Page /Parent 2 0 R /MediaBox [0 0 {$pageW} {$pageH}]\n" .
            "  /Contents {$sid} 0 R\n" .
            "  /Resources << /XObject << /Img{$imgId} {$imgId} 0 R >> >> >>"
        );
    }

    if (empty($pageIds)) throw new RuntimeException('No se pudo procesar ninguna imagen');

    // Ensamblar PDF
    $kids = implode(' 0 R ', $pageIds) . ' 0 R';
    $pdf  = "%PDF-1.4\n%\xe2\xe3\xcf\xd3\n";
    $refs = [];

    $refs[1] = strlen($pdf);
    $pdf .= "1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n";

    $refs[2] = strlen($pdf);
    $pdf .= "2 0 obj\n<< /Type /Pages /Kids [{$kids}] /Count " . count($pageIds) . " >>\nendobj\n";

    foreach ($objects as $id => $body) {
        $refs[$id] = strlen($pdf);
        $pdf .= "{$id} 0 obj\n{$body}\nendobj\n";
    }

    $xrefPos = strlen($pdf);
    $total   = $nextId;
    $pdf .= "xref\n0 {$total}\n0000000000 65535 f \n";
    for ($i = 1; $i < $total; $i++) {
        $pdf .= str_pad($refs[$i] ?? 0, 10, '0', STR_PAD_LEFT) . " 00000 n \n";
    }
    $pdf .= "trailer\n<< /Size {$total} /Root 1 0 R >>\nstartxref\n{$xrefPos}\n%%EOF\n";

    file_put_contents($outPath, $pdf);
    return $outPath;
}

function pdfSafeText(string $s): string
{
    // Eliminar caracteres no imprimibles y escapar paréntesis para PDF
    $s = preg_replace('/[^\x20-\x7E]/', '', $s);
    return str_replace(['(', ')', '\\'], ['\\(', '\\)', '\\\\'], $s);
}
