<?php
declare(strict_types=1);

/**
 * /functional/files/file_toggle.php
 * Перемикає is_public (відкрито/закрито).
 *
 * Вимоги:
 * - тільки 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);
}

/* Дістаємо поточний стан */
$st = $pdo->prepare("SELECT id, is_public, share_token FROM myfiles WHERE id=? AND user_id=? LIMIT 1");
$st->execute([$id, (int)$me['id']]);
$row = $st->fetch(PDO::FETCH_ASSOC);

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

$new = ((int)($row['is_public'] ?? 0) === 1) ? 0 : 1;

/* Якщо робимо public — переконайся, що є валідний токен */
$token = (string)($row['share_token'] ?? '');
$needToken = ($new === 1) && !preg_match('~^[a-f0-9]{64}$~', $token);
if ($needToken) {
    $token = bin2hex(random_bytes(32));
}

/* UPDATE (з fallback якщо немає updated_at) */
try {
    if ($needToken) {
        $st = $pdo->prepare("UPDATE myfiles SET is_public=?, share_token=?, updated_at=NOW() WHERE id=? AND user_id=? LIMIT 1");
        $st->execute([$new, $token, $id, (int)$me['id']]);
    } else {
        $st = $pdo->prepare("UPDATE myfiles SET is_public=?, updated_at=NOW() WHERE id=? AND user_id=? LIMIT 1");
        $st->execute([$new, $id, (int)$me['id']]);
    }
} catch (Throwable $e) {
    // fallback: якщо updated_at відсутній у таблиці
    if ($needToken) {
        $st = $pdo->prepare("UPDATE myfiles SET is_public=?, share_token=? WHERE id=? AND user_id=? LIMIT 1");
        $st->execute([$new, $token, $id, (int)$me['id']]);
    } else {
        $st = $pdo->prepare("UPDATE myfiles SET is_public=? WHERE id=? AND user_id=? LIMIT 1");
        $st->execute([$new, $id, (int)$me['id']]);
    }
}

mf_flash_set('ok', $new ? 'Access: public' : 'Access: private');
redirect($back);