<?php
/**
 * Shared helper functions used across public pages and the admin panel.
 */

require_once __DIR__ . '/../config/database.php';

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

/** Escape a string for safe HTML output. */
function e(?string $value): string
{
    return htmlspecialchars($value ?? '', ENT_QUOTES, 'UTF-8');
}

/** Fetch the singleton site settings row (cached per request). */
function getSettings(): array
{
    static $settings = null;
    if ($settings === null) {
        $stmt = db()->query('SELECT * FROM settings WHERE id = 1');
        $settings = $stmt->fetch() ?: [];
    }
    return $settings;
}

/** Fetch SEO metadata for a given page key (home, about, services, downloads, contact). */
function getSeo(string $pageKey): array
{
    $stmt = db()->prepare('SELECT * FROM seo_pages WHERE page_key = ? LIMIT 1');
    $stmt->execute([$pageKey]);
    return $stmt->fetch() ?: [
        'title' => 'PIMS Nepal',
        'meta_description' => '',
        'meta_keywords' => '',
        'og_image_path' => '',
        'canonical_url' => '',
    ];
}

/** Fetch active navigation links, ordered. */
function getNavLinks(): array
{
    return db()->query('SELECT * FROM nav_links WHERE is_active = 1 ORDER BY sort_order ASC, id ASC')->fetchAll();
}

/** Build a public URL for an uploaded/asset file path stored in the DB. */
function assetUrl(?string $path): string
{
    if (!$path) {
        return '';
    }
    if (str_starts_with($path, 'http://') || str_starts_with($path, 'https://')) {
        return $path;
    }
    return rtrim(basePath(), '/') . '/' . ltrim($path, '/');
}

/** Base path of the site relative to the domain root (auto-detected). */
function basePath(): string
{
    if (defined('SITE_URL') && SITE_URL !== '') {
        return SITE_URL;
    }
    return '';
}

/** Render a set of <meta> tags + <title> for the current page's SEO row. */
function renderSeoTags(array $seo): void
{
    echo '<title>' . e($seo['title'] ?? 'PIMS Nepal') . "</title>\n";
    if (!empty($seo['meta_description'])) {
        echo '<meta name="description" content="' . e($seo['meta_description']) . "\">\n";
    }
    if (!empty($seo['meta_keywords'])) {
        echo '<meta name="keywords" content="' . e($seo['meta_keywords']) . "\">\n";
    }
    if (!empty($seo['canonical_url'])) {
        echo '<link rel="canonical" href="' . e($seo['canonical_url']) . "\">\n";
    }
    if (!empty($seo['og_image_path'])) {
        echo '<meta property="og:image" content="' . e(assetUrl($seo['og_image_path'])) . "\">\n";
    }
}

/** Generate (and stash in session) a CSRF token, or return the existing one. */
function csrfToken(): string
{
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/** Verify a submitted CSRF token against the session's token. */
function csrfVerify(?string $token): bool
{
    return !empty($token) && !empty($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}

/**
 * Very simple per-session rate limiter (e.g. for the contact form) —
 * allows up to $max submissions per $windowSeconds.
 */
function rateLimitCheck(string $key, int $max = 5, int $windowSeconds = 60): bool
{
    $now = time();
    $bucket = $_SESSION['rate_' . $key] ?? ['count' => 0, 'start' => $now];
    if ($now - $bucket['start'] > $windowSeconds) {
        $bucket = ['count' => 0, 'start' => $now];
    }
    $bucket['count']++;
    $_SESSION['rate_' . $key] = $bucket;
    return $bucket['count'] <= $max;
}

/** Decode a JSON TEXT column safely into an array. */
function jdecode(?string $json): array
{
    if (!$json) {
        return [];
    }
    $decoded = json_decode($json, true);
    return is_array($decoded) ? $decoded : [];
}

/** Redirect helper. */
function redirect(string $url): never
{
    header('Location: ' . $url);
    exit;
}

/** Is an admin currently logged in? */
function isAdminLoggedIn(): bool
{
    return !empty($_SESSION['admin_id']);
}

/** Require admin login or redirect to the admin login page. */
function requireAdmin(): void
{
    if (!isAdminLoggedIn()) {
        redirect('login.php');
    }
}

/** Flash a one-time message to session, read/cleared on next request. */
function flash(string $key, ?string $message = null): ?string
{
    if ($message !== null) {
        $_SESSION['flash_' . $key] = $message;
        return null;
    }
    $value = $_SESSION['flash_' . $key] ?? null;
    unset($_SESSION['flash_' . $key]);
    return $value;
}
