<?php
set_time_limit(600); // 10 минут

$uploadDir = rtrim(__DIR__ . DIRECTORY_SEPARATOR . "uploads" . DIRECTORY_SEPARATOR, "\\/");
$logFile = __DIR__ . DIRECTORY_SEPARATOR . "transcription_log.txt";
$whisperPath = "C:\\Users\\Evgen\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\whisper.exe";

$error = null;
$transcript = null;
$debugInfo = [];

function logMessage(string $message) {
    global $logFile;
    file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] " . $message . "\n", FILE_APPEND);
}

function phpFileUploadErrorMessage(int $code): string {
    $errors = [
        UPLOAD_ERR_OK => 'Ошибок нет',
        UPLOAD_ERR_INI_SIZE => 'Превышен размер файла, указанный в php.ini',
        UPLOAD_ERR_FORM_SIZE => 'Превышен размер файла, указанный в HTML-форме',
        UPLOAD_ERR_PARTIAL => 'Файл был загружен только частично',
        UPLOAD_ERR_NO_FILE => 'Файл не был загружен',
        UPLOAD_ERR_NO_TMP_DIR => 'Отсутствует временная папка',
        UPLOAD_ERR_CANT_WRITE => 'Не удалось записать файл на диск',
        UPLOAD_ERR_EXTENSION => 'Загрузка файла остановлена расширением',
    ];
    return $errors[$code] ?? 'Неизвестная ошибка загрузки файла';
}

if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_FILES["file"])) {

    $file = $_FILES["file"];

    // Проверка ошибки загрузки файла с расшифровкой кода
    if ($file["error"] !== UPLOAD_ERR_OK) {
        $error = "Ошибка загрузки файла: " . phpFileUploadErrorMessage($file["error"]);
        logMessage("Upload error code {$file["error"]}: $error");
    }
    // Проверяем размер
    elseif ($file["size"] > 10 * 1024 * 1024) {
        $error = "Файл больше 10 МБ";
        logMessage("File too large: {$file["size"]} bytes");
    }
    else {
        // Проверка mime-типа с помощью FileInfo (более надежно)
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_file($finfo, $file["tmp_name"]);
        finfo_close($finfo);

        $allowedMimeTypes = [
            'audio/mpeg',    // mp3
            'audio/wav',     // wav
            'audio/ogg',     // ogg
            'audio/x-flac',  // flac (часто встречается так)
            'audio/flac'
        ];

        if (!in_array($mimeType, $allowedMimeTypes, true)) {
            $error = "Недопустимый MIME-тип файла: $mimeType";
            logMessage("Invalid MIME type: $mimeType");
        }

        // Проверка расширения
        $ext = strtolower(pathinfo($file["name"], PATHINFO_EXTENSION));
        $allowedExt = ["mp3", "wav", "ogg", "flac"];
        if (!in_array($ext, $allowedExt, true)) {
            if (!$error) $error = "Недопустимое расширение файла. Разрешены: " . implode(", ", $allowedExt);
            logMessage("Invalid extension: $ext");
        }
    }

    if (!$error) {
        // Проверка, существует ли whisper.exe и доступен ли он
        if (!file_exists($whisperPath) || !is_executable($whisperPath)) {
            $error = "Не найден или не исполняемый файл whisper по пути: $whisperPath";
            logMessage("Whisper executable not found or not executable: $whisperPath");
        }
    }

    if (!$error) {
        // Создаем директорию, если нет
        if (!is_dir($uploadDir)) {
            if (!mkdir($uploadDir, 0777, true)) {
                $error = "Не удалось создать директорию для загрузок: $uploadDir";
                logMessage($error);
            } else {
                logMessage("Создана директория $uploadDir");
            }
        }
    }

    if (!$error) {
        // Уникальное имя файла
        $taskId = uniqid('task_', true);
        $audioPath = $uploadDir . $taskId . "." . $ext;

        // Перемещаем файл
        if (!move_uploaded_file($file["tmp_name"], $audioPath)) {
            $error = "Не удалось сохранить загруженный файл";
            logMessage("Failed to move uploaded file to $audioPath");
        } else {
            logMessage("Файл сохранён как: $audioPath");
        }
    }

    if (!$error) {
        $outputDir = $uploadDir;
        $txtFile = $outputDir . $taskId . ".txt";

        // Функция запуска процесса с подробным выводом stdout и stderr
        function runProcess(string $cmd, array &$stdout = null, array &$stderr = null, int &$exitCode = null) {
            $proc = proc_open(
                $cmd,
                [
                    1 => ['pipe', 'w'], // stdout
                    2 => ['pipe', 'w'], // stderr
                ],
                $pipes
            );
            $stdout = [];
            $stderr = [];
            if (!is_resource($proc)) {
                $exitCode = -1;
                return false;
            }

            while ($line = fgets($pipes[1])) {
                $stdout[] = rtrim($line, "\r\n");
            }
            while ($line = fgets($pipes[2])) {
                $stderr[] = rtrim($line, "\r\n");
            }

            fclose($pipes[1]);
            fclose($pipes[2]);

            $exitCode = proc_close($proc);

            return $exitCode === 0;
        }

        // Формируем команду
        $command = "\"$whisperPath\" --model large --language ru--language ru --output_dir \"$outputDir\" \"$audioPath\"";
        logMessage("Запуск команды транскрипции: $command");

        $startTime = microtime(true);

        $stdout = $stderr = [];
        $processSuccess = runProcess($command, $stdout, $stderr, $returnCode);

        $endTime = microtime(true);
        $duration = round($endTime - $startTime, 2);

        logMessage("Команда завершена с кодом $returnCode. Время: {$duration}сек");
        if ($stdout) logMessage("STDOUT:\n" . implode("\n", $stdout));
        if ($stderr) logMessage("STDERR:\n" . implode("\n", $stderr));

        // Удаляем аудиофайл
        if (file_exists($audioPath)) {
            unlink($audioPath);
            logMessage("Удалён аудиофайл $audioPath");
        }

        if (!$processSuccess) {
            $error = "Ошибка при транскрипции аудио. Код возврата: $returnCode.";
            if ($stderr) {
                $error .= " Подробности: " . implode(" ", $stderr);
            }
            logMessage("Ошибка транскрипции: $error");
        } elseif (!file_exists($txtFile)) {
            $error = "Файл с транскриптом ($txtFile) не найден после выполнения команды.";
            logMessage($error);
        } else {
            // Успешно
            $transcript = file_get_contents($txtFile);
            unlink($txtFile);
            logMessage("Транскрипция успешно получена, удалён файл $txtFile");
            $logEntry = sprintf("[%s] Задача: %s | Время транскрипции: %s сек\nРезультат:\n%s\n\n",
                date('Y-m-d H:i:s'), $taskId, $duration, $transcript);
            file_put_contents($logFile, $logEntry, FILE_APPEND);
        }
    }
}
?>

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8" />
    <title>Whisper — Транскрипция аудио</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 650px; margin: 40px auto; padding: 10px; }
        .error { color: red; white-space: pre-wrap; background: #fee; padding: 10px; border: 1px solid #faa; }
        .transcript { white-space: pre-wrap; background: #f5f5f5; border: 1px solid #ccc; padding: 15px; margin-top: 20px; }
        form { margin-bottom: 20px; }
        label { display: block; margin-bottom: 8px; font-weight: bold; }
        input[type="file"] { margin-bottom: 15px; }
        button { padding: 8px 16px; font-size: 16px; cursor: pointer; }
        .debug { margin-top: 30px; font-size: 12px; color: #666; background: #f0f0f0; padding: 10px; border: 1px solid #ccc; white-space: pre-wrap; }
    </style>
</head>
<body>

<h1>Whisper — Транскрипция аудио</h1>

<form action="" method="post" enctype="multipart/form-data" novalidate>
    <label for="file">Выберите аудиофайл (до 10 МБ):</label>
    <input type="file" name="file" id="file" accept=".mp3,.wav,.ogg,.flac" required>
    <button type="submit">Транскрибировать</button>
</form>

<?php if ($error): ?>
    <div class="error">Ошибка: <?= htmlspecialchars($error) ?></div>
<?php elseif ($transcript !== null): ?>
    <h2>Результат транскрипции:</h2>
    <div class="transcript"><?= nl2br(htmlspecialchars($transcript)) ?></div>
<?php endif; ?>

</body>
</html> перепиши на питон api. на бекенде на фронте используй ajax html и bootsrap. php не эффективен в этом решении.