<?php
/* ============================================================================
   WBMCZ — ACTIVITY LOG
   ----------------------------------------------------------------------------
   Records what happens inside the admin panel: who did it, where, when and
   from which IP.  Two ways in:

     activity_log($db, 'update', 'User Management', 'Blocked user #42', 'user', 42);
        → explicit, use it inside any POST handler you care about.

     activity_autolog($db);
        → automatic. Called once per request from db.php. Logs every admin
          POST (the actions) and every admin page view (the trail), skipping
          AJAX/asset noise and collapsing repeats.

   The table is created on demand, so no manual step is required — but
   ccpsimigration.php creates it up-front too.
   ========================================================================== */

if (!function_exists('activity_ensure_schema')) {

function activity_ensure_schema($db, $force = false) {
    if (!$force && !empty($_SESSION['wb_activity_schema_ok'])) return true;
    try {
        $db->getConnection()->query(
            "CREATE TABLE IF NOT EXISTS activity_logs (
                id BIGINT AUTO_INCREMENT PRIMARY KEY,
                user_id INT NULL,
                user_name VARCHAR(150) NULL,
                user_role VARCHAR(20) NULL,
                action VARCHAR(60) NOT NULL DEFAULT 'view',
                module VARCHAR(80) NULL,
                description VARCHAR(500) NULL,
                reference_type VARCHAR(40) NULL,
                reference_id INT NULL,
                method VARCHAR(10) NULL,
                url VARCHAR(255) NULL,
                ip_address VARCHAR(45) NULL,
                user_agent VARCHAR(255) NULL,
                meta TEXT NULL,
                created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                KEY idx_al_user (user_id, created_at),
                KEY idx_al_action (action),
                KEY idx_al_module (module),
                KEY idx_al_created (created_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
        );
        $_SESSION['wb_activity_schema_ok'] = 1;
        return true;
    } catch (\Throwable $e) {
        return false;
    }
}

/** Client IP, proxy aware. */
function activity_ip() {
    foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'] as $k) {
        if (!empty($_SERVER[$k])) {
            $ip = trim(explode(',', $_SERVER[$k])[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
        }
    }
    return '0.0.0.0';
}

/** Turn a file name into the friendly module label used by the sidebar. */
function activity_module_name($file) {
    $map = [
        'index.php'              => 'Dashboard',
        'profile.php'            => 'Profile',
        'activity_log.php'       => 'Activity Log',
        'activity_task.php'      => 'Activity & Task',
        'subscription_plans.php' => 'Subscription Management',
        'user_list.php'          => 'User Management',
        'users.php'              => 'User Management',
        'staff.php'              => 'User Management',
        'roles.php'              => 'User Management',
        'kyc_pending.php'        => 'User Management',
        'upgrade_requests.php'   => 'User Management',
        'notifications.php'      => 'Notifications',
        'sellers.php'            => 'Sellers',
        'wallet.php'             => 'Wallet Management',
        'wallet_history.php'     => 'Wallet Management',
        'transactions.php'       => 'Wallet Management',
        'services.php'           => 'Service Management',
        'pending_services.php'   => 'Service Management',
        'product_management.php' => 'Service Management',
        'product_management_gov.php' => 'Service Management',
        'service_import.php'     => 'Service Management',
        'kyc_fields.php'         => 'Service Management',
        'leads.php'              => 'Lead Management',
        'hero_slides.php'        => 'Website Settings',
        'sms_settings.php'       => 'Website Settings',
        'orders.php'             => 'Order Management',
        'settings.php'           => 'Website Settings',
        'payouts.php'            => 'Payout & Earning',
        'withdrawals.php'        => 'Payout & Earning',
        'reports.php'            => 'Payout & Earning',
        'commissions.php'        => 'Commission Management',
        'tickets.php'            => 'Helpdesk Management',
        'refer.php'              => 'Refer & Earn',
        'website_requests.php'   => 'Website Requests',
    ];
    return $map[$file] ?? ucwords(str_replace(['_', '.php'], [' ', ''], $file));
}

/**
 * Write one activity row.
 *
 * @param object $db
 * @param string $action       view|create|update|delete|approve|reject|login|logout|export|payout…
 * @param string $module       friendly section name
 * @param string $description  human sentence
 * @param string $refType      e.g. 'user', 'order', 'ticket'
 * @param int    $refId
 * @param array  $meta         anything extra (stored as JSON)
 */
function activity_log($db, $action, $module = null, $description = '', $refType = null, $refId = null, $meta = []) {
    if (!is_object($db)) return false;
    if (!activity_ensure_schema($db)) return false;

    $file = basename($_SERVER['PHP_SELF'] ?? '');
    $uid  = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : null;

    $name = $_SESSION['user_name'] ?? null;
    $role = $_SESSION['user_type'] ?? null;
    if (($name === null || $role === null) && $uid) {
        try {
            $r = $db->select("SELECT name, user_type, role_id FROM users WHERE id = ?", [$uid]);
            if (!empty($r)) {
                $name = $r[0]['name'];
                $role = ($r[0]['user_type'] === 'admin')
                        ? (empty($r[0]['role_id']) ? 'admin' : 'employee')
                        : $r[0]['user_type'];
            }
        } catch (\Throwable $e) {}
    }

    $url = (string)($_SERVER['REQUEST_URI'] ?? $file);

    try {
        $db->insert(
            "INSERT INTO activity_logs
                (user_id, user_name, user_role, action, module, description,
                 reference_type, reference_id, method, url, ip_address, user_agent, meta)
             VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",
            [
                $uid,
                $name !== null ? substr($name, 0, 150) : null,
                $role !== null ? substr($role, 0, 20) : null,
                substr($action, 0, 60),
                substr((string)($module ?: activity_module_name($file)), 0, 80),
                substr((string)$description, 0, 500),
                $refType !== null ? substr($refType, 0, 40) : null,
                $refId !== null ? (int)$refId : null,
                substr((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'), 0, 10),
                substr($url, 0, 255),
                activity_ip(),
                substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255),
                !empty($meta) ? json_encode($meta, JSON_UNESCAPED_UNICODE) : null,
            ]
        );
        return true;
    } catch (\Throwable $e) {
        return false;
    }
}

/**
 * Automatic capture. Safe to call on every request — it decides for itself
 * whether the request is worth recording.
 */
function activity_autolog($db) {
    // Only admin panel requests, only for a logged-in account.
    $uri = (string)($_SERVER['REQUEST_URI'] ?? '');
    if (strpos($uri, '/admin/') === false) return;
    if (empty($_SESSION['user_id'])) return;

    // Ignore AJAX/JSON/export endpoints and asset hits.
    if (isset($_GET['ajax']) || isset($_GET['export'])) return;
    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) return;

    $file   = basename($_SERVER['PHP_SELF'] ?? '');
    if (substr($file, -4) !== '.php') return;
    $module = activity_module_name($file);
    $method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');

    if ($method === 'POST') {
        // Name the action after the submit button, e.g. name="update_order".
        $action = 'update';
        $what   = '';
        foreach ($_POST as $k => $v) {
            if (is_string($v) && preg_match('/^(add|create|update|edit|delete|remove|approve|reject|block|unblock|reset|save|set|send|assign|pay|process)_/i', $k)) {
                $what = $k;
                $action = strtolower(explode('_', $k)[0]);
                break;
            }
        }
        if ($what === '') { $what = 'form submit'; }
        $label = ucfirst(str_replace('_', ' ', $what));

        $refId = null;
        foreach (['id', 'user_id', 'order_id', 'ticket_id', 'request_id', 'target_user_id', 'seller_id', 'service_id'] as $k) {
            if (isset($_POST[$k]) && is_numeric($_POST[$k])) { $refId = (int)$_POST[$k]; break; }
        }

        activity_log($db, $action, $module, $label . ' in ' . $module, null, $refId);
        return;
    }

    // GET → a page view. Collapse repeats of the same page within 90 seconds.
    $key  = $file . '|' . ($_GET['role'] ?? '') . '|' . ($_GET['cat_id'] ?? '');
    $now  = time();
    if (isset($_SESSION['wb_last_view']) && is_array($_SESSION['wb_last_view'])
        && ($_SESSION['wb_last_view']['k'] ?? '') === $key
        && ($now - (int)($_SESSION['wb_last_view']['t'] ?? 0)) < 90) {
        return;
    }
    $_SESSION['wb_last_view'] = ['k' => $key, 't' => $now];

    activity_log($db, 'view', $module, 'Opened ' . $module);
}

} // end function_exists guard
