<?php
declare(strict_types=1);

/**
 * /admin/users/activate.php
 * Адмін: вручну активувати користувача.
 *
 * Підтримує схеми з:
 * - is_active / active / verified / email_verified (та інші варіанти)
 * - activation_token_hash (або інший token-стовпець)
 * - якщо є activated_at / verified_at / email_verified_at — заповнює.
 *
 * ОНОВЛЕНО:
 * - SEO: X-Robots-Tag noindex (адмінка)
 * - safe backUrl: бере back з POST (пріоритет) або referer, але тільки /admin/users/ або /admin/users.php
 * - 303 redirect
 * - без leak $e->getMessage() у flash
 * - “user not found” / “already active”
 * - UPDATE тільки якщо ще не активний
 */

require_once __DIR__ . '/../../includes/start.php';
require_role(['admin']);

require_once __DIR__ . '/../_helpers.php';
require_once __DIR__ . '/../_csrf.php';

$pdo = db();

/* =========================
   SEO: адмінка НЕ індексується
========================= */
if (!headers_sent()) {
    header('X-Robots-Tag: noindex, nofollow, noarchive, nosnippet', true);
}

/* =========================
   Safe back URL
========================= */
if (!function_exists('admin_norm_local_url')) {
    function admin_norm_local_url(string $raw): string {
        $raw = trim($raw);
        if ($raw === '') return '';

        // якщо абсолютний URL — лишаємо тільки path+query
        if (preg_match('~^https?://~i', $raw)) {
            $p = parse_url($raw);
            $path = (string)($p['path'] ?? '');
            $q = isset($p['query']) && (string)$p['query'] !== '' ? ('?' . (string)$p['query']) : '';
            $raw = $path . $q;
        }

        if ($raw === '' || $raw[0] !== '/') return '';
        if (str_starts_with($raw, '//')) return '';

        return $raw;
    }
}

function admin_users_back_url(): string {
    $default = '/admin/users/';

    // 1) back з POST
    $postBack = admin_norm_local_url((string)($_POST['back'] ?? ''));
    if ($postBack !== '') {
        $path = (string)parse_url($postBack, PHP_URL_PATH);
        if ($path === '/admin/users/' || $path === '/admin/users.php') return $postBack;
    }

    // 2) referer fallback
    $ref = admin_norm_local_url((string)($_SERVER['HTTP_REFERER'] ?? ''));
    if ($ref !== '') {
        $path = (string)parse_url($ref, PHP_URL_PATH);
        if ($path === '/admin/users/' || $path === '/admin/users.php') return $ref;
    }

    return $default;
}
$backUrl = admin_users_back_url();

/* =========================
   Method + CSRF
========================= */
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
    http_response_code(405);
    exit('Method Not Allowed');
}

if (!admin_csrf_verify()) {
    admin_flash_set('danger', admin_tt('csrf_bad', 'CSRF помилка', 'CSRF ошибка', 'CSRF error'));
    header('Location: ' . $backUrl, true, 303);
    exit;
}

$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
    admin_flash_set('danger', admin_tt('admin_bad_id', 'Невірний ID', 'Неверный ID', 'Bad ID'));
    header('Location: ' . $backUrl, true, 303);
    exit;
}

/* =========================
   Detect columns
========================= */
$activeCol = null;
$tokenCol  = null;

if (function_exists('admin_user_activation_fields')) {
    $fields = (array)admin_user_activation_fields($pdo);
    $activeCol = $fields['active_col'] ?? null;
    $tokenCol  = $fields['token_col'] ?? null;
}

// fallback: активність
if (!$activeCol) {
    foreach (['is_active','active','verified','email_verified','is_verified'] as $c) {
        if (function_exists('admin_column_exists') && admin_column_exists($pdo, 'users', $c)) {
            $activeCol = $c;
            break;
        }
    }
}

// fallback: токен
if (!$tokenCol) {
    foreach (['activation_token_hash','activation_token','verify_token','verification_token','email_token','token'] as $c) {
        if (function_exists('admin_column_exists') && admin_column_exists($pdo, 'users', $c)) {
            $tokenCol = $c;
            break;
        }
    }
}

// дата активації
$activatedAtCol = null;
foreach (['activated_at','verified_at','email_verified_at'] as $c) {
    if (function_exists('admin_column_exists') && admin_column_exists($pdo, 'users', $c)) {
        $activatedAtCol = $c;
        break;
    }
}

if (!$activeCol) {
    admin_flash_set('warning', admin_tt('admin_no_active_col', 'Немає колонки активності у users', 'Нет колонки активности в users', 'No active column in users'));
    header('Location: ' . $backUrl, true, 303);
    exit;
}

/* =========================
   Activate
========================= */
try {
    // 1) перевіряємо чи користувач існує і чи вже активний
    $st = $pdo->prepare("SELECT `$activeCol` FROM users WHERE id=? LIMIT 1");
    $st->execute([$id]);
    $cur = $st->fetch(PDO::FETCH_ASSOC);

    if (!$cur) {
        admin_flash_set('danger', admin_tt('user_nf', 'Користувача не знайдено', 'Пользователь не найден', 'User not found'));
        header('Location: ' . $backUrl, true, 303);
        exit;
    }

    $isActive = (int)($cur[$activeCol] ?? 0) === 1;
    if ($isActive) {
        admin_flash_set('success', admin_tt('already_active', 'Вже активований', 'Уже активирован', 'Already active'));
        header('Location: ' . $backUrl, true, 303);
        exit;
    }

    // 2) активуємо тільки якщо ще не активний
    $set = ["`$activeCol`=1"];
    if ($tokenCol) $set[] = "`$tokenCol`=NULL";
    if ($activatedAtCol) $set[] = "`$activatedAtCol`=NOW()";

    $sql = 'UPDATE users SET ' . implode(', ', $set)
         . " WHERE id=? AND (`$activeCol` IS NULL OR `$activeCol`=0) LIMIT 1";

    $up = $pdo->prepare($sql);
    $up->execute([$id]);

    if ($up->rowCount() > 0) {
        admin_flash_set('success', admin_tt('admin_activated', 'Користувача активовано', 'Пользователь активирован', 'User activated'));
    } else {
        // race / вже встиг активуватись
        admin_flash_set('success', admin_tt('already_active', 'Вже активований', 'Уже активирован', 'Already active'));
    }
} catch (Throwable $e) {
    admin_flash_set('danger', admin_tt('admin_save_error', 'Помилка збереження', 'Ошибка сохранения', 'Save error'));
}

header('Location: ' . $backUrl, true, 303);
exit;