<?php
/**
 * Helper Functions
 * Common utility functions used throughout the application
 */

/**
 * Sanitize input data
 */
function sanitize($data) {
    if (is_array($data)) {
        return array_map('sanitize', $data);
    }
    return htmlspecialchars(trim($data), ENT_QUOTES, 'UTF-8');
}

/**
 * Generate unique ID
 */
function generateUniqueId($prefix = '', $length = 10) {
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $id = $prefix;
    for ($i = 0; $i < $length; $i++) {
        $id .= $characters[random_int(0, strlen($characters) - 1)];
    }
    return $id;
}

/**
 * Generate user ID
 */
function generateUserId() {
    return 'USR' . date('y') . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 8));
}

/**
 * Generate trade ID
 */
function generateTradeId() {
    return 'TRD' . date('ymd') . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 8));
}

/**
 * Generate transaction ID
 */
function generateTransactionId($type = 'TXN') {
    return $type . date('ymdHis') . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 6));
}

/**
 * Generate referral code
 */
function generateReferralCode() {
    return 'REF' . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 8));
}

/**
 * Hash password
 */
function hashPassword($password) {
    return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}

/**
 * Verify password
 */
function verifyPassword($password, $hash) {
    return password_verify($password, $hash);
}

/**
 * Generate CSRF token
 */
function generateCsrfToken() {
    if (empty($_SESSION[CSRF_TOKEN_NAME])) {
        $_SESSION[CSRF_TOKEN_NAME] = bin2hex(random_bytes(32));
    }
    return $_SESSION[CSRF_TOKEN_NAME];
}

/**
 * Verify CSRF token
 */
function verifyCsrfToken($token) {
    return isset($_SESSION[CSRF_TOKEN_NAME]) && hash_equals($_SESSION[CSRF_TOKEN_NAME], $token);
}

/**
 * Get CSRF input field
 */
function csrfField() {
    return '<input type="hidden" name="' . CSRF_TOKEN_NAME . '" value="' . generateCsrfToken() . '">';
}

/**
 * Format currency
 */
function formatCurrency($amount, $symbol = null) {
    $symbol = $symbol ?? CURRENCY_SYMBOL;
    return $symbol . number_format((float)$amount, 2);
}

/**
 * Format date
 */
function formatDate($date, $format = 'd M Y') {
    return date($format, strtotime($date));
}

/**
 * Format datetime
 */
function formatDateTime($datetime, $format = 'd M Y H:i:s') {
    return date($format, strtotime($datetime));
}

/**
 * Time ago format
 */
function timeAgo($datetime) {
    $time = strtotime($datetime);
    $diff = time() - $time;
    
    if ($diff < 60) {
        return 'Just now';
    } elseif ($diff < 3600) {
        $mins = floor($diff / 60);
        return $mins . ' min' . ($mins > 1 ? 's' : '') . ' ago';
    } elseif ($diff < 86400) {
        $hours = floor($diff / 3600);
        return $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago';
    } elseif ($diff < 604800) {
        $days = floor($diff / 86400);
        return $days . ' day' . ($days > 1 ? 's' : '') . ' ago';
    } else {
        return formatDate($datetime);
    }
}

/**
 * Redirect
 */
function redirect($url, $message = null, $type = 'success') {
    if ($message) {
        $_SESSION['flash_message'] = $message;
        $_SESSION['flash_type'] = $type;
    }
    header("Location: " . $url);
    exit;
}

/**
 * Get flash message
 */
function getFlashMessage() {
    if (isset($_SESSION['flash_message'])) {
        $message = $_SESSION['flash_message'];
        $type = $_SESSION['flash_type'] ?? 'success';
        unset($_SESSION['flash_message'], $_SESSION['flash_type']);
        return ['message' => $message, 'type' => $type];
    }
    return null;
}

/**
 * Display flash message HTML
 */
function displayFlashMessage() {
    $flash = getFlashMessage();
    if ($flash) {
        $classes = [
            'success' => 'alert-success',
            'error' => 'alert-danger',
            'warning' => 'alert-warning',
            'info' => 'alert-info'
        ];
        $alertClass = isset($classes[$flash['type']]) ? $classes[$flash['type']] : 'alert-info';
        echo '<div class="alert ' . $alertClass . ' alert-dismissible fade show" role="alert">';
        echo $flash['message'];
        echo '<button type="button" class="btn-close" data-bs-dismiss="alert"></button>';
        echo '</div>';
    }
}

/**
 * Get client IP address
 */
function getClientIp() {
    $ipKeys = ['HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'];
    
    foreach ($ipKeys as $key) {
        if (!empty($_SERVER[$key])) {
            $ip = $_SERVER[$key];
            if (strpos($ip, ',') !== false) {
                $ip = trim(explode(',', $ip)[0]);
            }
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }
    return '0.0.0.0';
}

/**
 * Get user agent
 */
function getUserAgent() {
    return $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
}

/**
 * Detect device type
 */
function getDeviceType() {
    $userAgent = strtolower(getUserAgent());
    
    if (preg_match('/mobile|android|iphone|ipod|blackberry|windows phone/i', $userAgent)) {
        return 'mobile';
    } elseif (preg_match('/tablet|ipad/i', $userAgent)) {
        return 'tablet';
    }
    return 'desktop';
}

/**
 * Log activity
 */
function logActivity($userType, $userId, $action, $description = null) {
    dbInsert('activity_logs', [
        'user_type' => $userType,
        'user_id' => $userId,
        'action' => $action,
        'description' => $description,
        'ip_address' => getClientIp(),
        'user_agent' => getUserAgent()
    ]);
}

/**
 * Get setting value
 */
// getSetting() is defined in config.php - removed duplicate

/**
 * Update setting value
 */
function updateSetting($key, $value) {
    return dbQuery(
        "INSERT INTO settings (setting_key, setting_value) VALUES (:key, :value) 
         ON DUPLICATE KEY UPDATE setting_value = :value2",
        ['key' => $key, 'value' => $value, 'value2' => $value]
    );
}

/**
 * Validate email
 */
function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
 * Validate phone (Indian format)
 */
function isValidPhone($phone) {
    return preg_match('/^[6-9]\d{9}$/', preg_replace('/[^0-9]/', '', $phone));
}

/**
 * Validate password strength
 */
function isStrongPassword($password) {
    // At least 8 characters, one uppercase, one lowercase, one number
    return strlen($password) >= 8 &&
           preg_match('/[A-Z]/', $password) &&
           preg_match('/[a-z]/', $password) &&
           preg_match('/[0-9]/', $password);
}

/**
 * Upload file
 */
function uploadFile($file, $destination, $allowedTypes = null, $maxSize = null) {
    $allowedTypes = $allowedTypes ?? ALLOWED_IMAGE_TYPES;
    $maxSize = $maxSize ?? MAX_UPLOAD_SIZE;
    
    if ($file['error'] !== UPLOAD_ERR_OK) {
        return ['success' => false, 'error' => 'Upload error occurred'];
    }
    
    if ($file['size'] > $maxSize) {
        return ['success' => false, 'error' => 'File size exceeds limit'];
    }
    
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mimeType = $finfo->file($file['tmp_name']);
    
    if (!in_array($mimeType, $allowedTypes)) {
        return ['success' => false, 'error' => 'File type not allowed'];
    }
    
    $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
    $filename = uniqid() . '_' . time() . '.' . $extension;
    $filepath = $destination . '/' . $filename;
    
    if (!is_dir($destination)) {
        mkdir($destination, 0755, true);
    }
    
    if (move_uploaded_file($file['tmp_name'], $filepath)) {
        return ['success' => true, 'filename' => $filename, 'path' => $filepath];
    }
    
    return ['success' => false, 'error' => 'Failed to move uploaded file'];
}

/**
 * Delete file
 */
function deleteFile($filepath) {
    if (file_exists($filepath)) {
        return unlink($filepath);
    }
    return false;
}

/**
 * Send JSON response
 */
function jsonResponse($data, $statusCode = 200) {
    http_response_code($statusCode);
    header('Content-Type: application/json');
    echo json_encode($data);
    exit;
}

/**
 * Success JSON response
 */
function jsonSuccess($message = 'Success', $data = []) {
    jsonResponse(array_merge(['success' => true, 'message' => $message], $data));
}

/**
 * Error JSON response
 */
function jsonError($message = 'Error', $statusCode = 400, $data = []) {
    jsonResponse(array_merge(['success' => false, 'error' => $message], $data), $statusCode);
}

/**
 * Encrypt data
 */
function encryptData($data) {
    $key = hash('sha256', ENCRYPTION_KEY);
    $iv = random_bytes(16);
    $encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv);
    return base64_encode($iv . $encrypted);
}

/**
 * Decrypt data
 */
function decryptData($data) {
    $key = hash('sha256', ENCRYPTION_KEY);
    $data = base64_decode($data);
    $iv = substr($data, 0, 16);
    $encrypted = substr($data, 16);
    return openssl_decrypt($encrypted, 'AES-256-CBC', $key, 0, $iv);
}

/**
 * Generate random token
 */
function generateToken($length = 32) {
    return bin2hex(random_bytes($length / 2));
}

/**
 * Calculate payout
 */
function calculatePayout($amount, $payoutPercent) {
    return $amount * ($payoutPercent / 100);
}

/**
 * Format percentage
 */
function formatPercent($value, $decimals = 2) {
    return number_format((float)$value, $decimals) . '%';
}

/**
 * Truncate text
 */
function truncate($text, $length = 100, $suffix = '...') {
    if (strlen($text) <= $length) {
        return $text;
    }
    return substr($text, 0, $length) . $suffix;
}

/**
 * Get status badge HTML
 */
function statusBadge($status, $type = 'default') {
    $badges = [
        'active' => 'bg-success',
        'inactive' => 'bg-secondary',
        'pending' => 'bg-warning',
        'approved' => 'bg-success',
        'rejected' => 'bg-danger',
        'blocked' => 'bg-danger',
        'suspended' => 'bg-warning',
        'verified' => 'bg-success',
        'won' => 'bg-success',
        'lost' => 'bg-danger',
        'open' => 'bg-info',
        'closed' => 'bg-secondary',
        'processing' => 'bg-info',
        'completed' => 'bg-success',
        'cancelled' => 'bg-secondary'
    ];
    
    $class = $badges[strtolower($status)] ?? 'bg-secondary';
    return '<span class="badge ' . $class . '">' . ucfirst($status) . '</span>';
}

/**
 * Pagination helper
 */
function paginate($total, $perPage, $currentPage, $url) {
    $totalPages = ceil($total / $perPage);
    $currentPage = max(1, min($currentPage, $totalPages));
    
    $html = '<nav><ul class="pagination justify-content-center">';
    
    // Previous
    $prevDisabled = $currentPage <= 1 ? 'disabled' : '';
    $html .= '<li class="page-item ' . $prevDisabled . '"><a class="page-link" href="' . $url . '?page=' . ($currentPage - 1) . '">Previous</a></li>';
    
    // Pages
    $start = max(1, $currentPage - 2);
    $end = min($totalPages, $currentPage + 2);
    
    if ($start > 1) {
        $html .= '<li class="page-item"><a class="page-link" href="' . $url . '?page=1">1</a></li>';
        if ($start > 2) {
            $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
        }
    }
    
    for ($i = $start; $i <= $end; $i++) {
        $active = $i == $currentPage ? 'active' : '';
        $html .= '<li class="page-item ' . $active . '"><a class="page-link" href="' . $url . '?page=' . $i . '">' . $i . '</a></li>';
    }
    
    if ($end < $totalPages) {
        if ($end < $totalPages - 1) {
            $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
        }
        $html .= '<li class="page-item"><a class="page-link" href="' . $url . '?page=' . $totalPages . '">' . $totalPages . '</a></li>';
    }
    
    // Next
    $nextDisabled = $currentPage >= $totalPages ? 'disabled' : '';
    $html .= '<li class="page-item ' . $nextDisabled . '"><a class="page-link" href="' . $url . '?page=' . ($currentPage + 1) . '">Next</a></li>';
    
    $html .= '</ul></nav>';
    
    return [
        'html' => $html,
        'totalPages' => $totalPages,
        'currentPage' => $currentPage,
        'offset' => ($currentPage - 1) * $perPage,
        'limit' => $perPage
    ];
}

/**
 * Check if request is AJAX
 */
function isAjax() {
    return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && 
           strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}

/**
 * Get request method
 */
function getRequestMethod() {
    return strtoupper($_SERVER['REQUEST_METHOD']);
}

/**
 * Check request method
 */
function isPost() {
    return getRequestMethod() === 'POST';
}

function isGet() {
    return getRequestMethod() === 'GET';
}

/**
 * Get POST data
 */
function post($key = null, $default = null) {
    if ($key === null) {
        return $_POST;
    }
    // Don't sanitize CSRF token as it breaks hash comparison
    if ($key === CSRF_TOKEN_NAME || $key === 'csrf_token') {
        return isset($_POST[$key]) ? $_POST[$key] : $default;
    }
    return isset($_POST[$key]) ? sanitize($_POST[$key]) : $default;
}

/**
 * Get GET data
 */
function get($key = null, $default = null) {
    if ($key === null) {
        return $_GET;
    }
    return isset($_GET[$key]) ? sanitize($_GET[$key]) : $default;
}

/**
 * Mask sensitive data
 */
function maskEmail($email) {
    $parts = explode('@', $email);
    $name = $parts[0];
    $domain = $parts[1] ?? '';
    
    $maskedName = substr($name, 0, 2) . str_repeat('*', max(0, strlen($name) - 4)) . substr($name, -2);
    return $maskedName . '@' . $domain;
}

function maskPhone($phone) {
    return substr($phone, 0, 3) . '****' . substr($phone, -3);
}

function maskAccount($account) {
    return str_repeat('*', max(0, strlen($account) - 4)) . substr($account, -4);
}

/**
 * Set/update a setting value
 */
function setSetting($key, $value) {
    $exists = dbFetch("SELECT id FROM settings WHERE setting_key = ?", [$key]);
    if ($exists) {
        dbQuery("UPDATE settings SET setting_value = ? WHERE setting_key = ?", [$value, $key]);
    } else {
        dbInsert('settings', ['setting_key' => $key, 'setting_value' => $value]);
    }
    return true;
}
