<?php

declare(strict_types=1);

require_once __DIR__ . '/helpers.php';

function upload_directory_path(string $subdirectory = ''): string
{
    $basePath = app_root('app/public/assets/uploads');

    if ($subdirectory === '') {
        return $basePath;
    }

    return $basePath . '/' . trim(str_replace('\\', '/', $subdirectory), '/');
}

function ensure_upload_directory(string $subdirectory = ''): string
{
    $path = upload_directory_path($subdirectory);

    if (!is_dir($path)) {
        mkdir($path, 0775, true);
    }

    return $path;
}

function upload_file(array $file, array $options = []): string
{
    $allowedMimeTypes = $options['allowed_mime_types'] ?? ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
    $allowedExtensions = $options['allowed_extensions'] ?? ['jpg', 'jpeg', 'png', 'webp', 'gif'];
    $maxSize = (int) ($options['max_size'] ?? 2 * 1024 * 1024);
    $directory = (string) ($options['directory'] ?? 'generic');

    if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
        throw new RuntimeException('File upload failed.');
    }

    if (($file['size'] ?? 0) <= 0 || (int) $file['size'] > $maxSize) {
        throw new RuntimeException('Uploaded file exceeds the allowed size.');
    }

    $originalName = (string) ($file['name'] ?? '');
    $extension = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));

    if (!in_array($extension, $allowedExtensions, true)) {
        throw new RuntimeException('Uploaded file type is not allowed.');
    }

    $tmpName = (string) ($file['tmp_name'] ?? '');
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimeType = $finfo ? finfo_file($finfo, $tmpName) : false;
    if ($finfo) {
        finfo_close($finfo);
    }

    if (!is_string($mimeType) || !in_array($mimeType, $allowedMimeTypes, true)) {
        throw new RuntimeException('Uploaded file content is not allowed.');
    }

    ensure_upload_directory($directory);
    $safeName = bin2hex(random_bytes(16)) . '.' . $extension;
    $destinationPath = upload_directory_path($directory) . '/' . $safeName;

    if (!move_uploaded_file($tmpName, $destinationPath)) {
        throw new RuntimeException('Unable to move uploaded file.');
    }

    return 'app/public/assets/uploads/' . trim($directory, '/') . '/' . $safeName;
}

function delete_uploaded_file(?string $relativePath): void
{
    if ($relativePath === null || $relativePath === '') {
        return;
    }

    $fullPath = app_root($relativePath);

    if (is_file($fullPath)) {
        unlink($fullPath);
    }
}
