<?php
/**
 * TraderAlign — Email Verification Page
 * Handles email verification via token from sign-up or resend
 */

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../src/ScopedDb.php';
require_once __DIR__ . '/../src/Auth.php';

// Start session for flash messages
if (session_status() === PHP_SESSION_NONE) {
    session_name(SESSION_NAME);
    session_start();
}

// Database connection
try {
    $dsn = "mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=utf8mb4";
    $pdo = new PDO($dsn, DB_USER, DB_PASS, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]);
} catch (PDOException $e) {
    error_log("Database connection failed in verify: " . $e->getMessage());
    $_SESSION['verify_error'] = 'System error. Please try again later.';
    header('Location: ' . APP_URL . '/dashboard');
    exit;
}

// Normally reached via the router, which already constructs $auth — but
// this file can also be hit directly, so fall back to building our own.
if (!isset($auth) || !($auth instanceof Auth)) {
    $auth = new Auth($pdo);
}

// Get and validate token
$token = trim($_GET['token'] ?? '');

if (empty($token) || strlen($token) !== 36) {
    $_SESSION['verify_error'] = 'Invalid verification link.';
    header('Location: ' . APP_URL . '/dashboard');
    exit;
}

try {
    // Find user with this verification token
    $stmt = $pdo->prepare(
        'SELECT id, email, email_verified_at 
         FROM users 
         WHERE verification_token = :token 
         AND deleted_at IS NULL 
         LIMIT 1'
    );
    $stmt->execute([':token' => $token]);
    $user = $stmt->fetch();

    if (!$user) {
        $_SESSION['verify_error'] = 'Invalid or expired verification link. Please request a new one.';
        header('Location: ' . APP_URL . '/dashboard');
        exit;
    }

    // Check if already verified
    if ($user['email_verified_at'] !== null) {
        $_SESSION['verify_success'] = 'Your email is already verified!';
        header('Location: ' . APP_URL . '/dashboard');
        exit;
    }

    // Mark email as verified and clear token
    $stmt = $pdo->prepare(
        'UPDATE users 
         SET email_verified_at = NOW(), 
             verification_token = NULL 
         WHERE id = :uid 
         AND verification_token = :token'
    );
    $stmt->execute([':uid' => $user['id'], ':token' => $token]);

    if ($stmt->rowCount() > 0) {
        // Log successful verification (a historical "this happened" record,
        // not a usable credential — safe to keep even outside dev, though
        // logs/ is now blocked at the web-server level regardless).
        $logDir = __DIR__ . '/../logs';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }

        $logEntry = sprintf(
            "[%s] VERIFIED - User ID: %s | Email: %s | IP: %s\n",
            date('Y-m-d H:i:s'),
            $user['id'],
            $user['email'],
            $_SERVER['REMOTE_ADDR'] ?? 'unknown'
        );
        file_put_contents($logDir . '/verification.log', $logEntry, FILE_APPEND | LOCK_EX);

        // Log the user in if not already logged in — routed through Auth's
        // own session-start path (session_regenerate_id) rather than
        // assigning $_SESSION directly, so this auto-login can't be used
        // for session fixation. Unrelated to, and not affected by, the
        // 2026-08-19 removal of auto-login from Auth::signUp() (see that
        // method's own comment) — a verification token is a real,
        // unguessable proof the requester controls the claimed inbox, not
        // a client-supplied value an attacker could probe for account
        // existence with, so auto-login here was never part of that
        // enumeration finding and stays exactly as it was.
        if (!$auth->isLoggedIn()) {
            $auth->loginUser($user['id'], $user['email']);
        }

        $_SESSION['verify_success'] = 'Email verified successfully! Welcome to TraderAlign.';

        // 2026-08-19 (finding M-3 follow-up): since Auth::signUp() no
        // longer auto-logs in and redirects to /onboarding, THIS is now
        // one of the two real places (alongside api/auth/sign-in.php's
        // identical check) a first-time user actually reaches an
        // authenticated session — send them to /onboarding instead of
        // /dashboard exactly once, the same as a first real sign-in
        // would. Every other outcome in this file (already verified,
        // invalid/expired token, system error) redirects to /dashboard
        // unchanged, which already self-resolves to /sign-in via
        // requireAuth() for a visitor who isn't authenticated.
        $onboardingComplete = true;
        try {
            $obStmt = $pdo->prepare('SELECT onboarding_complete FROM user_profiles WHERE user_id = :uid LIMIT 1');
            $obStmt->execute([':uid' => $user['id']]);
            $obRow = $obStmt->fetch();
            $onboardingComplete = $obRow === false || (bool)($obRow['onboarding_complete'] ?? false);
        } catch (PDOException $e) {
            error_log('verify.php: onboarding_complete check failed: ' . $e->getMessage());
        }
        header('Location: ' . APP_URL . ($onboardingComplete ? '/dashboard' : '/onboarding'));
        exit;
    } else {
        $_SESSION['verify_error'] = 'Verification failed. Please try again.';
    }

} catch (PDOException $e) {
    error_log("Email verification failed: " . $e->getMessage());
    $_SESSION['verify_error'] = 'System error. Please try again later.';
}

header('Location: ' . APP_URL . '/dashboard');
exit;