<?php
/**
 * Enterprise HRM ERP System - Authentication & Authorization
 * Multi-site, Multi-HR, Role-based System
 */

// Prevent direct access
if (!defined('HRM_ACCESS')) {
    die('Direct access not allowed');
}

/**
 * Start session if not started
 */
function startSession() {
    if (session_status() === PHP_SESSION_NONE) {
        $sessionTimeout = getSetting('SESSION_TIMEOUT', SESSION_LIFETIME);
        ini_set('session.gc_maxlifetime', $sessionTimeout);
        session_name(SESSION_NAME);
        session_start();
        
        // Check session timeout
        if (isset($_SESSION['last_activity']) && 
            (time() - $_SESSION['last_activity']) > $sessionTimeout) {
            session_destroy();
            session_start();
        }
        
        $_SESSION['last_activity'] = time();
    }
}

/**
 * Check if user is logged in
 */
function isLoggedIn() {
    startSession();
    return isset($_SESSION['user_id']); // site_id is optional, can be set later
}

/**
 * Require login
 */
function requireLogin() {
    if (!isLoggedIn()) {
        $_SESSION['redirect_after_login'] = $_SERVER['REQUEST_URI'];
        header('Location: ' . BASE_URL . '/auth/login.php');
        exit;
    }
}

/**
 * Login user
 */
function login($username, $password) {
    try {
        $db = getDB();
        
        // Check if account is locked
        $stmt = $db->prepare("
            SELECT user_id, username, password_hash, user_status, failed_login_attempts, locked_until
            FROM users 
            WHERE username = ? OR email = ?
        ");
        $stmt->execute([$username, $username]);
        $user = $stmt->fetch();
        
        if (!$user) {
            return ['success' => false, 'message' => 'Invalid username or password.'];
        }
        
        // Check if account is locked
        if ($user['locked_until'] && strtotime($user['locked_until']) > time()) {
            $lockedUntil = formatDateTime($user['locked_until']);
            return ['success' => false, 'message' => "Account is locked until {$lockedUntil}. Please try again later."];
        }
        
        // Check if account is inactive
        if ($user['user_status'] !== 'active') {
            return ['success' => false, 'message' => 'Your account is inactive. Please contact administrator.'];
        }
        
        // Verify password
        if (!verifyPassword($password, $user['password_hash'])) {
            // Increment failed login attempts
            $maxAttempts = getSetting('MAX_LOGIN_ATTEMPTS', 5);
            $lockoutDuration = getSetting('LOCKOUT_DURATION', 1800);
            $failedAttempts = $user['failed_login_attempts'] + 1;
            
            if ($failedAttempts >= $maxAttempts) {
                $lockedUntil = date('Y-m-d H:i:s', time() + $lockoutDuration);
                $stmt = $db->prepare("
                    UPDATE users 
                    SET failed_login_attempts = ?, locked_until = ?
                    WHERE user_id = ?
                ");
                $stmt->execute([$failedAttempts, $lockedUntil, $user['user_id']]);
                
                return ['success' => false, 'message' => 'Too many failed login attempts. Account locked for ' . ($lockoutDuration / 60) . ' minutes.'];
            } else {
                $stmt = $db->prepare("UPDATE users SET failed_login_attempts = ? WHERE user_id = ?");
                $stmt->execute([$failedAttempts, $user['user_id']]);
                
                $remaining = $maxAttempts - $failedAttempts;
                return ['success' => false, 'message' => "Invalid username or password. {$remaining} attempt(s) remaining."];
            }
        }
        
        // Reset failed login attempts
        $stmt = $db->prepare("
            UPDATE users 
            SET failed_login_attempts = 0, locked_until = NULL, last_login = NOW()
            WHERE user_id = ?
        ");
        $stmt->execute([$user['user_id']]);
        
        // Get user permissions (if permissions table exists)
        $permissions = [];
        try {
            $stmt = $db->prepare("
                SELECT p.permission_code
                FROM permissions p
                INNER JOIN role_permissions rp ON p.permission_id = rp.permission_id
                INNER JOIN users u ON rp.role_id = u.role_id
                WHERE u.user_id = ?
            ");
            $stmt->execute([$user['user_id']]);
            $permissions = $stmt->fetchAll(PDO::FETCH_COLUMN);
        } catch (Exception $e) {
            // Permissions table doesn't exist, use empty array
            $permissions = [];
        }
        
        // Get user details with role
        $stmt = $db->prepare("
            SELECT u.*, r.role_name, r.role_code
            FROM users u
            INNER JOIN roles r ON u.role_id = r.role_id
            WHERE u.user_id = ?
        ");
        $stmt->execute([$user['user_id']]);
        $userDetails = $stmt->fetch();
        
        // Get user's primary site from user_sites
        $stmt = $db->prepare("
            SELECT s.site_id, s.site_name, s.site_code
            FROM sites s
            INNER JOIN user_sites us ON s.site_id = us.site_id
            WHERE us.user_id = ? AND us.is_primary = 1
            LIMIT 1
        ");
        $stmt->execute([$user['user_id']]);
        $site = $stmt->fetch();
        
        // If no primary site, get first assigned site
        if (!$site) {
            $stmt = $db->prepare("
                SELECT s.site_id, s.site_name, s.site_code
                FROM sites s
                INNER JOIN user_sites us ON s.site_id = us.site_id
                WHERE us.user_id = ?
                LIMIT 1
            ");
            $stmt->execute([$user['user_id']]);
            $site = $stmt->fetch();
        }
        
        // If still no site, use default site (site_id = 1)
        if (!$site) {
            $stmt = $db->prepare("SELECT site_id, site_name, site_code FROM sites WHERE site_id = 1 LIMIT 1");
            $stmt->execute();
            $site = $stmt->fetch();
        }
        
        // Set session variables
        startSession();
        $_SESSION['user_id'] = $user['user_id'];
        $_SESSION['site_id'] = $site['site_id'] ?? 1;
        $_SESSION['username'] = $user['username'];
        $_SESSION['full_name'] = $userDetails['full_name'];
        $_SESSION['role_id'] = $userDetails['role_id'];
        $_SESSION['role_code'] = $userDetails['role_code'];
        $_SESSION['role_name'] = $userDetails['role_name'];
        $_SESSION['site_name'] = $site['site_name'] ?? 'Main Office';
        $_SESSION['site_code'] = $site['site_code'] ?? 'MAIN';
        $_SESSION['permissions'] = $permissions;
        $_SESSION['last_activity'] = time();
        
        // Create session record
        $sessionId = session_id();
        $stmt = $db->prepare("
            INSERT INTO user_sessions (session_id, user_id, ip_address, user_agent)
            VALUES (?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE last_activity = NOW()
        ");
        $stmt->execute([
            $sessionId,
            $user['user_id'],
            $_SERVER['REMOTE_ADDR'] ?? null,
            $_SERVER['HTTP_USER_AGENT'] ?? null
        ]);
        
        // Log audit
        logAudit('LOGIN', 'users', $user['user_id']);
        
        return ['success' => true, 'message' => 'Login successful.'];
        
    } catch (Exception $e) {
        error_log("Login error: " . $e->getMessage());
        return ['success' => false, 'message' => 'An error occurred during login. Please try again.'];
    }
}

/**
 * Logout user
 */
function logout() {
    startSession();
    
    if (isset($_SESSION['user_id'])) {
        // Log audit
        logAudit('LOGOUT', 'users', $_SESSION['user_id']);
        
        // Delete session record
        try {
            $db = getDB();
            $stmt = $db->prepare("DELETE FROM user_sessions WHERE session_id = ?");
            $stmt->execute([session_id()]);
        } catch (Exception $e) {
            error_log("Error deleting session: " . $e->getMessage());
        }
    }
    
    session_destroy();
    header('Location: ' . BASE_URL . '/auth/login.php');
    exit;
}

/**
 * Get current user ID
 */
function getCurrentUserId() {
    return isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
}

/**
 * Get current site ID
 */
function getCurrentSiteId() {
    return isset($_SESSION['site_id']) ? $_SESSION['site_id'] : null;
}

