<?php
// Enhanced Authentication Helper Functions

/**
 * Check if user is authenticated with remember me functionality
 */
function checkAuthentication() {
    global $pdo;
    
    // Check regular session
    if (isset($_SESSION['admin_id']) && !empty($_SESSION['admin_id'])) {
        return true;
    }
    
    // Check remember me cookie (simplified version without admin_sessions table)
    if (isset($_COOKIE['remember_token']) && !empty($_COOKIE['remember_token'])) {
        $token = $_COOKIE['remember_token'];
        
        try {
            // For now, we'll skip the remember me functionality since admin_sessions table doesn't exist
            // This can be re-enabled once the table is created
            error_log("Remember me token found but admin_sessions table not available");
            // Remove the cookie since we can't validate it
            setcookie('remember_token', '', time() - 3600, '/', '', true, true);
        } catch (Exception $e) {
            error_log("Remember me authentication error: " . $e->getMessage());
        }
    }
    
    return false;
}

/**
 * Alias for checkAuthentication for API compatibility
 */
function isAuthenticated() {
    return checkAuthentication();
}

/**
 * Enhanced admin authentication requirement
 */
function requireAdmin() {
    if (!checkAuthentication()) {
        if (isAjaxRequest()) {
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => 'Authentication required', 'redirect' => 'login.php']);
            exit;
        } else {
            header('Location: login.php');
            exit;
        }
    }
    
    // Check session timeout
    checkSessionTimeout();
}

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

/**
 * Check session timeout
 */
function checkSessionTimeout() {
    global $pdo;
    
    $timeout = getSetting('session_timeout', 30) * 60; // Convert to seconds
    
    if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity']) > $timeout) {
        // Session expired
        logActivity($_SESSION['admin_id'], 'session_timeout', 'Session expired due to inactivity');
        destroySession();
        
        if (isAjaxRequest()) {
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => 'Session expired', 'redirect' => 'login.php']);
            exit;
        } else {
            header('Location: login.php?expired=1');
            exit;
        }
    }
    
    $_SESSION['last_activity'] = time();
}

/**
 * Check admin permissions
 */
function hasPermission($permission) {
    if (!isset($_SESSION['admin_permissions'])) {
        return false;
    }
    
    $permissions = $_SESSION['admin_permissions'];
    
    // Super admin has all permissions
    if (in_array('super_admin', $permissions)) {
        return true;
    }
    
    return in_array($permission, $permissions);
}

/**
 * Require specific permission
 */
function requirePermission($permission) {
    if (!hasPermission($permission)) {
        if (isAjaxRequest()) {
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => 'Insufficient permissions']);
            exit;
        } else {
            header('Location: index.php?error=permission_denied');
            exit;
        }
    }
}

/**
 * Get setting value
 */
function getSetting($key, $default = null) {
    global $pdo;
    
    try {
        $stmt = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = ?");
        $stmt->execute([$key]);
        $result = $stmt->fetch();
        
        return $result ? $result['setting_value'] : $default;
    } catch (Exception $e) {
        return $default;
    }
}

/**
 * Log activity with enhanced details
 */
function logActivity($admin_id, $action, $details = null, $severity = 'medium') {
    global $pdo;
    
    try {
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? '';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        
        // Log to activity_logs
        $stmt = $pdo->prepare("
            INSERT INTO activity_logs (user_id, action, details, ip_address, user_agent, created_at) 
            VALUES (?, ?, ?, ?, ?, NOW())
        ");
        $stmt->execute([$admin_id, $action, $details, $ip_address, $user_agent]);
        
        // Log to security_logs for security-related events
        $security_events = ['login', 'login_failed', 'account_locked', 'password_reset', 'permission_change'];
        if (in_array($action, $security_events)) {
            $stmt = $pdo->prepare("
                INSERT INTO security_logs (admin_id, event_type, ip_address, user_agent, details, severity, created_at) 
                VALUES (?, ?, ?, ?, ?, ?, NOW())
            ");
            $stmt->execute([$admin_id, $action, $ip_address, $user_agent, $details, $severity]);
        }
    } catch (Exception $e) {
        error_log("Activity logging error: " . $e->getMessage());
    }
}

/**
 * Enhanced session destruction
 */
function destroySession() {
    global $pdo;
    
    // Remove remember me token
    if (isset($_COOKIE['remember_token'])) {
        $token = $_COOKIE['remember_token'];
        try {
            $stmt = $pdo->prepare("DELETE FROM admin_sessions WHERE token = ?");
            $stmt->execute([$token]);
        } catch (Exception $e) {
            error_log("Session cleanup error: " . $e->getMessage());
        }
        
        setcookie('remember_token', '', time() - 3600, '/', '', true, true);
    }
    
    // Clear session
    $_SESSION = [];
    session_destroy();
}

/**
 * Password strength validation
 */
function validatePasswordStrength($password) {
    $errors = [];
    
    $min_length = getSetting('password_min_length', 8);
    $require_uppercase = getSetting('password_require_uppercase', 1);
    $require_lowercase = getSetting('password_require_lowercase', 1);
    $require_numbers = getSetting('password_require_numbers', 1);
    $require_symbols = getSetting('password_require_symbols', 1);
    
    if (strlen($password) < $min_length) {
        $errors[] = "Password must be at least {$min_length} characters long";
    }
    
    if ($require_uppercase && !preg_match('/[A-Z]/', $password)) {
        $errors[] = "Password must contain at least one uppercase letter";
    }
    
    if ($require_lowercase && !preg_match('/[a-z]/', $password)) {
        $errors[] = "Password must contain at least one lowercase letter";
    }
    
    if ($require_numbers && !preg_match('/[0-9]/', $password)) {
        $errors[] = "Password must contain at least one number";
    }
    
    if ($require_symbols && !preg_match('/[^A-Za-z0-9]/', $password)) {
        $errors[] = "Password must contain at least one special character";
    }
    
    return $errors;
}

/**
 * Generate secure random password
 */
function generateSecurePassword($length = 12) {
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
    $password = '';
    
    for ($i = 0; $i < $length; $i++) {
        $password .= $chars[random_int(0, strlen($chars) - 1)];
    }
    
    return $password;
}

/**
 * Check if password needs to be changed
 */
function passwordNeedsChange($admin_id) {
    global $pdo;
    
    $expiry_days = getSetting('password_expiry_days', 90);
    if ($expiry_days == 0) {
        return false; // Password never expires
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT updated_at 
            FROM admins 
            WHERE id = ? AND updated_at < DATE_SUB(NOW(), INTERVAL ? DAY)
        ");
        $stmt->execute([$admin_id, $expiry_days]);
        
        return $stmt->fetch() !== false;
    } catch (Exception $e) {
        return false;
    }
}

/**
 * Rate limiting check
 */
function checkRateLimit($identifier, $action, $limit = 5, $window = 900) {
    global $pdo;
    
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*) as attempts 
            FROM activity_logs 
            WHERE (ip_address = ? OR user_id = ?) 
            AND action = ? 
            AND created_at > DATE_SUB(NOW(), INTERVAL ? SECOND)
        ");
        $stmt->execute([$identifier, $identifier, $action, $window]);
        
        $attempts = $stmt->fetch()['attempts'];
        return $attempts < $limit;
    } catch (Exception $e) {
        return true; // Allow on error
    }
}
?>
