<?php
/**
 * Helper Functions
 * PHP User Registration - https://rskworld.in
 * Developer: Molla Samser | RSK World
 * Contact: help@rskworld.in | +91 93305 39277
 * Year: 2026
 */

function sanitize(string $input): string {
    return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}

function generateVerificationToken(): string {
    return bin2hex(random_bytes(32));
}

function getBaseUrl(): string {
    return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost') . rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/');
}

function sendVerificationEmail(string $email, string $name, string $token): bool {
    $verifyUrl = getBaseUrl() . '/verify.php?token=' . urlencode($token);
    $subject = 'Verify your email - PHP Registration (rskworld.in)';
    $message = "Hello {$name},\n\nPlease verify your email by clicking:\n{$verifyUrl}\n\nThis link expires in 24 hours.\n\n— RSK World (https://rskworld.in)";
    $headers = 'From: noreply@rskworld.in' . "\r\n" . 'Reply-To: help@rskworld.in' . "\r\n" . 'X-Mailer: PHP/' . phpversion();
    return @mail($email, $subject, $message, $headers);
}

function sendPasswordResetEmail(string $email, string $name, string $token): bool {
    $resetUrl = getBaseUrl() . '/reset-password.php?token=' . urlencode($token);
    $subject = 'Reset your password - PHP Registration (rskworld.in)';
    $message = "Hello {$name},\n\nReset your password by clicking:\n{$resetUrl}\n\nThis link expires in 1 hour. If you didn't request this, ignore this email.\n\n— RSK World (https://rskworld.in)";
    $headers = 'From: noreply@rskworld.in' . "\r\n" . 'Reply-To: help@rskworld.in' . "\r\n" . 'X-Mailer: PHP/' . phpversion();
    return @mail($email, $subject, $message, $headers);
}

function setFlash(string $key, string $message): void {
    $_SESSION['flash'][$key] = $message;
}

function getFlash(string $key): ?string {
    $msg = $_SESSION['flash'][$key] ?? null;
    unset($_SESSION['flash'][$key]);
    return $msg;
}

/**
 * Log a failed login attempt (email, IP). Creates failed_login_attempts table if missing.
 */
function logFailedLogin(string $email, ?string $ip = null): void {
    try {
        $pdo = getDbConnection();
        $pdo->prepare('INSERT INTO failed_login_attempts (email, ip_address) VALUES (?, ?)')->execute([$email, $ip]);
    } catch (PDOException $e) {
        if ($e->getCode() === '42S02') {
            $pdo->exec("CREATE TABLE IF NOT EXISTS failed_login_attempts (
                id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                email VARCHAR(255) NOT NULL,
                ip_address VARCHAR(45) NULL,
                attempted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_email (email),
                INDEX idx_attempted (attempted_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
            $pdo->prepare('INSERT INTO failed_login_attempts (email, ip_address) VALUES (?, ?)')->execute([$email, $ip]);
        }
    }
}

/**
 * Log an admin action (set_role, suspend, unsuspend, verify_user). Creates admin_activity_log if missing.
 */
function logAdminActivity(int $adminUserId, string $action, ?int $targetUserId = null, ?string $details = null): void {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? null;
    if (is_string($ip) && strpos($ip, ',') !== false) $ip = trim(explode(',', $ip)[0]);
    try {
        $pdo = getDbConnection();
        $pdo->prepare('INSERT INTO admin_activity_log (admin_user_id, action, target_user_id, details, ip_address) VALUES (?, ?, ?, ?, ?)')
            ->execute([$adminUserId, $action, $targetUserId, $details !== null ? substr($details, 0, 500) : null, $ip]);
    } catch (PDOException $e) {
        if ($e->getCode() === '42S02') {
            $pdo->exec("CREATE TABLE IF NOT EXISTS admin_activity_log (
                id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                admin_user_id INT UNSIGNED NOT NULL,
                action VARCHAR(50) NOT NULL,
                target_user_id INT UNSIGNED NULL,
                details VARCHAR(500) NULL,
                ip_address VARCHAR(45) NULL,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_admin (admin_user_id),
                INDEX idx_created (created_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
            $pdo->prepare('INSERT INTO admin_activity_log (admin_user_id, action, target_user_id, details, ip_address) VALUES (?, ?, ?, ?, ?)')
                ->execute([$adminUserId, $action, $targetUserId, $details !== null ? substr($details, 0, 500) : null, $ip]);
        }
    }
}

/**
 * Ensure demo user and demo admin exist (created on first run). Credentials in config/demo.php
 * Works with or without is_admin column (if migration not yet run).
 */
function ensureDemoUser(): void {
    if (!defined('DEMO_EMAIL')) {
        require_once __DIR__ . '/../config/demo.php';
    }
    $pdo = getDbConnection();
    $hash = password_hash(DEMO_PASSWORD, PASSWORD_DEFAULT);
    $name = defined('DEMO_NAME') ? DEMO_NAME : 'Demo User';
    $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
    $stmt->execute([DEMO_EMAIL]);
    if (!$stmt->fetch()) {
        try {
            $pdo->prepare('INSERT INTO users (name, email, password, email_verified, is_admin) VALUES (?, ?, ?, 1, 1)')->execute([$name, DEMO_EMAIL, $hash]);
        } catch (PDOException $e) {
            if ($e->getCode() === '42S22' || strpos($e->getMessage(), 'is_admin') !== false) {
                $pdo->prepare('INSERT INTO users (name, email, password, email_verified) VALUES (?, ?, ?, 1)')->execute([$name, DEMO_EMAIL, $hash]);
            } else {
                throw $e;
            }
        }
    }
    if (!defined('DEMO_ADMIN_EMAIL')) {
        require_once __DIR__ . '/../config/demo.php';
    }
    $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
    $stmt->execute([DEMO_ADMIN_EMAIL]);
    if (!$stmt->fetch()) {
        $adminHash = password_hash(DEMO_ADMIN_PASSWORD, PASSWORD_DEFAULT);
        $adminName = defined('DEMO_ADMIN_NAME') ? DEMO_ADMIN_NAME : 'Demo Admin';
        try {
            $pdo->prepare('INSERT INTO users (name, email, password, email_verified, is_admin, role) VALUES (?, ?, ?, 1, 1, ?)')->execute([$adminName, DEMO_ADMIN_EMAIL, $adminHash, 'admin']);
        } catch (PDOException $e) {
            if ($e->getCode() === '42S22') {
                try {
                    $pdo->prepare('INSERT INTO users (name, email, password, email_verified, is_admin) VALUES (?, ?, ?, 1, 1)')->execute([$adminName, DEMO_ADMIN_EMAIL, $adminHash]);
                } catch (PDOException $e2) {
                    $pdo->prepare('INSERT INTO users (name, email, password, email_verified) VALUES (?, ?, ?, 1)')->execute([$adminName, DEMO_ADMIN_EMAIL, $adminHash]);
                }
            } else {
                throw $e;
            }
        }
    }
    if (!defined('DEMO_SUPERADMIN_EMAIL')) require_once __DIR__ . '/../config/demo.php';
    $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
    $stmt->execute([DEMO_SUPERADMIN_EMAIL]);
    if (!$stmt->fetch()) {
        $superHash = password_hash(DEMO_SUPERADMIN_PASSWORD, PASSWORD_DEFAULT);
        $superName = defined('DEMO_SUPERADMIN_NAME') ? DEMO_SUPERADMIN_NAME : 'Demo Super Admin';
        try {
            $pdo->prepare('INSERT INTO users (name, email, password, email_verified, is_admin, role) VALUES (?, ?, ?, 1, 1, ?)')->execute([$superName, DEMO_SUPERADMIN_EMAIL, $superHash, 'superadmin']);
        } catch (PDOException $e) {
            if ($e->getCode() === '42S22') {
                try {
                    $pdo->exec('ALTER TABLE users ADD COLUMN role VARCHAR(30) DEFAULT \'user\'');
                    $pdo->prepare('UPDATE users SET role = \'admin\' WHERE is_admin = 1')->execute();
                } catch (PDOException $e2) {}
                try {
                    $pdo->prepare('INSERT INTO users (name, email, password, email_verified, is_admin, role) VALUES (?, ?, ?, 1, 1, ?)')->execute([$superName, DEMO_SUPERADMIN_EMAIL, $superHash, 'superadmin']);
                } catch (PDOException $e2) {
                    $pdo->prepare('INSERT INTO users (name, email, password, email_verified, is_admin) VALUES (?, ?, ?, 1, 1)')->execute([$superName, DEMO_SUPERADMIN_EMAIL, $superHash]);
                }
            } else {
                throw $e;
            }
        }
    }
}

/**
 * Get demo user IDs (for display). Call after ensureDemoUser().
 * Returns ['demo' => id or null, 'admin' => id or null]
 */
function getDemoUserIds(): array {
    if (!defined('DEMO_EMAIL') || !defined('DEMO_ADMIN_EMAIL')) {
        require_once __DIR__ . '/../config/demo.php';
    }
    $pdo = getDbConnection();
    $out = ['demo' => null, 'admin' => null, 'superadmin' => null];
    $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
    $stmt->execute([DEMO_EMAIL]);
    $row = $stmt->fetch();
    if ($row) $out['demo'] = (int) $row['id'];
    $stmt->execute([DEMO_ADMIN_EMAIL]);
    $row = $stmt->fetch();
    if ($row) $out['admin'] = (int) $row['id'];
    if (defined('DEMO_SUPERADMIN_EMAIL')) {
        $stmt->execute([DEMO_SUPERADMIN_EMAIL]);
        $row = $stmt->fetch();
        if ($row) $out['superadmin'] = (int) $row['id'];
    }
    return $out;
}
