<?php
/**
 * MJ Marketplace v3.0.4 Bootstrap Helpers
 * Safe overlay helpers for CRM, notifications, dashboard widgets, and admin review queue.
 */
if (session_status() === PHP_SESSION_NONE) { @session_start(); }
if (!defined('MJ_MARKETPLACE_VERSION')) { define('MJ_MARKETPLACE_VERSION', '3.0.4'); }

function mjv304_safe_config_load(): void {
    static $loaded = false;
    if ($loaded) { return; }
    $loaded = true;

    // First load the normal MJ Marketplace bootstrap when present.
    // This keeps v3.0.4 connected to the same DB/session/helpers used by v3.0.3.
    $normalFunctions = __DIR__ . '/functions.php';
    if (is_file($normalFunctions)) {
        require_once $normalFunctions;
        return;
    }

    $candidates = [
        __DIR__ . '/../config.php',
        __DIR__ . '/../includes/config.php',
        __DIR__ . '/../admin/config.php',
        __DIR__ . '/../db.php',
        __DIR__ . '/../includes/db.php',
        dirname(__DIR__) . '/config/database.php',
    ];
    foreach ($candidates as $file) {
        if (is_file($file)) { require_once $file; }
    }
}

function mjv304_db(): PDO {
    mjv304_safe_config_load();

    // Native MJ Marketplace v3 database function from includes/db.php.
    if (function_exists('db')) {
        $pdo = db();
        if ($pdo instanceof PDO) {
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $GLOBALS['pdo'] = $pdo;
            return $pdo;
        }
    }

    foreach (['pdo','PDO','db','DBH','dbh'] as $key) {
        if (isset($GLOBALS[$key]) && $GLOBALS[$key] instanceof PDO) {
            $GLOBALS[$key]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $GLOBALS[$key];
        }
    }

    $host = defined('DB_HOST') ? DB_HOST : (defined('MYSQL_HOST') ? MYSQL_HOST : getenv('DB_HOST'));
    $name = defined('DB_NAME') ? DB_NAME : (defined('MYSQL_DATABASE') ? MYSQL_DATABASE : getenv('DB_NAME'));
    $user = defined('DB_USER') ? DB_USER : (defined('MYSQL_USER') ? MYSQL_USER : getenv('DB_USER'));
    $pass = defined('DB_PASS') ? DB_PASS : (defined('DB_PASSWORD') ? DB_PASSWORD : getenv('DB_PASS'));

    // MJ Marketplace installer config array fallback.
    if ((!$host || !$name || !$user) && function_exists('mj_config')) {
        $cfg = mj_config();
        $host = $host ?: ($cfg['db_host'] ?? null);
        $name = $name ?: ($cfg['db_name'] ?? null);
        $user = $user ?: ($cfg['db_user'] ?? null);
        $pass = $pass !== false && $pass !== null ? $pass : ($cfg['db_pass'] ?? '');
    }

    if (!$host || !$name || !$user) {
        throw new RuntimeException('MJ v3.0.4 cannot find the project database connection. Make sure includes/config.php exists and the project is installed.');
    }
    $pdo = new PDO('mysql:host='.$host.';dbname='.$name.';charset=utf8mb4', $user, (string)$pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]);
    $GLOBALS['pdo'] = $pdo;
    return $pdo;
}

function mjv304_e($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
function mjv304_now(): string { return date('Y-m-d H:i:s'); }
function mjv304_json($value): string { return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); }
function mjv304_decode_json(?string $json): array { $a = json_decode((string)$json, true); return is_array($a) ? $a : []; }

function mjv304_current_user_id(): int {
    foreach (['user_id','userid','seller_id','seller_user_id','id','uid','admin_id'] as $key) {
        if (!empty($_SESSION[$key]) && is_numeric($_SESSION[$key])) { return (int)$_SESSION[$key]; }
    }
    if (!empty($_SESSION['USER']['id'])) { return (int)$_SESSION['USER']['id']; }
    if (!empty($_SESSION['user']['id'])) { return (int)$_SESSION['user']['id']; }
    return 0;
}

function mjv304_current_user_name(): string {
    foreach (['name','fullname','username','email'] as $key) {
        if (!empty($_SESSION[$key])) { return (string)$_SESSION[$key]; }
    }
    foreach (['USER','user','admin'] as $group) {
        if (!empty($_SESSION[$group]) && is_array($_SESSION[$group])) {
            foreach (['name','fullname','username','email'] as $key) {
                if (!empty($_SESSION[$group][$key])) { return (string)$_SESSION[$group][$key]; }
            }
        }
    }
    return 'User';
}

function mjv304_is_admin(): bool {
    if (!empty($_SESSION['is_admin']) || !empty($_SESSION['admin_id'])) { return true; }
    $role = strtolower((string)($_SESSION['role'] ?? ($_SESSION['USER']['role'] ?? ($_SESSION['user']['role'] ?? ''))));
    return in_array($role, ['admin','superadmin','super_admin','administrator'], true);
}

function mjv304_require_login(): void {
    if (mjv304_current_user_id() <= 0) {
        header('Location: login.php');
        exit;
    }
}

function mjv304_require_admin(): void {
    if (!mjv304_is_admin()) {
        http_response_code(403);
        echo '<div style="padding:25px;font-family:Arial">Access denied.</div>';
        exit;
    }
}

function mjv304_fetch_all(string $sql, array $params = []): array {
    $stmt = mjv304_db()->prepare($sql);
    $stmt->execute($params);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function mjv304_fetch_one(string $sql, array $params = []): ?array {
    $stmt = mjv304_db()->prepare($sql);
    $stmt->execute($params);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    return $row ?: null;
}
function mjv304_fetch_value(string $sql, array $params = []) {
    $stmt = mjv304_db()->prepare($sql);
    $stmt->execute($params);
    return $stmt->fetchColumn();
}
function mjv304_execute(string $sql, array $params = []): int {
    $stmt = mjv304_db()->prepare($sql);
    $stmt->execute($params);
    return $stmt->rowCount();
}

function mjv304_table_exists(string $table): bool {
    return (bool)mjv304_fetch_value("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?", [$table]);
}
function mjv304_column_exists(string $table, string $column): bool {
    return (bool)mjv304_fetch_value("SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?", [$table, $column]);
}
function mjv304_table_columns(string $table): array {
    $rows = mjv304_fetch_all("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?", [$table]);
    return array_map(static fn($r) => $r['COLUMN_NAME'], $rows);
}

function mjv304_base_url(string $path = ''): string {
    $base = defined('BASE_URL') ? rtrim(BASE_URL, '/') : '';
    if (!$base) {
        $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? '';
        $dir = rtrim(str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '')), '/');
        $base = $host ? ($scheme . '://' . $host . ($dir === '/' ? '' : $dir)) : '';
    }
    return rtrim($base, '/') . '/' . ltrim($path, '/');
}

function mjv304_notify(string $userType, ?int $userId, string $title, string $message = '', string $type = 'info', ?string $link = null, array $meta = []): int {
    // v3.0.4.1 compatibility: existing installs may have older mj_notifications columns.
    if (function_exists('mjv3041_notify')) {
        return mjv3041_notify($userType, $userId, $title, $message, $type, (string)($link ?? ''), $meta);
    }
    $cols = mjv304_table_columns('mj_notifications');
    $data = [];
    if (in_array('user_type', $cols, true)) { $data['user_type'] = $userType; }
    if (in_array('user_id', $cols, true)) { $data['user_id'] = ($userType === 'user') ? ($userId ?: null) : null; }
    if (in_array('admin_id', $cols, true)) { $data['admin_id'] = ($userType === 'admin') ? ($userId ?: null) : null; }
    if (in_array('title', $cols, true)) { $data['title'] = $title; }
    if (in_array('message', $cols, true)) { $data['message'] = $message; }
    if (in_array('body', $cols, true)) { $data['body'] = $message; }
    if (in_array('type', $cols, true)) { $data['type'] = $type; }
    if (in_array('priority', $cols, true)) { $data['priority'] = in_array($type, ['lead','chat','payment','review'], true) ? 'high' : 'normal'; }
    if (in_array('link', $cols, true)) { $data['link'] = $link; }
    if (in_array('action_url', $cols, true)) { $data['action_url'] = $link; }
    if (in_array('url', $cols, true)) { $data['url'] = $link; }
    if (in_array('is_read', $cols, true)) { $data['is_read'] = 0; }
    if (in_array('meta_json', $cols, true)) { $data['meta_json'] = $meta ? mjv304_json($meta) : null; }
    if (in_array('created_at', $cols, true)) { $data['created_at'] = mjv304_now(); }
    if (!$data) { return 0; }
    $names = array_keys($data);
    mjv304_execute('INSERT INTO mj_notifications (`'.implode('`,`', $names).'`) VALUES ('.implode(',', array_fill(0, count($names), '?')).')', array_values($data));
    return (int)mjv304_db()->lastInsertId();
}

function mjv304_admin_notify(string $title, string $message = '', string $type = 'admin', ?string $link = null, array $meta = []): int {
    return mjv304_notify('admin', null, $title, $message, $type, $link, $meta);
}

function mjv304_mark_notification_read(int $id, string $userType, ?int $userId = null): void {
    $sql = "UPDATE mj_notifications SET is_read=1, read_at=NOW() WHERE id=? AND user_type=?";
    $params = [$id, $userType];
    if ($userId !== null) { $sql .= " AND (user_id=? OR user_id IS NULL)"; $params[] = $userId; }
    mjv304_execute($sql, $params);
}

function mjv304_whatsapp_link(?string $phone, string $message = ''): string {
    $digits = preg_replace('/\D+/', '', (string)$phone);
    if ($digits === '') { return '#'; }
    return 'https://wa.me/' . $digits . ($message !== '' ? '?text=' . rawurlencode($message) : '');
}
function mjv304_tel_link(?string $phone): string {
    $digits = preg_replace('/[^0-9+]+/', '', (string)$phone);
    return $digits ? 'tel:' . $digits : '#';
}
function mjv304_mail_link(?string $email, string $subject = ''): string {
    $email = trim((string)$email);
    if ($email === '') { return '#'; }
    return 'mailto:' . rawurlencode($email) . ($subject !== '' ? '?subject=' . rawurlencode($subject) : '');
}
function mjv304_status_options(): array {
    return ['new'=>'New','contacted'=>'Contacted','followup'=>'Follow-up','converted'=>'Converted','closed'=>'Closed','spam'=>'Spam / Not Relevant'];
}
function mjv304_badge_class(string $status): string {
    return [
        'new'=>'mj-badge-new','contacted'=>'mj-badge-info','followup'=>'mj-badge-warning',
        'converted'=>'mj-badge-success','closed'=>'mj-badge-dark','spam'=>'mj-badge-danger',
        'pending'=>'mj-badge-warning','approved'=>'mj-badge-success','rejected'=>'mj-badge-danger'
    ][$status] ?? 'mj-badge-info';
}
function mjv304_redirect(string $url): void { header('Location: '.$url); exit; }
