<?php
/**
 * ERP Global Audit Helper v1.1
 * Supports: INSERT, UPDATE, DELETE, LOGIN, LOGOUT, VIEW, EXPORT
 * Path: /public_html/erp.jewellersbd.com/api/_audit_helper.php
 */

if (isset($_SERVER['SCRIPT_FILENAME']) && realpath($_SERVER['SCRIPT_FILENAME']) === realpath(__FILE__)) {
    http_response_code(403);
    exit('Forbidden');
}

if (!function_exists('erp_audit_is_db_connection')) {
    function erp_audit_is_db_connection($value)
    {
        return (class_exists('PDO') && $value instanceof PDO)
            || (class_exists('mysqli') && $value instanceof mysqli);
    }
}

if (!function_exists('erp_audit_detect_db')) {
    function erp_audit_detect_db()
    {
        foreach (array('pdo', 'db', 'conn', 'mysqli', 'con', 'link') as $name) {
            if (isset($GLOBALS[$name]) && erp_audit_is_db_connection($GLOBALS[$name])) {
                return $GLOBALS[$name];
            }
        }
        return null;
    }
}

if (!function_exists('erp_audit_limit_text')) {
    function erp_audit_limit_text($text, $maxLength)
    {
        if ($text === null) return null;
        $text = (string)$text;
        return strlen($text) <= $maxLength ? $text : substr($text, 0, $maxLength - 20) . '...[truncated]';
    }
}

if (!function_exists('erp_audit_sensitive_key')) {
    function erp_audit_sensitive_key($key)
    {
        $key = strtolower((string)$key);
        $bad = array(
            'password', 'passwd', 'pwd', 'pass',
            'token', 'access_token', 'refresh_token',
            'secret', 'api_key', 'private_key',
            'authorization', 'cookie', 'session',
            'csrf', 'otp', 'pin'
        );

        foreach ($bad as $word) {
            if (strpos($key, $word) !== false) {
                return true;
            }
        }

        return false;
    }
}

if (!function_exists('erp_audit_sanitize')) {
    function erp_audit_sanitize($value, $depth = 0)
    {
        if ($depth > 6) return '[max_depth]';

        if (is_array($value)) {
            $clean = array();
            foreach ($value as $k => $v) {
                $clean[$k] = erp_audit_sensitive_key($k) ? '[hidden]' : erp_audit_sanitize($v, $depth + 1);
            }
            return $clean;
        }

        if (is_object($value)) {
            return erp_audit_sanitize(get_object_vars($value), $depth + 1);
        }

        return $value;
    }
}

if (!function_exists('erp_audit_encode')) {
    function erp_audit_encode($value)
    {
        if ($value === null) return null;

        $value = erp_audit_sanitize($value);

        if (is_string($value)) {
            return erp_audit_limit_text($value, 65000);
        }

        $json = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        if ($json === false) return '[json_encode_failed]';

        return erp_audit_limit_text($json, 65000);
    }
}

if (!function_exists('erp_audit_ip')) {
    function erp_audit_ip()
    {
        foreach (array('HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR') as $key) {
            if (!empty($_SERVER[$key])) {
                $ip = (string)$_SERVER[$key];
                if ($key === 'HTTP_X_FORWARDED_FOR' && strpos($ip, ',') !== false) {
                    $parts = explode(',', $ip);
                    $ip = trim($parts[0]);
                }
                return erp_audit_limit_text($ip, 50);
            }
        }
        return null;
    }
}

if (!function_exists('erp_audit_user_id')) {
    function erp_audit_user_id($overrideUserId = null)
    {
        if ($overrideUserId !== null && is_numeric($overrideUserId)) {
            return (int)$overrideUserId;
        }

        if (isset($_SESSION) && is_array($_SESSION)) {
            foreach (array('user_id', 'admin_id', 'staff_id', 'uid', 'id') as $key) {
                if (isset($_SESSION[$key]) && is_numeric($_SESSION[$key])) {
                    return (int)$_SESSION[$key];
                }
            }

            if (isset($_SESSION['user']) && is_array($_SESSION['user'])) {
                foreach (array('user_id', 'admin_id', 'staff_id', 'uid', 'id') as $key) {
                    if (isset($_SESSION['user'][$key]) && is_numeric($_SESSION['user'][$key])) {
                        return (int)$_SESSION['user'][$key];
                    }
                }
            }
        }

        return null;
    }
}

if (!function_exists('erp_audit_action')) {
    function erp_audit_action($action)
    {
        $action = strtoupper(trim((string)$action));

        $map = array(
            'CREATE' => 'INSERT',
            'ADD' => 'INSERT',
            'STORE' => 'INSERT',
            'NEW' => 'INSERT',

            'EDIT' => 'UPDATE',
            'MODIFY' => 'UPDATE',
            'CHANGE' => 'UPDATE',
            'CANCEL' => 'UPDATE',
            'RESTORE' => 'UPDATE',
            'REVERSE' => 'UPDATE',

            'REMOVE' => 'DELETE',
            'SOFT_DELETE' => 'DELETE',

            'SIGNIN' => 'LOGIN',
            'LOG_IN' => 'LOGIN',

            'SIGNOUT' => 'LOGOUT',
            'LOG_OUT' => 'LOGOUT',

            'READ' => 'VIEW',
            'SHOW' => 'VIEW',
            'OPEN' => 'VIEW',
            'DETAIL' => 'VIEW',
            'LIST' => 'VIEW',

            'DOWNLOAD' => 'EXPORT',
            'PRINT' => 'EXPORT',
            'PDF' => 'EXPORT',
            'CSV' => 'EXPORT',
            'EXCEL' => 'EXPORT',
            'REPORT_EXPORT' => 'EXPORT'
        );

        if (isset($map[$action])) {
            return $map[$action];
        }

        $allowed = array('INSERT', 'UPDATE', 'DELETE', 'LOGIN', 'LOGOUT', 'VIEW', 'EXPORT');

        return in_array($action, $allowed, true) ? $action : 'UPDATE';
    }
}

if (!function_exists('erp_audit_log')) {
    function erp_audit_log($db, $tableName, $recordId, $action, $oldValues = null, $newValues = null, $note = '', $changedBy = null)
    {
        try {
            if (!erp_audit_is_db_connection($db)) {
                $db = erp_audit_detect_db();
            }

            if (!erp_audit_is_db_connection($db)) {
                return false;
            }

            $tableName = preg_replace('/[^a-zA-Z0-9_:-]/', '', (string)$tableName);
            $tableName = erp_audit_limit_text($tableName, 50);
            if ($tableName === '') return false;

            $recordIdValue = null;
            if ($recordId !== null && $recordId !== '' && is_numeric($recordId)) {
                $recordIdValue = (int)$recordId;
            }

            $changedByValue = erp_audit_user_id($changedBy);
            $actionValue = erp_audit_action($action);
            $ipAddress = erp_audit_ip();
            $oldText = erp_audit_encode($oldValues);
            $newText = erp_audit_encode($newValues);
            $noteText = erp_audit_limit_text($note, 255);

            $sql = "
                INSERT INTO audit_log
                    (table_name, record_id, action, changed_by, ip_address, old_values, new_values, note)
                VALUES
                    (?, ?, ?, ?, ?, ?, ?, ?)
            ";

            if (class_exists('PDO') && $db instanceof PDO) {
                $stmt = $db->prepare($sql);
                if (!$stmt) return false;

                return $stmt->execute(array(
                    $tableName,
                    $recordIdValue,
                    $actionValue,
                    $changedByValue,
                    $ipAddress,
                    $oldText,
                    $newText,
                    $noteText
                ));
            }

            if (class_exists('mysqli') && $db instanceof mysqli) {
                $stmt = $db->prepare($sql);
                if (!$stmt) return false;

                $stmt->bind_param(
                    'sisissss',
                    $tableName,
                    $recordIdValue,
                    $actionValue,
                    $changedByValue,
                    $ipAddress,
                    $oldText,
                    $newText,
                    $noteText
                );

                $ok = $stmt->execute();
                $stmt->close();
                return $ok;
            }

            return false;
        } catch (Exception $e) {
            return false;
        }
    }
}

if (!function_exists('erp_audit_insert')) {
    function erp_audit_insert($db, $tableName, $recordId, $newValues = null, $note = '', $changedBy = null)
    {
        return erp_audit_log($db, $tableName, $recordId, 'INSERT', null, $newValues, $note, $changedBy);
    }
}

if (!function_exists('erp_audit_update')) {
    function erp_audit_update($db, $tableName, $recordId, $oldValues = null, $newValues = null, $note = '', $changedBy = null)
    {
        return erp_audit_log($db, $tableName, $recordId, 'UPDATE', $oldValues, $newValues, $note, $changedBy);
    }
}

if (!function_exists('erp_audit_delete')) {
    function erp_audit_delete($db, $tableName, $recordId, $oldValues = null, $note = '', $changedBy = null)
    {
        return erp_audit_log($db, $tableName, $recordId, 'DELETE', $oldValues, null, $note, $changedBy);
    }
}

if (!function_exists('erp_audit_login')) {
    function erp_audit_login($db, $userId, $newValues = null, $note = 'User login')
    {
        return erp_audit_log($db, 'users', $userId, 'LOGIN', null, $newValues, $note, $userId);
    }
}

if (!function_exists('erp_audit_logout')) {
    function erp_audit_logout($db, $userId, $oldValues = null, $note = 'User logout')
    {
        return erp_audit_log($db, 'users', $userId, 'LOGOUT', $oldValues, null, $note, $userId);
    }
}

if (!function_exists('erp_audit_view')) {
    function erp_audit_view($db, $tableName, $recordId = null, $note = 'Viewed', $changedBy = null)
    {
        return erp_audit_log($db, $tableName, $recordId, 'VIEW', null, null, $note, $changedBy);
    }
}

if (!function_exists('erp_audit_export')) {
    function erp_audit_export($db, $tableName, $recordId = null, $note = 'Exported', $changedBy = null)
    {
        return erp_audit_log($db, $tableName, $recordId, 'EXPORT', null, null, $note, $changedBy);
    }
}
