<?php
declare(strict_types=1);

/**
 * /functional/files/file_delete.php
 * Видаляє файл:
 * - видаляє фізично (лише всередині /upload)
 * - видаляє запис з myfiles (лише власник)
 *
 * Вимоги:
 * - тільки POST
 * - CSRF
 *
 * SEO: службовий endpoint => noindex
 */

/*
  ВАЖЛИВО:
  /functional/files/* => до кореня сайту треба піднятися на 2 рівні:
  files -> functional -> ROOT
*/
require_once dirname(__DIR__, 2) . '/includes/start.php';

/** @var PDO|null $pdo */
/** @var array|null $me */
$pdo = (isset($pdo) && $pdo instanceof PDO) ? $pdo : db();
$me  = $me ?? current_user();

/* SEO / robots */
if (!headers_sent()) {
    header('X-Robots-Tag: noindex, nofollow, noarchive, nosnippet', true);
    header('X-Content-Type-Options: nosniff', true);
    header('Referrer-Policy: same-origin', true);
    header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true);
    header('Pragma: no-cache', true);
    header('Expires: 0', true);
}

if (!function_exists('redirect')) {
    function redirect(string $to): void {
        header('Location: ' . $to, true, 303);
        exit;
    }
}
if (!function_exists('is_post')) {
    function is_post(): bool {
        return (string)($_SERVER['REQUEST_METHOD'] ?? '') === 'POST';
    }
}
if (!function_exists('csrf_check')) {
    function csrf_check(?string $t): bool {
        return !empty($t) && !empty($_SESSION['csrf']) && hash_equals((string)$_SESSION['csrf'], (string)$t);
    }
}

/* flash compatible with includes/header.php */
if (!function_exists('mf_flash_set')) {
    function mf_flash_set(string $k, string $v): void {
        if (!isset($_SESSION)) return;
        if (!isset($_SESSION['_flash']) || !is_array($_SESSION['_flash'])) $_SESSION['_flash'] = [];
        $_SESSION['_flash'][$k] = $v;
    }
}

/* login required */
if (!$me || (int)($me['id'] ?? 0) <= 0) {
    redirect('/login.php');
}

/* не POST — назад */
if (!is_post()) {
    redirect('/functional/files/');
}

/* CSRF */
if (!csrf_check((string)($_POST['csrf'] ?? ''))) {
    mf_flash_set('err', 'CSRF error');
    redirect('/functional/files/');
}

$id = (int)($_POST['id'] ?? 0);
$backFolder = (int)($_POST['back_folder'] ?? 0);
if ($backFolder < 0) $backFolder = 0;

$back = '/functional/files/' . ($backFolder > 0 ? ('?folder=' . $backFolder) : '');

if ($id <= 0) {
    mf_flash_set('err', 'Bad id');
    redirect($back);
}

/* Витягаємо rel_path тільки для власника */
$st = $pdo->prepare("SELECT rel_path FROM myfiles WHERE id=? AND user_id=? LIMIT 1");
$st->execute([$id, (int)$me['id']]);
$rel = (string)($st->fetchColumn() ?: '');

if ($rel === '') {
    mf_flash_set('err', 'File not found');
    redirect($back);
}

/* Корінь проєкту та /upload */
$root = realpath(dirname(__DIR__, 2));
if ($root === false) $root = dirname(__DIR__, 2);

$uploadsRoot = realpath($root . '/upload');
if ($uploadsRoot === false) {
    mf_flash_set('err', 'Uploads root missing');
    redirect($back);
}

/* Нормалізація rel_path */
$rel = str_replace(["\\", "\0"], ['/', ''], $rel);
$rel = preg_replace('~[\r\n]~', '', $rel);
$rel = preg_replace('~\.\.+~', '', $rel);
$rel = ltrim($rel, '/');

/* Додатково: файл має бути саме всередині upload/ */
if ($rel === '' || !str_starts_with($rel, 'upload/')) {
    // все одно видаляємо запис (якщо він “битий”), але фізично нічого не чіпаємо
    $del = $pdo->prepare("DELETE FROM myfiles WHERE id=? AND user_id=? LIMIT 1");
    $del->execute([$id, (int)$me['id']]);

    mf_flash_set('ok', 'Deleted');
    redirect($back);
}

$abs = realpath($root . '/' . $rel);

/* Перевірка що $abs реально всередині /upload (з захистом від prefix-bypass) */
$uploadsRootNorm = rtrim($uploadsRoot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

$didUnlink = false;
if ($abs !== false && is_file($abs)) {
    $absNorm = rtrim($abs, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

    if (strpos($absNorm, $uploadsRootNorm) === 0) {
        $didUnlink = @unlink($abs);
        // якщо не видалилось (права/lock) — не падаємо, але все одно видалимо запис з БД
    }
}

/* Прибираємо порожні директорії вгору (до /upload, але не чіпаємо сам /upload) */
if ($didUnlink && $abs !== false) {
    $dir = dirname($abs);

    while ($dir && is_dir($dir)) {
        $dirNorm = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

        // стоп якщо вийшли за upload або дійшли до самого /upload
        if (strpos($dirNorm, $uploadsRootNorm) !== 0) break;
        if (rtrim($dirNorm, DIRECTORY_SEPARATOR) === rtrim($uploadsRootNorm, DIRECTORY_SEPARATOR)) break;

        $items = @scandir($dir);
        if (!is_array($items)) break;

        $items = array_values(array_diff($items, ['.', '..']));
        if (count($items) > 0) break;

        @rmdir($dir);
        $dir = dirname($dir);
    }
}

/* Видаляємо запис з БД */
$st = $pdo->prepare("DELETE FROM myfiles WHERE id=? AND user_id=? LIMIT 1");
$st->execute([$id, (int)$me['id']]);

mf_flash_set('ok', 'Deleted');
redirect($back);