<?php
/**
 * Authentication Functions
 * GHAMECC Choir Management Platform
 */

// Include database connection
require_once __DIR__ . '/../config/database.php';

// Start session if not already started
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

/**
 * Check if user is logged in
 * @return bool True if user is logged in, false otherwise
 */
function isLoggedIn() {
    return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}

/**
 * Check if user session has timed out due to inactivity
 * Logs out user if inactive for more than the specified timeout period
 * 
 * @param int $timeout Timeout period in seconds (default: 600 seconds = 10 minutes)
 * @return bool True if session is still valid, false if timed out
 */
function checkSessionTimeout($timeout = 600) {
    // Skip check if user is not logged in
    if (!isLoggedIn()) {
        return false;
    }
    
    $currentTime = time();
    
    // Check if last_activity is set
    if (!isset($_SESSION['last_activity'])) {
        // Initialize last_activity if not set
        $_SESSION['last_activity'] = $currentTime;
        return true;
    }
    
    // Calculate time difference
    $timeDiff = $currentTime - $_SESSION['last_activity'];
    
    // If user has been inactive for too long
    if ($timeDiff > $timeout) {
        // Log the timeout
        if (function_exists('logInfo')) {
            logInfo("User session timed out due to inactivity", [
                'user_id' => $_SESSION['user_id'] ?? 'unknown',
                'username' => $_SESSION['username'] ?? 'unknown',
                'inactive_time' => $timeDiff
            ]);
        }
        
        // Log the user out
        logoutUser();
        return false;
    }
    
    // Update last activity time
    $_SESSION['last_activity'] = $currentTime;
    return true;
}

/**
 * Require user to be logged in
 * Redirects to login page if not logged in
 * Also checks for session timeout
 */
function requireLogin() {
    if (!isLoggedIn()) {
        // Store the requested URL for redirection after login
        $_SESSION['redirect_after_login'] = $_SERVER['REQUEST_URI'];
        
        // Redirect to login page
        header("Location: /ghameccapp/login.php");
        exit;
    }
    
    // Check for session timeout
    checkSessionTimeout();
}

/**
 * Require user to have specific role(s)
 * Redirects to access denied page if user doesn't have the required role
 * 
 * @param string|array $requiredRoles Role or array of roles that are allowed
 */
function requireRole($requiredRoles) {
    // First ensure user is logged in
    requireLogin();
    
    // Check if user has the required role
    if (!hasRole($requiredRoles)) {
        // Redirect to access denied page
        header("Location: /ghameccapp/access-denied.php");
        exit;
    }
}

/**
 * Log in a user and set session variables
 */
function loginUser($userId, $username, $fullName, $role, $profileImage = null, $societyId = null, $circuitId = null, $dioceseId = null) {
    // Start session if not already started
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    
    // Set session variables
    $_SESSION['user_id'] = $userId;
    $_SESSION['username'] = $username;
    $_SESSION['full_name'] = $fullName;
    $_SESSION['role'] = $role;
    $_SESSION['profile_image'] = $profileImage;
    $_SESSION['logged_in'] = true;
    $_SESSION['last_activity'] = time();
    
    // Set entity IDs in session if provided
    if ($societyId) {
        $_SESSION['society_id'] = $societyId;
    }
    
    if ($circuitId) {
        $_SESSION['circuit_id'] = $circuitId;
    }
    
    if ($dioceseId) {
        $_SESSION['diocese_id'] = $dioceseId;
    }
    
    // Log the entity IDs for debugging
    if (function_exists('logInfo')) {
        logInfo("User logged in with entity IDs", [
            'user_id' => $userId,
            'society_id' => $societyId,
            'circuit_id' => $circuitId,
            'diocese_id' => $dioceseId
        ]);
    }
    
    // Redirect to appropriate page based on role
    if (in_array($role, ['admin'])) {
        header("Location: admin/index.php");
        exit;
    } elseif (in_array($role, ['diocesan_chairman', 'diocesan_secretary', 'diocesan_dom', 'diocesan_treasurer'])) {
        header("Location: diocese/index.php");
        exit;
    } elseif (in_array($role, ['circuit_chairman', 'circuit_secretary', 'circuit_dom', 'circuit_treasurer'])) {
        header("Location: circuit/index.php");
        exit;
    } elseif (in_array($role, ['choirmaster', 'society_secretary', 'society_treasurer'])) {
        header("Location: society/index.php");
        exit;
    } else {
        // Redirect to main index.php instead of dashboard.php
        header("Location: index.php");
        exit;
    }
}

/**
 * Log user out
 */
function logoutUser() {
    // Clear all session variables
    $_SESSION = array();
    
    // Destroy the session
    session_destroy();
    
    // Redirect to login page
    header("Location: /ghameccapp/login.php");
    exit;
}

/**
 * Check if user has specific role
 * @param string|array $roles Role or array of roles to check
 * @return bool True if user has any of the specified roles
 */
function hasRole($roles) {
    if (!isLoggedIn()) {
        return false;
    }
    
    // Get user ID from session
    $userId = $_SESSION['user_id'] ?? 0;
    if (!$userId) {
        return false;
    }
    
    // First check if role is directly in session
    if (isset($_SESSION['role'])) {
        $sessionRole = $_SESSION['role'];
        
        // Check if the session role matches any of the required roles
        if (is_array($roles)) {
            if (in_array($sessionRole, $roles)) {
                return true;
            }
        } else {
            if ($sessionRole === $roles) {
                return true;
            }
        }
    }
    
    // If we get here, either the session role doesn't exist or doesn't match
    // Try to get the role from the database
    global $conn;
    
    // Check if database connection is available
    if (!$conn) {
        // Log the error if logger is available
        if (function_exists('logError')) {
            logError("Database connection not available in hasRole function", [
                'user_id' => $userId,
                'requested_roles' => is_array($roles) ? implode(',', $roles) : $roles
            ]);
        }
        
        // Return false if no database connection
        return false;
    }
    
    $stmt = $conn->prepare("SELECT r.role_key FROM users u JOIN roles r ON u.role_id = r.id WHERE u.id = ?");
    $stmt->bind_param("i", $userId);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($row = $result->fetch_assoc()) {
        $dbRole = $row['role_key'];
        
        // Update the session with the correct role
        $_SESSION['role'] = $dbRole;
        
        // Check if the database role matches any of the required roles
        if (is_array($roles)) {
            return in_array($dbRole, $roles);
        }
        
        return $dbRole === $roles;
    }
    
    return false;
}

/**
 * Check if the current user has access to a specific entity
 * 
 * @param string $entityType The type of entity (society, circuit, diocese)
 * @param int $entityId The ID of the entity to check access for
 * @return bool True if the user has access, false otherwise
 */
function hasEntityAccess($entityType, $entityId) {
    // Admin and manager have access to all entities
    if (hasRole(['admin', 'manager'])) {
        return true;
    }
    
    // If no entity ID is provided, deny access
    if (empty($entityId)) {
        return false;
    }
    
    // Get current user's role and entity IDs from session
    $userRole = $_SESSION['role'] ?? '';
    $userSocietyId = $_SESSION['society_id'] ?? null;
    $userCircuitId = $_SESSION['circuit_id'] ?? null;
    $userDioceseId = $_SESSION['diocese_id'] ?? null;
    
    // Define role-entity mappings
    $societyRoles = ['choirmaster', 'society_secretary', 'society_treasurer'];
    $circuitRoles = ['circuit_secretary', 'circuit_treasurer'];
    $dioceseRoles = ['diocesan_secretary', 'diocesan_treasurer'];
    
    // Check access based on entity type
    switch ($entityType) {
        case 'society':
            // Society-level roles can only access their own society
            if (in_array($userRole, $societyRoles)) {
                return $userSocietyId == $entityId;
            }
            
            // Circuit-level roles can access all societies in their circuit
            if (in_array($userRole, $circuitRoles) && !empty($userCircuitId)) {
                // Get all societies in the user's circuit
                $societiesInCircuit = fetchRows("SELECT id FROM societies WHERE circuit_id = ?", [$userCircuitId]);
                $societyIds = array_column($societiesInCircuit, 'id');
                return in_array($entityId, $societyIds);
            }
            
            // Diocese-level roles can access all societies in their diocese
            if (in_array($userRole, $dioceseRoles) && !empty($userDioceseId)) {
                // Get all societies in the user's diocese
                $societiesInDiocese = fetchRows("SELECT s.id 
                                               FROM societies s 
                                               JOIN circuits c ON s.circuit_id = c.id 
                                               WHERE c.diocese_id = ?", [$userDioceseId]);
                $societyIds = array_column($societiesInDiocese, 'id');
                return in_array($entityId, $societyIds);
            }
            
            break;
            
        case 'circuit':
            // Circuit-level roles can only access their own circuit
            if (in_array($userRole, $circuitRoles)) {
                return $userCircuitId == $entityId;
            }
            
            // Society-level roles can access their parent circuit
            if (in_array($userRole, $societyRoles) && !empty($userSocietyId)) {
                $societyCircuit = fetchRow("SELECT circuit_id FROM societies WHERE id = ?", [$userSocietyId]);
                return $societyCircuit && $societyCircuit['circuit_id'] == $entityId;
            }
            
            // Diocese-level roles can access all circuits in their diocese
            if (in_array($userRole, $dioceseRoles) && !empty($userDioceseId)) {
                $circuitsInDiocese = fetchRows("SELECT id FROM circuits WHERE diocese_id = ?", [$userDioceseId]);
                $circuitIds = array_column($circuitsInDiocese, 'id');
                return in_array($entityId, $circuitIds);
            }
            
            break;
            
        case 'diocese':
            // Diocese-level roles can only access their own diocese
            if (in_array($userRole, $dioceseRoles)) {
                return $userDioceseId == $entityId;
            }
            
            // Circuit-level roles can access their parent diocese
            if (in_array($userRole, $circuitRoles) && !empty($userCircuitId)) {
                $circuitDiocese = fetchRow("SELECT diocese_id FROM circuits WHERE id = ?", [$userCircuitId]);
                return $circuitDiocese && $circuitDiocese['diocese_id'] == $entityId;
            }
            
            // Society-level roles can access their parent diocese
            if (in_array($userRole, $societyRoles) && !empty($userSocietyId)) {
                $societyCircuit = fetchRow("SELECT circuit_id FROM societies WHERE id = ?", [$userSocietyId]);
                if ($societyCircuit && !empty($societyCircuit['circuit_id'])) {
                    $circuitDiocese = fetchRow("SELECT diocese_id FROM circuits WHERE id = ?", [$societyCircuit['circuit_id']]);
                    return $circuitDiocese && $circuitDiocese['diocese_id'] == $entityId;
                }
            }
            
            break;
    }
    
    // Default: deny access
    return false;
}

/**
 * Check if the current user has access to a specific member
 * 
 * @param int $memberId The ID of the member to check access for
 * @return bool True if the user has access, false otherwise
 */
function hasMemberAccess($memberId) {
    // Admin and manager have access to all members
    if (hasRole(['admin', 'manager'])) {
        return true;
    }
    
    // If no member ID is provided, deny access
    if (empty($memberId)) {
        return false;
    }
    
    // Get current user's role and entity IDs from session
    $userRole = $_SESSION['role'] ?? '';
    $userSocietyId = $_SESSION['society_id'] ?? null;
    $userCircuitId = $_SESSION['circuit_id'] ?? null;
    $userDioceseId = $_SESSION['diocese_id'] ?? null;
    
    // Define role-entity mappings
    $societyRoles = ['choirmaster', 'society_secretary', 'society_treasurer'];
    $circuitRoles = ['circuit_secretary', 'circuit_treasurer'];
    $dioceseRoles = ['diocesan_secretary', 'diocesan_treasurer'];
    
    // Get member's society ID
    $memberSociety = fetchRow("SELECT society_id FROM members WHERE id = ?", [$memberId]);
    
    if (!$memberSociety) {
        return false;
    }
    
    $memberSocietyId = $memberSociety['society_id'];
    
    // Society-level roles can only access members in their society
    if (in_array($userRole, $societyRoles)) {
        return $userSocietyId == $memberSocietyId;
    }
    
    // Circuit-level roles can access members in societies within their circuit
    if (in_array($userRole, $circuitRoles) && !empty($userCircuitId)) {
        $societyCircuit = fetchRow("SELECT circuit_id FROM societies WHERE id = ?", [$memberSocietyId]);
        return $societyCircuit && $societyCircuit['circuit_id'] == $userCircuitId;
    }
    
    // Diocese-level roles can access members in societies within their diocese
    if (in_array($userRole, $dioceseRoles) && !empty($userDioceseId)) {
        $societyCircuit = fetchRow("SELECT circuit_id FROM societies WHERE id = ?", [$memberSocietyId]);
        if ($societyCircuit && !empty($societyCircuit['circuit_id'])) {
            $circuitDiocese = fetchRow("SELECT diocese_id FROM circuits WHERE id = ?", [$societyCircuit['circuit_id']]);
            return $circuitDiocese && $circuitDiocese['diocese_id'] == $userDioceseId;
        }
    }
    
    // Default: deny access
    return false;
}

/**
 * Check if the current user is a member who can act as an employer
 * @return bool True if user can post jobs, false otherwise
 */
function isMemberEmployer() {
    if (!isLoggedIn()) {
        return false;
    }
    
    // Check if user has a member_id (is linked to a member record)
    if (isset($_SESSION['member_id']) && !empty($_SESSION['member_id'])) {
        return true;
    }
    
    // Check if user has admin or manager roles that can post jobs
    if (isset($_SESSION['role'])) {
        $employerRoles = ['admin', 'manager', 'pastor', 'secretary'];
        return in_array($_SESSION['role'], $employerRoles);
    }
    
    return false;
}
