<?php
/**
 * validate-file-fragment.php
 *
 * HTMX fragment: validates a single uploaded file against MIME type and size
 * constraints. Returns an inline error message or clears the file input wrapper.
 *
 * Expected POST (multipart/form-data):
 *   file         — the uploaded file
 *   field_name   — 'couverture' | 'note_intention' | 'tfe' | 'annexes'
 *   admin_mode   — '1' to skip validation (admins can upload anything)
 */

require_once __DIR__ . '/../../bootstrap.php';

$adminMode = ($_POST['admin_mode'] ?? '0') === '1';
$fieldName = $_POST['field_name'] ?? '';

// Read file from the field-name-specific key (e.g., $_FILES['couverture'], $_FILES['annexes'])
// Fall back to the first file in $_FILES if the specific key is empty
// (handles PeerTube inputs where name differs from field_name).
$rawFile = $_FILES[$fieldName] ?? null;
if (!$rawFile || empty($rawFile['name'])) {
    // Try any uploaded file
    foreach ($_FILES as $v) {
        if (!empty($v['name'])) {
            $rawFile = $v;
            break;
        }
    }
}
if ($rawFile && is_array($rawFile['name'] ?? null)) {
    // Multi-file: flatten first entry
    $file = [
        'name'     => $rawFile['name'][0] ?? null,
        'tmp_name' => $rawFile['tmp_name'][0] ?? null,
        'error'    => $rawFile['error'][0] ?? UPLOAD_ERR_NO_FILE,
        'size'     => $rawFile['size'][0] ?? 0,
    ];
    // Validate ALL selected files (batch validation)
    $allFiles = [];
    $count = count($rawFile['name'] ?? []);
    for ($i = 0; $i < $count; $i++) {
        $allFiles[] = [
            'name'     => $rawFile['name'][$i] ?? null,
            'tmp_name' => $rawFile['tmp_name'][$i] ?? null,
            'error'    => $rawFile['error'][$i] ?? UPLOAD_ERR_NO_FILE,
            'size'     => $rawFile['size'][$i] ?? 0,
        ];
    }
} else {
    $file = $rawFile;
    $allFiles = $file ? [$file] : [];
}

// ── No file provided — clear any existing validation state ──────────────────
if (empty($allFiles)) {
    echo '';
    exit;
}

if ($adminMode) {
    // Admins: no validation, always OK
    $count = count($allFiles);
    echo '<span class="fv-ok">✓ ' . $count . ' fichier' . ($count > 1 ? 's' : '') . ' accepté' . ($count > 1 ? 's' : '') . '</span>';
    exit;
}

// ── MIME + extension whitelist per field type ────────────────────────────────
$finfo = new finfo(FILEINFO_MIME_TYPE);

$constraints = match ($fieldName) {
    'couverture' => [
        'mimes'       => ['image/jpeg', 'image/png', 'image/webp'],
        'exts'        => ['jpg', 'jpeg', 'png', 'webp'],
        'maxSize'     => 20 * 1024 * 1024,  // 20 MB
        'label'       => 'Image de couverture',
        'allowedDesc' => 'JPG, PNG ou WEBP',
        'maxSizeDesc' => '20 MB',
    ],
    'note_intention' => [
        'mimes'       => ['application/pdf'],
        'exts'        => ['pdf'],
        'maxSize'     => 100 * 1024 * 1024, // 100 MB
        'label'       => 'Note d\'intention',
        'allowedDesc' => 'PDF uniquement',
        'maxSizeDesc' => '100 MB',
    ],
    'tfe' => [
        'mimes'       => [
            'application/pdf',
            'image/jpeg', 'image/png', 'image/gif', 'image/webp',
            'video/mp4', 'video/webm', 'video/ogg', 'video/quicktime',
            'audio/mpeg', 'audio/mp3', 'audio/ogg', 'audio/wav',
            'audio/flac', 'audio/aac', 'audio/x-m4a', 'audio/mp4',
            'text/vtt',
            'application/zip', 'application/x-zip-compressed',
            'application/x-tar', 'application/gzip',
            'application/octet-stream',
        ],
        'exts'        => [
            'jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf',
            'mp4', 'webm', 'ogv', 'mov',
            'mp3', 'ogg', 'oga', 'wav', 'flac', 'aac', 'm4a',
            'vtt', 'zip', 'tar', 'gz', 'tgz',
        ],
        'maxSize'     => 500 * 1024 * 1024, // 500 MB
        'label'       => 'Fichier TFE',
        'allowedDesc' => 'PDF, images, vidéos, audio, archives',
        'maxSizeDesc' => '500 MB',
    ],
    'annexes' => [
        'mimes'       => [
            'application/pdf', 'image/jpeg', 'image/png', 'image/gif', 'image/webp',
            'video/mp4', 'video/webm', 'video/ogg', 'video/quicktime',
            'audio/mpeg', 'audio/mp3', 'audio/ogg', 'audio/wav',
            'audio/flac', 'audio/aac', 'audio/x-m4a', 'audio/mp4',
            'text/vtt',
            'application/zip', 'application/x-zip-compressed',
            'application/x-tar', 'application/gzip',
            'application/octet-stream',
        ],
        'exts'        => [
            'jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf',
            'mp4', 'webm', 'ogv', 'mov',
            'mp3', 'ogg', 'oga', 'wav', 'flac', 'aac', 'm4a',
            'vtt', 'zip', 'tar', 'gz', 'tgz',
        ],
        'maxSize'     => 500 * 1024 * 1024, // 500 MB
        'label'       => 'Annexe',
        'allowedDesc' => 'PDF, archives, images',
        'maxSizeDesc' => '500 MB',
    ],
    default => [
        'mimes'       => [],
        'exts'        => [],
        'maxSize'     => 500 * 1024 * 1024,
        'label'       => 'Fichier',
        'allowedDesc' => 'tous types',
        'maxSizeDesc' => '500 MB',
    ],
};

// ── Validate each file ──────────────────────────────────────────────────────
$errors = [];
$oks = [];
foreach ($allFiles as $idx => $f) {
    if (($f['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
        continue;
    }

    $mimeType = $finfo->file($f['tmp_name']);
    $ext      = strtolower(pathinfo($f['name'], PATHINFO_EXTENSION));
    $size     = $f['size'];

    if ($mimeType === 'text/plain' && $ext === 'vtt') {
        $mimeType = 'text/vtt';
    }

    // PDF size limit
    $effMaxSize = $constraints['maxSize'];
    $effMaxDesc = $constraints['maxSizeDesc'];
    if ($mimeType === 'application/pdf' || $ext === 'pdf') {
        $effMaxSize = min($effMaxSize, 100 * 1024 * 1024);
        $effMaxDesc = '100 MB';
    }

    // Validate MIME
    $mimeOk = false;
    if ($mimeType === 'application/octet-stream' && !in_array($ext, $constraints['exts'], true)) {
        $mimeOk = false;
    } elseif (in_array($mimeType, $constraints['mimes'], true)) {
        $mimeOk = true;
    } elseif (in_array($ext, $constraints['exts'], true)) {
        $mimeOk = true;
    }

    if (!$mimeOk) {
        $errors[] = '✕ <em>' . htmlspecialchars($f['name']) . '</em> : type non accepté.'
                  . ' Formats acceptés : ' . htmlspecialchars($constraints['allowedDesc']) . '.';
        continue;
    }

    if ($size > $effMaxSize) {
        $mb = round($size / 1024 / 1024, 1);
        $errors[] = '✕ <em>' . htmlspecialchars($f['name']) . '</em> : fichier trop volumineux ('
                   . $mb . ' MB). Maximum : ' . htmlspecialchars($effMaxDesc) . '.';
        continue;
    }

    $oks[] = '✓ <em>' . htmlspecialchars($f['name']) . '</em> : ' . round($size / 1024 / 1024, 1) . ' MB';
}

// ── Output ────────────────────────────────────────────────────────────────────
if (!empty($errors)) {
    echo '<span class="fv-error">' . implode('<br>', $errors) . '</span>';
} elseif (!empty($oks)) {
    echo '<span class="fv-ok">' . implode('<br>', $oks) . '</span>';
} else {
    echo '';
}
