<?php
declare(strict_types=1);

/**
 * /activate.php
 * Активація акаунта по токену з листа.
 *
 * Підтримує різні схеми БД:
 * - active колонки: is_active / active / verified / email_verified / is_verified
 * - token колонки: activation_token_hash (sha256) або activation_token / verify_token / verification_token / email_token / token (raw)
 * - timestamp колонки: activated_at / verified_at / email_verified_at
 *
 * ОНОВЛЕНО:
 * - SEO: noindex + X-Robots-Tag
 * - $pdo гарантовано визначений
 * - не прив’язано жорстко до is_active та activation_token_hash
 * - UPDATE тільки якщо token співпав (захист від race)
 * - якщо вже активний — best-effort чистимо токен (щоб не можна було повторно) і можемо залогінити
 */

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

/* make sure $pdo exists */
if (!isset($pdo) || !($pdo instanceof PDO)) {
    $pdo = function_exists('db') ? db() : null;
}
if (!($pdo instanceof PDO)) {
    http_response_code(500);
    exit('DB error');
}

$title = function_exists('t') ? (string)t('activation_title') : 'Activate';

/* SEO: activation page should not be indexed */
$meta_robots = 'noindex, nofollow, noarchive, nosnippet';
$meta_desc   = '';
if (!headers_sent()) {
    header('X-Robots-Tag: noindex, nofollow, noarchive, nosnippet', true);
    header('Cache-Control: no-store', true);
}

/* helpers */
if (!function_exists('h')) {
    function h(?string $s): string { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('db_has_column')) {
    function db_has_column(PDO $pdo, string $table, string $col): bool {
        try {
            $st = $pdo->prepare('
                SELECT 1
                FROM information_schema.columns
                WHERE table_schema = DATABASE()
                  AND table_name = ?
                  AND column_name = ?
                LIMIT 1
            ');
            $st->execute([$table, $col]);
            return (bool)$st->fetchColumn();
        } catch (Throwable $e) {
            return false;
        }
    }
}
if (!function_exists('pick_first_existing_col')) {
    function pick_first_existing_col(PDO $pdo, string $table, array $candidates): ?string {
        foreach ($candidates as $c) {
            if (db_has_column($pdo, $table, (string)$c)) return (string)$c;
        }
        return null;
    }
}

/* detect columns */
$activeCol = pick_first_existing_col($pdo, 'users', ['is_active','active','verified','email_verified','is_verified']);
$tokenCol  = pick_first_existing_col($pdo, 'users', ['activation_token_hash','activation_token','verify_token','verification_token','email_token','token']);
$timeCol   = pick_first_existing_col($pdo, 'users', ['activated_at','verified_at','email_verified_at']);

$token = trim((string)($_GET['token'] ?? ''));

$ok = false;
$msg = '';

/* validations */
if ($token === '' || strlen($token) < 20) {
    $ok = false;
    $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
} elseif (!$tokenCol) {
    $ok = false;
    $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
} elseif (!$activeCol) {
    // немає колонки активності — краще не “вигадувати”
    $ok = false;
    $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
} else {
    $isHashCol = (bool)preg_match('~(_hash|hash)$~i', (string)$tokenCol);
    $lookupToken = $isHashCol ? hash('sha256', $token) : $token;

    try {
        // load user by token
        $sqlSel = "SELECT id, `$activeCol` AS active_val, `$tokenCol` AS token_val FROM users WHERE `$tokenCol`=? LIMIT 1";
        $st = $pdo->prepare($sqlSel);
        $st->execute([$lookupToken]);
        $u = $st->fetch(PDO::FETCH_ASSOC) ?: null;

        if (!$u) {
            $ok = false;
            $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
        } else {
            $uid = (int)($u['id'] ?? 0);
            $isActive = (int)($u['active_val'] ?? 0) === 1;

            if ($uid <= 0) {
                $ok = false;
                $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
            } else {
                // Будуємо SET
                $set = [];
                $params = [];

                // якщо ще не активний — активуємо
                if (!$isActive) {
                    $set[] = "`$activeCol`=1";
                }

                // токен гасимо завжди (best-effort)
                $set[] = "`$tokenCol`=NULL";

                if ($timeCol) {
                    // якщо вже активний — можна не чіпати дату, але простіше: ставимо NOW() тільки при неактивному
                    if (!$isActive) {
                        $set[] = "`$timeCol`=NOW()";
                    }
                }

                // UPDATE тільки якщо токен ще співпадає (захист від повторного використання/гонок)
                $sqlUp = "UPDATE users SET " . implode(', ', $set) . " WHERE id=? AND `$tokenCol`=? LIMIT 1";
                $params = [$uid, $lookupToken];

                $up = $pdo->prepare($sqlUp);
                $up->execute($params);

                // якщо rowCount == 0 і юзер вже активний — теж ок, значить токен вже згорів раніше
                if (!$isActive && $up->rowCount() <= 0) {
                    // не активували — токен вже не валідний (або вже використаний)
                    $ok = false;
                    $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
                } else {
                    // логін
                    if (function_exists('login_user')) {
                        login_user($uid);
                    }
                    $ok = true;
                    $msg = function_exists('t') ? (string)t('activation_ok') : 'Account activated.';
                }
            }
        }
    } catch (Throwable $e) {
        $ok = false;
        $msg = function_exists('t') ? (string)t('activation_bad') : 'Bad activation token.';
    }
}

require __DIR__ . '/includes/header.php';
?>

<div class="row justify-content-center">
  <div class="col-md-7 col-lg-6">
    <div class="card card-app p-4">
      <h1 class="h4 mb-2"><?= h(function_exists('t') ? (string)t('activation_mail_title') : 'Activation') ?></h1>

      <?php if ($ok): ?>
        <div class="alert alert-success mb-3"><?= h($msg) ?></div>
        <a class="btn btn-primary" href="/"><?= h(function_exists('t') ? (string)t('feed') : 'Feed') ?></a>
      <?php else: ?>
        <div class="alert alert-danger mb-3"><?= h($msg) ?></div>
        <a class="btn btn-outline-secondary" href="/login.php"><?= h(function_exists('t') ? (string)t('login') : 'Login') ?></a>
      <?php endif; ?>
    </div>
  </div>
</div>

<?php require __DIR__ . '/includes/footer.php'; ?>