<?php
declare(strict_types=1);

require_once __DIR__ . '/app.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: /');
    exit;
}

try {
    app_boot();
} catch (Throwable $e) {
    notify_redirect('/', 'danger', 'The converter is not ready yet. Please try again in a moment.');
}

if (request_exceeds_upload_limit()) {
    notify_redirect('/', 'warning', 'That upload is larger than the current ' . effective_upload_limit_mb() . ' MB limit. Please choose a smaller file.');
}

$toolKey = trim((string)($_POST['tool_key'] ?? 'webm_mp4'));
$catalog = tool_catalog();
if (!isset($catalog[$toolKey])) {
    notify_redirect('/', 'warning', 'Please choose a supported conversion tool.');
}

$tool = $catalog[$toolKey];
if (!empty($tool['requires_ffmpeg']) && !ffmpeg_is_available()) {
    notify_redirect('/', 'warning', 'FFmpeg is not available on the server yet, so this conversion tool is temporarily offline.');
}

$file = $_FILES['source_file'] ?? $_FILES['video_file'] ?? null;
if (!is_array($file)) {
    notify_redirect('/', 'warning', 'Please choose a file to convert.');
}

$errorCode = (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE);
if (in_array($errorCode, [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE], true)) {
    notify_redirect('/', 'warning', 'That upload is larger than the current ' . effective_upload_limit_mb() . ' MB limit. Please choose a smaller file.');
}

if ($errorCode !== UPLOAD_ERR_OK) {
    notify_redirect('/', 'danger', 'Upload failed. Please try another file.');
}

$originalName = (string) ($file['name'] ?? 'upload.bin');
$safeOriginalName = preg_replace('/[^A-Za-z0-9._-]/', '-', $originalName) ?: 'upload.bin';
$extension = file_extension($safeOriginalName);

if (!in_array($extension, $tool['input_extensions'], true)) {
    notify_redirect('/', 'warning', 'That file type is not supported for ' . $tool['label'] . '.');
}

$size = (int) ($file['size'] ?? 0);
if ($size < 1) {
    notify_redirect('/', 'warning', 'The selected file looks empty. Please upload a valid file.');
}

if ($size > effective_upload_limit_bytes()) {
    notify_redirect('/', 'warning', 'That upload is larger than the current ' . effective_upload_limit_mb() . ' MB limit. Please choose a smaller file.');
}

$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = strtolower((string) $finfo->file((string) $file['tmp_name']));
$allowedMimes = match ($toolKey) {
    'webm_mp4' => ['video/webm', 'application/octet-stream'],
    'social_mp4' => ['video/webm', 'video/mp4', 'application/mp4', 'video/quicktime', 'application/octet-stream'],
    'subtitle_convert' => ['text/plain', 'text/vtt', 'application/octet-stream', 'application/x-subrip'],
    default => ['application/octet-stream'],
};

if (!in_array($mime, $allowedMimes, true)) {
    notify_redirect('/', 'warning', 'The uploaded file does not match the expected file type for this converter.');
}

$targetFormat = 'mp4';
$presetKey = null;
$outputMime = $tool['output_mime'] !== '' ? $tool['output_mime'] : null;

if ($toolKey === 'social_mp4') {
    $presetKey = trim((string)($_POST['preset_key'] ?? ''));
    if ($presetKey === '' || preset_option($toolKey, $presetKey) === null) {
        notify_redirect('/', 'warning', 'Please choose a social export preset.');
    }
}

if ($toolKey === 'subtitle_convert') {
    $requestedTarget = strtolower(trim((string)($_POST['subtitle_target'] ?? '')));
    $allowedTargets = array_keys(subtitle_target_options());
    if (!in_array($requestedTarget, $allowedTargets, true)) {
        notify_redirect('/', 'warning', 'Please choose whether to export to SRT or VTT.');
    }
    if ($requestedTarget === $extension) {
        notify_redirect('/', 'warning', 'Please choose the opposite subtitle format so the file is actually converted.');
    }
    $targetFormat = $requestedTarget;
    $outputMime = $targetFormat === 'vtt' ? 'text/vtt' : 'application/x-subrip';
}

$publicId = bin2hex(random_bytes(16));
$inputPath = APP_UPLOAD_DIR . '/' . $publicId . '.' . $extension;
$outputPath = APP_OUTPUT_DIR . '/' . $publicId . '.' . $targetFormat;

if (!move_uploaded_file((string) $file['tmp_name'], $inputPath)) {
    notify_redirect('/', 'danger', 'We could not save the uploaded file. Please try again.');
}

$downloadName = build_download_name($originalName, $toolKey, $targetFormat, $presetKey);
$jobId = create_job_record($publicId, $originalName, $inputPath, $size, $toolKey, $extension, $targetFormat, $presetKey, $outputMime, $downloadName);

$result = match ($toolKey) {
    'webm_mp4' => convert_media_to_mp4($inputPath, $outputPath),
    'social_mp4' => convert_media_to_mp4($inputPath, $outputPath, (string) preset_option($toolKey, $presetKey)['filter']),
    'subtitle_convert' => convert_subtitle_file($inputPath, $outputPath, $extension, $targetFormat),
    default => ['success' => false, 'message' => 'Unsupported conversion request.'],
};

if (!empty($result['success']) && is_file($outputPath)) {
    mark_job_completed($jobId, $outputPath, (int) filesize($outputPath));
    notify_redirect('/job.php?id=' . urlencode($publicId), 'success', $tool['label'] . ' completed. Your download is ready.');
}

mark_job_failed($jobId, (string) ($result['message'] ?? 'Conversion failed.'));
notify_redirect('/job.php?id=' . urlencode($publicId), 'danger', $tool['label'] . ' failed. Check the job details for more information.');
