<?php
declare(strict_types=1);

/**
 * /functional/video/upload.php
 * Завантаження відео:
 * - quota 10GB/user
 * - max 500MB/file
 * - зберігаємо в /upload/<username>/video (директорія закрита .htaccess)
 * - пишемо запис в myvideos (size_bytes для швидкого підрахунку квоти)
 */

require_once __DIR__ . '/../../includes/start.php';

$pdo = db();
$me  = current_user();

require_once __DIR__ . '/_lib.php';

require_login();
mv_private_seo_headers();

if (!headers_sent()) {
  header('X-Content-Type-Options: nosniff', true);
}

$GLOBALS['mv_lang'] = mv_detect_lang($me);
$lang = (string)$GLOBALS['mv_lang'];

if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
  redirect('/functional/video/');
}

if (!csrf_check((string)($_POST['csrf'] ?? ''))) {
  flash_set('err', mv_t('err_csrf', $lang));
  redirect('/functional/video/');
}

$titles = $_POST['title'] ?? [];
$files  = $_FILES['video'] ?? null;

if (!is_array($titles) || !is_array($files) || !isset($files['name']) || !is_array($files['name'])) {
  flash_set('err', mv_t('err_file', $lang));
  redirect('/functional/video/');
}

/* normalize items */
$count = count($files['name']);
$items = [];

for ($i = 0; $i < $count; $i++) {
  $name = (string)($files['name'][$i] ?? '');
  $tmp  = (string)($files['tmp_name'][$i] ?? '');
  $err  = (int)($files['error'][$i] ?? UPLOAD_ERR_NO_FILE);
  $size = (int)($files['size'][$i] ?? 0);

  $title = trim((string)($titles[$i] ?? ''));

  // пропускаємо повністю порожні рядки
  if ($name === '' && $tmp === '' && $size === 0) {
    continue;
  }

  if ($title === '') {
    flash_set('err', mv_t('err_title', $lang));
    redirect('/functional/video/');
  }

  if ($err !== UPLOAD_ERR_OK || $tmp === '' || !is_uploaded_file($tmp)) {
    flash_set('err', mv_t('err_file', $lang));
    redirect('/functional/video/');
  }

  if ($size <= 0) {
    flash_set('err', mv_t('err_file', $lang));
    redirect('/functional/video/');
  }

  if ($size > MV_MAX_FILE_BYTES) {
    flash_set('err', mv_t('err_size', $lang));
    redirect('/functional/video/');
  }

  $ext = mv_ext_from_name($name);
  if ($ext === '') $ext = 'mp4';

  $items[] = [
    'title' => mv_mb_substr($title, 0, 190),
    'orig'  => mv_mb_substr($name, 0, 255),
    'tmp'   => $tmp,
    'size'  => $size,
    'ext'   => $ext,
  ];
}

if (!$items) {
  flash_set('err', mv_t('err_file', $lang));
  redirect('/functional/video/');
}

/* ensure dir (і як fallback для квоти по FS) */
[$fsDir, $webDir, $safeU] = mv_ensure_video_dir((string)($me['username'] ?? 'user'));

/* check quota */
$usedBytes = mv_user_used_bytes($pdo, (int)($me['id'] ?? 0), $fsDir);

$totalIncoming = 0;
foreach ($items as $it) {
  $totalIncoming += (int)$it['size'];
}

if (!mv_can_fit_quota($usedBytes, $totalIncoming)) {
  flash_set('err', mv_t('err_quota', $lang));
  redirect('/functional/video/');
}

/* check mime/ext */
foreach ($items as &$it) {
  $mime = mv_guess_mime((string)$it['tmp'], 'application/octet-stream');
  $ext  = strtolower(trim((string)$it['ext']));

  if (!mv_is_allowed_video($ext, $mime)) {
    flash_set('err', mv_t('err_type', $lang));
    redirect('/functional/video/');
  }

  // якщо ext дивний/порожній, але mime норм — підберемо мінімально
  $allowedExts = mv_allowed_video_exts();
  if (!in_array($ext, $allowedExts, true)) {
    if ($mime === 'video/mp4') $ext = 'mp4';
    elseif ($mime === 'video/webm') $ext = 'webm';
    elseif ($mime === 'video/ogg') $ext = 'ogg';
    elseif ($mime === 'video/quicktime') $ext = 'mov';
    elseif ($mime === 'video/x-m4v') $ext = 'm4v';
    elseif ($mime === 'video/x-matroska') $ext = 'mkv';
    else $ext = 'mp4';
  }

  $it['mime'] = mv_mb_substr($mime, 0, 190);
  $it['ext']  = $ext;
}
unset($it);

/* move + insert */
$movedFiles = [];

$pdo->beginTransaction();
try {
  // на всяк випадок: таблиця/колонки
  if (!db_has_table($pdo, 'myvideos')) {
    throw new RuntimeException('DB table myvideos not found');
  }

  $stIns = $pdo->prepare("
    INSERT INTO myvideos (user_id, title, original_name, stored_name, rel_path, mime, size_bytes, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, NOW())
  ");

  foreach ($items as $it) {
    $stored = mv_make_stored_name((string)$it['ext']); // типу 20260304_123000_xxx.mp4
    $stored = mv_mb_substr($stored, 0, 255);

    $fsPath = rtrim($fsDir, '/') . '/' . $stored;
    $rel    = rtrim($webDir, '/') . '/' . $stored;

    if (!@move_uploaded_file((string)$it['tmp'], $fsPath)) {
      throw new RuntimeException('move_uploaded_file failed');
    }
    @chmod($fsPath, 0644);
    $movedFiles[] = $fsPath;

    $stIns->execute([
      (int)$me['id'],
      (string)$it['title'],
      (string)$it['orig'],
      (string)$stored,
      (string)$rel,
      (string)$it['mime'],
      (int)$it['size'],
    ]);
  }

  $pdo->commit();
  flash_set('ok', mv_t('ok_uploaded', $lang));
} catch (Throwable $e) {
  if ($pdo->inTransaction()) $pdo->rollBack();

  // best-effort cleanup
  foreach ($movedFiles as $p) {
    if (is_string($p) && $p !== '' && is_file($p) && mv_fs_is_safe($p)) {
      @unlink($p);
    }
  }

  flash_set('err', mv_t('err_file', $lang));
}

redirect('/functional/video/');