<?php
require_once __DIR__ . '/auth.php';

// Gemeinsame Endung→MIME-Whitelists.
const UPLOAD_TYPES_DOCS = [
    'pdf'  => ['application/pdf'],
    'doc'  => ['application/msword'],
    'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
    'jpg'  => ['image/jpeg'],
    'jpeg' => ['image/jpeg'],
    'png'  => ['image/png'],
];

const UPLOAD_TYPES_PDF_IMG = [
    'pdf'  => ['application/pdf'],
    'jpg'  => ['image/jpeg'],
    'jpeg' => ['image/jpeg'],
    'png'  => ['image/png'],
];

const UPLOAD_TYPES_IMAGES = [
    'jpg'  => ['image/jpeg'],
    'jpeg' => ['image/jpeg'],
    'png'  => ['image/png'],
    'gif'  => ['image/gif'],
    'webp' => ['image/webp'],
];

const UPLOAD_TYPES_PDF = [
    'pdf' => ['application/pdf'],
];

const UPLOAD_TYPES_OFFICE = [
    'pdf'  => ['application/pdf'],
    'doc'  => ['application/msword'],
    'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
    'xls'  => ['application/vnd.ms-excel'],
    'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
    'ppt'  => ['application/vnd.ms-powerpoint'],
    'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
    'txt'  => ['text/plain'],
    'zip'  => ['application/zip', 'application/x-zip-compressed'],
];

/**
 * Validiert und speichert eine hochgeladene Datei.
 *
 * @param array $file Eintrag aus $_FILES, z.B. $_FILES['datei']
 * @param array $opts allowed (ext=>mimes, Pflicht), dir (Pflicht), prefix,
 *                    max_bytes (Default 12 MB), required (Default true),
 *                    naming ('dated' [Default] = Datum_Username_Prefix_Rand,
 *                            'plain' = Username_Rand, 'hash' = nur Rand),
 *                    username (Default current_username(); für 'dated'/'plain'),
 *                    messages (Überschreibt Standardtexte: missing/upload/ext/mime/size/move)
 * @return array ['ok'=>bool, 'error'=>?string, 'filename'=>?string,
 *               'original_name'=>?string, 'mime'=>?string]
 */
function handle_upload(array $file, array $opts): array {
    $allowed   = $opts['allowed'];
    $dir       = rtrim($opts['dir'], '/') . '/';
    $maxBytes  = $opts['max_bytes'] ?? 12 * 1024 * 1024;
    $required  = $opts['required']  ?? true;
    $naming    = $opts['naming']    ?? 'dated';
    $prefix    = $opts['prefix']    ?? 'datei';
    $username  = $opts['username']  ?? current_username();

    $msg = array_merge([
        'missing' => 'Bitte eine Datei auswählen.',
        'upload'  => 'Fehler beim Hochladen der Datei.',
        'ext'     => 'Dateityp nicht erlaubt.',
        'mime'    => 'Dateityp nicht erlaubt.',
        'size'    => 'Datei ist zu groß (max. 12 MB).',
        'move'    => 'Fehler beim Hochladen der Datei.',
    ], $opts['messages'] ?? []);

    $err = $file['error'] ?? UPLOAD_ERR_NO_FILE;

    if ($err === UPLOAD_ERR_NO_FILE || !isset($file['tmp_name'])) {
        if ($required) return ['ok' => false, 'error' => $msg['missing']];
        return ['ok' => true, 'error' => null, 'filename' => null, 'original_name' => null, 'mime' => null];
    }
    if ($err !== UPLOAD_ERR_OK) {
        return ['ok' => false, 'error' => $msg['upload']];
    }

    $originalName = $file['name'];
    $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
    if (!isset($allowed[$ext])) {
        return ['ok' => false, 'error' => $msg['ext']];
    }

    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime  = $finfo->file($file['tmp_name']);
    if (!in_array($mime, $allowed[$ext], true)) {
        return ['ok' => false, 'error' => $msg['mime']];
    }

    if ($file['size'] > $maxBytes) {
        return ['ok' => false, 'error' => $msg['size']];
    }

    $safeName = match ($naming) {
        'hash'  => bin2hex(random_bytes(16)) . '.' . $ext,
        'plain' => $username . '_' . bin2hex(random_bytes(8)) . '.' . $ext,
        default => date('Y-m-d') . '_' . $username . '_' . $prefix . '_' . bin2hex(random_bytes(8)) . '.' . $ext,
    };

    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }
    if (!move_uploaded_file($file['tmp_name'], $dir . $safeName)) {
        return ['ok' => false, 'error' => $msg['move']];
    }

    return [
        'ok'            => true,
        'error'         => null,
        'filename'      => $safeName,
        'original_name' => $originalName,
        'mime'          => $mime,
    ];
}

function redirect_error(string $back, string $msg): never {
    header('Location: ' . $back . '?error=' . urlencode($msg));
    exit;
}

function redirect_ok(string $back, string $param = 'success', string $val = '1'): never {
    header('Location: ' . $back . '?' . $param . '=' . $val);
    exit;
}
