<?php
require_once __DIR__ . '/../app/bootstrap.php';

use App\Core\Auth;
use App\Core\Database;
use App\Core\Response;
use App\Core\Security;

Auth::requireLogin('public/login.php');
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !verify_csrf()) {
    Response::json(['ok' => false, 'message' => 'Invalid request.'], 419);
}
if (!Security::rateLimit('upload:' . Auth::id(), 30, 3600)) {
    Response::json(['ok' => false, 'message' => 'Upload limit reached. Try again later.'], 429);
}
if (empty($_FILES['file']) || !is_uploaded_file((string)($_FILES['file']['tmp_name'] ?? ''))) {
    Response::json(['ok' => false, 'message' => 'No uploaded file found.'], 422);
}

$file = $_FILES['file'];
$errorCode = (int)($file['error'] ?? UPLOAD_ERR_NO_FILE);
if ($errorCode !== UPLOAD_ERR_OK) {
    Response::json(['ok' => false, 'message' => 'The upload did not complete successfully.'], 422);
}
$size = (int)($file['size'] ?? 0);
if ($size < 1 || $size > MAX_UPLOAD_BYTES) {
    Response::json(['ok' => false, 'message' => 'File size must be between 1 byte and ' . number_format(MAX_UPLOAD_BYTES / 1048576, 1) . ' MB.'], 422);
}

$tmp = (string)$file['tmp_name'];
$mime = (new finfo(FILEINFO_MIME_TYPE))->file($tmp) ?: '';
$imageTypes = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
$originalName = Security::safeFilename((string)($file['name'] ?? 'file'));

if (isset($imageTypes[$mime])) {
    $imageInfo = @getimagesize($tmp);
    if (!$imageInfo || ($imageInfo['mime'] ?? '') !== $mime) {
        Response::json(['ok' => false, 'message' => 'The image file is invalid.'], 422);
    }
    $pixels = (int)$imageInfo[0] * (int)$imageInfo[1];
    if ($pixels < 1 || $pixels > MAX_IMAGE_PIXELS) {
        Response::json(['ok' => false, 'message' => 'The image dimensions are too large.'], 422);
    }

    $relativeDirectory = 'uploads/' . date('Y/m');
    $directory = ROOT_PATH . '/public/' . $relativeDirectory;
    if (!is_dir($directory) && !mkdir($directory, 0755, true)) {
        Response::json(['ok' => false, 'message' => 'Upload directory is not writable.'], 500);
    }
    $name = bin2hex(random_bytes(16)) . '.' . $imageTypes[$mime];
    $path = $directory . '/' . $name;
    if (!move_uploaded_file($tmp, $path)) {
        Response::json(['ok' => false, 'message' => 'Could not save uploaded image.'], 500);
    }
    @chmod($path, 0644);
    $relative = $relativeDirectory . '/' . $name;
    Database::safeExecute(
        'INSERT INTO media_files (disk,file_name,file_path,mime_type,file_size,uploaded_by,created_at) VALUES ("public",?,?,?,?,?,NOW())',
        [$originalName, $relative, $mime, $size, Auth::id()]
    );
    Response::json(['ok' => true, 'path' => $relative, 'url' => asset($relative), 'message' => 'Image uploaded.']);
}

if ($mime === 'application/pdf') {
    if (!in_array((string)Auth::role(), ['admin', 'staff', 'vendor', 'affiliate'], true)) {
        Response::json(['ok' => false, 'message' => 'Your account cannot upload private documents.'], 403);
    }
    $header = (string)file_get_contents($tmp, false, null, 0, 5);
    if ($header !== '%PDF-') {
        Response::json(['ok' => false, 'message' => 'The PDF file is invalid.'], 422);
    }
    $directory = ROOT_PATH . '/storage/private_uploads/' . date('Y/m');
    if (!is_dir($directory) && !mkdir($directory, 0750, true)) {
        Response::json(['ok' => false, 'message' => 'Private upload directory is not writable.'], 500);
    }
    $name = bin2hex(random_bytes(20)) . '.pdf';
    $path = $directory . '/' . $name;
    if (!move_uploaded_file($tmp, $path)) {
        Response::json(['ok' => false, 'message' => 'Could not save uploaded document.'], 500);
    }
    @chmod($path, 0640);
    $relative = date('Y/m') . '/' . $name;
    Database::execute(
        'INSERT INTO media_files (disk,file_name,file_path,mime_type,file_size,uploaded_by,created_at) VALUES ("private",?,?,?,?,?,NOW())',
        [$originalName, $relative, $mime, $size, Auth::id()]
    );
    $mediaId = Database::lastInsertId();
    Response::json([
        'ok' => true,
        'media_id' => $mediaId,
        'path' => 'private:' . $mediaId,
        'url' => url('api/media.php?id=' . $mediaId),
        'message' => 'Private document uploaded.',
    ]);
}

Response::json(['ok' => false, 'message' => 'Only JPG, PNG, WEBP and PDF files are allowed.'], 422);
