<?php
/**
 * Page Access Control Middleware
 * Save this as: includes/page_access_control.php
 * 
 * This file enforces the page assignments you set up in the Page & Role Assignment system
 */

class PageAccessControl {
    private $conn;
    private $user_id;
    private $role_id;
    private $role_name;
    
    public function __construct($database_connection, $user_id = null) {
        $this->conn = $database_connection;
        $this->user_id = $user_id;
        
        if ($user_id) {
            $this->loadUserDetails();
        }
    }
    
    /**
     * Load user details including role
     */
    private function loadUserDetails() {
        $sql = "SELECT u.role_id, ur.role_name 
                FROM users u 
                INNER JOIN user_roles ur ON u.role_id = ur.role_id 
                WHERE u.user_id = ? AND u.status = 'ACTIVE' AND ur.is_active = 1";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $this->user_id);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();
        
        if ($result) {
            $this->role_id = $result['role_id'];
            $this->role_name = $result['role_name'];
        }
    }
    
    /**
     * Check if user's role has access to a specific page
     */
    public function hasPageAccess($page_name) {
        if (!$this->role_id) {
            return false;
        }
        
        // Super Admin has access to everything
        if ($this->role_name === 'Super Admin') {
            return true;
        }
        
        // Check if page is assigned to user's role
        $sql = "SELECT COUNT(*) as has_access 
                FROM role_page_permissions 
                WHERE role_id = ? AND page_name = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("is", $this->role_id, $page_name);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();
        
        return $result['has_access'] > 0;
    }
    
    /**
     * Get all pages assigned to user's role
     */
    public function getAssignedPages() {
        if (!$this->role_id) {
            return [];
        }
        
        // Super Admin gets all pages
        if ($this->role_name === 'Super Admin') {
            return ['*']; // Indicates all pages
        }
        
        $sql = "SELECT page_name FROM role_page_permissions WHERE role_id = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $this->role_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        $pages = [];
        while ($row = $result->fetch_assoc()) {
            $pages[] = $row['page_name'];
        }
        
        return $pages;
    }
    
    /**
     * Generate menu based on assigned pages
     */
    public function getFilteredMenu() {
        $assigned_pages = $this->getAssignedPages();
        
        // If Super Admin, return all menu items
        if (in_array('*', $assigned_pages)) {
            return $this->getAllMenuItems();
        }
        
        return $this->filterMenuByPages($assigned_pages);
    }
    
    /**
     * Get all available menu items
     */
    private function getAllMenuItems() {
        return [
            [
                'title' => 'Main Menu',
                'type' => 'header'
            ],
            [
                'title' => 'Dashboard',
                'icon' => 'ph-chart-line',
                'url' => 'index.php',
                'type' => 'link'
            ],
            
            // Patient Management Section
            [
                'title' => 'Patient Management',
                'type' => 'header'
            ],
            [
                'title' => 'Patients',
                'icon' => 'ph-user-circle',
                'type' => 'dropdown',
                'id' => 'patientMenu',
                'items' => [
                    ['title' => 'View All Patients', 'url' => 'list_patients.php'],
                    ['title' => 'Register New Patient', 'url' => 'register_patient.php'],
                    ['title' => 'Patient Search', 'url' => 'patient_search.php'],
                    ['title' => 'Patient Records', 'url' => 'patient_records.php'],
                    ['title' => 'Medical History', 'url' => 'medical_history.php'],
                    ['title' => 'Export Patient Data', 'url' => 'export_patients.php']
                ]
            ],
            [
                'title' => 'Patient Visits',
                'icon' => 'ph-calendar-check',
                'type' => 'dropdown',
                'id' => 'visitsMenu',
                'items' => [
                    ['title' => 'All Visits', 'url' => 'list_visits.php'],
                    ['title' => 'Register Visit', 'url' => 'register_visit.php'],
                    ['title' => 'Visit Queue', 'url' => 'visit_queue.php'],
                    ['title' => 'Visit History', 'url' => 'visit_history.php'],
                    ['title' => 'Emergency Visits', 'url' => 'emergency_visits.php']
                ]
            ],
            
            // Clinical Operations Section
            [
                'title' => 'Clinical Operations',
                'type' => 'header'
            ],
            [
                'title' => 'Consultations',
                'icon' => 'ph-chat-circle-dots',
                'type' => 'dropdown',
                'id' => 'consultationsMenu',
                'items' => [
                    ['title' => 'All Consultations', 'url' => 'list_consultations.php'],
                    ['title' => 'Conduct Consultation', 'url' => 'conduct_consultation.php'],
                    ['title' => 'Active Consultations', 'url' => 'active_consultations.php'],
                    ['title' => 'Consultation Queue', 'url' => 'consultation_queue.php'],
                    ['title' => 'Consultation Reports', 'url' => 'consultation_reports.php']
                ]
            ],
            [
                'title' => 'Procedures',
                'icon' => 'ph-syringe',
                'type' => 'dropdown',
                'id' => 'proceduresMenu',
                'items' => [
                    ['title' => 'All Procedures', 'url' => 'list_procedures.php'],
                    ['title' => 'Perform Procedure', 'url' => 'perform_procedure.php'],
                    ['title' => 'Schedule Procedure', 'url' => 'schedule_procedure.php'],
                    ['title' => 'Procedure Types', 'url' => 'procedure_types.php'],
                    ['title' => 'Procedure History', 'url' => 'procedure_history.php']
                ]
            ],
            
            // Laboratory Management Section
            [
                'title' => 'Laboratory Management',
                'type' => 'header'
            ],
            [
                'title' => 'Lab Orders',
                'icon' => 'ph-test-tube',
                'type' => 'dropdown',
                'id' => 'labOrdersMenu',
                'items' => [
                    ['title' => 'All Lab Orders', 'url' => 'list_lab_orders.php'],
                    ['title' => 'Create Lab Order', 'url' => 'create_lab_order.php'],
                    ['title' => 'Pending Orders', 'url' => 'pending_lab_orders.php'],
                    ['title' => 'Enter Results', 'url' => 'enter_lab_results.php'],
                    ['title' => 'Approve Results', 'url' => 'approve_lab_results.php']
                ]
            ],
            [
                'title' => 'Lab Tests & Results',
                'icon' => 'ph-flask',
                'type' => 'dropdown',
                'id' => 'labTestsMenu',
                'items' => [
                    ['title' => 'Test Types', 'url' => 'lab_test_types.php'],
                    ['title' => 'Test Results', 'url' => 'lab_results.php'],
                    ['title' => 'Lab Reports', 'url' => 'lab_reports.php']
                ]
            ],
            
            // Financial Management Section
            [
                'title' => 'Financial Management',
                'type' => 'header'
            ],
            [
                'title' => 'Billing & Invoicing',
                'icon' => 'ph-receipt',
                'type' => 'dropdown',
                'id' => 'billingMenu',
                'items' => [
                    ['title' => 'All Invoices', 'url' => 'list_invoices.php'],
                    ['title' => 'Create Invoice', 'url' => 'create_invoice.php'],
                    ['title' => 'Pending Invoices', 'url' => 'pending_invoices.php'],
                    ['title' => 'Overdue Invoices', 'url' => 'overdue_invoices.php']
                ]
            ],
            [
                'title' => 'Payments',
                'icon' => 'ph-credit-card',
                'type' => 'dropdown',
                'id' => 'paymentsMenu',
                'items' => [
                    ['title' => 'All Payments', 'url' => 'list_payments.php'],
                    ['title' => 'Record Payment', 'url' => 'record_payment.php'],
                    ['title' => 'MPesa Payments', 'url' => 'mpesa_payments.php'],
                    ['title' => 'Payment Reports', 'url' => 'payment_reports.php']
                ]
            ],
            
            // Revenue & Credit Section
            [
                'title' => 'Revenue & Credit',
                'type' => 'header'
            ],
            [
                'title' => 'Revenue Tracking',
                'icon' => 'ph-trending-up',
                'type' => 'dropdown',
                'id' => 'revenueMenu',
                'items' => [
                    ['title' => 'Daily Revenue', 'url' => 'daily_revenue.php'],
                    ['title' => 'Monthly Revenue', 'url' => 'monthly_revenue.php'],
                    ['title' => 'Revenue Analysis', 'url' => 'revenue_analysis.php'],
                    ['title' => 'Financial Reports', 'url' => 'financial_reports.php']
                ]
            ],
            [
                'title' => 'Credit Scoring',
                'icon' => 'ph-chart-line-up',
                'type' => 'dropdown',
                'id' => 'creditMenu',
                'items' => [
                    ['title' => 'Facility Credit Score', 'url' => 'facility_credit_score.php'],
                    ['title' => 'Credit History', 'url' => 'credit_history.php']
                ]
            ],
            
            // User Management Section
            [
                'title' => 'User Management',
                'type' => 'header'
            ],
            [
                'title' => 'Users & Staff',
                'icon' => 'ph-users',
                'type' => 'dropdown',
                'id' => 'userMenu',
                'items' => [
                    ['title' => 'View All Users', 'url' => 'list_users.php'],
                    ['title' => 'Add User/Staff', 'url' => 'add_user.php'],
                    ['title' => 'Role Assignment', 'url' => 'access_control.php'],
                    ['title' => 'Page Assignment', 'url' => 'page_role_assignment.php'],
                    ['title' => 'User Permissions', 'url' => 'role_permissions.php']
                ]
            ],
            
            // Reports & Analytics Section
            [
                'title' => 'Reports & Analytics',
                'type' => 'header'
            ],
            [
                'title' => 'Clinical Reports',
                'icon' => 'ph-chart-bar',
                'type' => 'dropdown',
                'id' => 'clinicalReportsMenu',
                'items' => [
                    ['title' => 'Patient Statistics', 'url' => 'patient_statistics.php'],
                    ['title' => 'Doctor Performance', 'url' => 'doctor_performance_report.php'],
                    ['title' => 'Lab Statistics', 'url' => 'lab_statistics.php']
                ]
            ],
            
            // System Administration Section
            [
                'title' => 'System Administration',
                'type' => 'header'
            ],
            [
                'title' => 'System Settings',
                'icon' => 'ph-gear',
                'type' => 'dropdown',
                'id' => 'settingsMenu',
                'items' => [
                    ['title' => 'System Configuration', 'url' => 'system_settings.php'],
                    ['title' => 'Activity Logs', 'url' => 'activity_logs.php'],
                    ['title' => 'Backup & Restore', 'url' => 'backup_restore.php']
                ]
            ],
            
            // My Account Section
            [
                'title' => 'My Account',
                'type' => 'header'
            ],
            [
                'title' => 'My Profile',
                'icon' => 'ph-user',
                'url' => 'profile.php',
                'type' => 'link'
            ],
            [
                'title' => 'Change Password',
                'icon' => 'ph-lock-key',
                'url' => 'change_password.php',
                'type' => 'link'
            ],
            [
                'title' => 'Logout',
                'icon' => 'ph-sign-out',
                'url' => 'logout.php',
                'type' => 'link',
                'class' => 'text-danger'
            ]
        ];
    }
    
    /**
     * Filter menu items based on assigned pages
     */
    private function filterMenuByPages($assigned_pages) {
        $all_menu = $this->getAllMenuItems();
        $filtered_menu = [];
        
        foreach ($all_menu as $menu_item) {
            // Always include headers and account sections
            if ($menu_item['type'] === 'header') {
                // Check if any pages in this section are assigned
                $section_has_pages = $this->sectionHasAssignedPages($menu_item['title'], $assigned_pages, $all_menu);
                if ($section_has_pages || in_array($menu_item['title'], ['Main Menu', 'My Account'])) {
                    $filtered_menu[] = $menu_item;
                }
                continue;
            }
            
            // Always include dashboard and account links
            if ($menu_item['type'] === 'link' && 
                in_array($menu_item['url'], ['index.php', 'profile.php', 'change_password.php', 'logout.php'])) {
                $filtered_menu[] = $menu_item;
                continue;
            }
            
            // For regular links, check if page is assigned
            if ($menu_item['type'] === 'link' && isset($menu_item['url'])) {
                if (in_array($menu_item['url'], $assigned_pages)) {
                    $filtered_menu[] = $menu_item;
                }
                continue;
            }
            
            // For dropdowns, filter sub-items
            if ($menu_item['type'] === 'dropdown' && isset($menu_item['items'])) {
                $filtered_items = [];
                foreach ($menu_item['items'] as $sub_item) {
                    if (isset($sub_item['url']) && in_array($sub_item['url'], $assigned_pages)) {
                        $filtered_items[] = $sub_item;
                    }
                }
                
                // Only include dropdown if it has accessible sub-items
                if (!empty($filtered_items)) {
                    $menu_item['items'] = $filtered_items;
                    $filtered_menu[] = $menu_item;
                }
            }
        }
        
        return $filtered_menu;
    }
    
    /**
     * Check if a section has any assigned pages
     */
    private function sectionHasAssignedPages($section_title, $assigned_pages, $all_menu) {
        $in_section = false;
        
        foreach ($all_menu as $menu_item) {
            if ($menu_item['type'] === 'header' && $menu_item['title'] === $section_title) {
                $in_section = true;
                continue;
            }
            
            if ($menu_item['type'] === 'header' && $in_section) {
                break; // We've moved to the next section
            }
            
            if ($in_section) {
                // Check if this menu item has assigned pages
                if ($menu_item['type'] === 'link' && isset($menu_item['url'])) {
                    if (in_array($menu_item['url'], $assigned_pages)) {
                        return true;
                    }
                }
                
                if ($menu_item['type'] === 'dropdown' && isset($menu_item['items'])) {
                    foreach ($menu_item['items'] as $sub_item) {
                        if (isset($sub_item['url']) && in_array($sub_item['url'], $assigned_pages)) {
                            return true;
                        }
                    }
                }
            }
        }
        
        return false;
    }
    
    /**
     * Log access attempt
     */
    public function logAccess($page_name, $status = 'ALLOWED') {
        if (!$this->user_id) return;
        
        $sql = "INSERT INTO activity_log (user_id, action, module, record_type, new_values, ip_address, user_agent) 
                VALUES (?, 'PAGE_ACCESS', 'ACCESS_CONTROL', 'PAGE', ?, ?, ?)";
        $stmt = $this->conn->prepare($sql);
        $new_values = json_encode(['page' => $page_name, 'status' => $status, 'role' => $this->role_name]);
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
        $stmt->bind_param("isss", $this->user_id, $new_values, $ip_address, $user_agent);
        $stmt->execute();
    }
    
    /**
     * Get user's role name
     */
    public function getRoleName() {
        return $this->role_name;
    }
}

/**
 * Helper Functions
 */

/**
 * Protect a page - use this at the top of each page
 */
function protectPage($conn, $required_page = null) {
    if (!isset($_SESSION['user_id'])) {
        header('Location: login.php');
        exit();
    }
    
    $page_name = $required_page ?? basename($_SERVER['PHP_SELF']);
    $pac = new PageAccessControl($conn, $_SESSION['user_id']);
    
    // Check if user has access to this page
    if (!$pac->hasPageAccess($page_name)) {
        $pac->logAccess($page_name, 'DENIED');
        header('Location: access_denied.php');
        exit();
    }
    
    $pac->logAccess($page_name, 'ALLOWED');
    return $pac;
}

/**
 * Generate filtered menu for current user
 */
function generateUserMenu($conn, $user_id = null) {
    $user_id = $user_id ?? $_SESSION['user_id'] ?? null;
    
    if (!$user_id) {
        return '';
    }
    
    $pac = new PageAccessControl($conn, $user_id);
    $menu_items = $pac->getFilteredMenu();
    
    return renderMenuItems($menu_items);
}

/**
 * Render menu items as HTML
 */
function renderMenuItems($menu_items) {
    $current_page = basename($_SERVER['PHP_SELF']);
    $html = '';
    
    foreach ($menu_items as $item) {
        if ($item['type'] === 'header') {
            $html .= '<li class="menu-title"><span data-key="t-menu">' . htmlspecialchars($item['title']) . '</span></li>';
        } elseif ($item['type'] === 'link') {
            $isActive = ($item['url'] === $current_page);
            $html .= '<li class="nav-item">';
            $html .= '<a class="nav-link menu-link' . ($isActive ? ' active' : '') . '" href="' . htmlspecialchars($item['url']) . '">';
            if (isset($item['icon'])) {
                $html .= '<i class="' . htmlspecialchars($item['icon']) . '"></i> ';
            }
            $html .= '<span data-key="t-' . strtolower(str_replace(' ', '-', $item['title'])) . '">' . htmlspecialchars($item['title']) . '</span>';
            $html .= '</a></li>';
            
        } elseif ($item['type'] === 'dropdown') {
            $hasActiveSubItem = false;
            if (isset($item['items'])) {
                foreach ($item['items'] as $subItem) {
                    if (isset($subItem['url']) && $subItem['url'] === $current_page) {
                        $hasActiveSubItem = true;
                        break;
                    }
                }
            }
            
            $html .= '<li class="nav-item">';
            $html .= '<a class="nav-link menu-link' . ($hasActiveSubItem ? ' active' : '') . '" href="#' . $item['id'] . '" data-bs-toggle="collapse" role="button">';
            if (isset($item['icon'])) {
                $html .= '<i class="' . htmlspecialchars($item['icon']) . '"></i> ';
            }
            $html .= '<span data-key="t-' . strtolower(str_replace(' ', '-', $item['title'])) . '">' . htmlspecialchars($item['title']) . '</span>';
            $html .= '</a>';
            
            $html .= '<div class="collapse menu-dropdown' . ($hasActiveSubItem ? ' show' : '') . '" id="' . $item['id'] . '">';
            $html .= '<ul class="nav nav-sm flex-column">';
            
            if (isset($item['items'])) {
                foreach ($item['items'] as $subItem) {
                    $isSubActive = (isset($subItem['url']) && $subItem['url'] === $current_page);
                    $html .= '<li class="nav-item">';
                    $html .= '<a href="' . htmlspecialchars($subItem['url']) . '" class="nav-link' . ($isSubActive ? ' active' : '') . '">';
                    $html .= htmlspecialchars($subItem['title']);
                    $html .= '</a></li>';
                }
            }
            
            $html .= '</ul></div></li>';
        }
    }
    
    return $html;
}

/**
 * Check if user has access to specific page (without redirecting)
 */
function checkPageAccess($conn, $page_name, $user_id = null) {
    $user_id = $user_id ?? $_SESSION['user_id'] ?? null;
    
    if (!$user_id) {
        return false;
    }
    
    $pac = new PageAccessControl($conn, $user_id);
    return $pac->hasPageAccess($page_name);
}

/**
 * Create access denied page
 */
if (!function_exists('createAccessDeniedPage')) {
    function createAccessDeniedPage() {
        return '<!DOCTYPE html>
<html>
<head>
    <title>Access Denied - Healthcare EMR</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { font-family: Arial, sans-serif; background: #f8fafc; margin: 0; padding: 50px; }
        .container { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); text-align: center; }
        .error-icon { font-size: 4rem; color: #ef4444; margin-bottom: 20px; }
        h1 { color: #1f2937; margin-bottom: 10px; }
        p { color: #6b7280; margin-bottom: 30px; }
        .btn { background: #3b82f6; color: white; padding: 12px 24px; border: none; border-radius: 6px; text-decoration: none; display: inline-block; }
        .btn:hover { background: #2563eb; }
    </style>
</head>
<body>
    <div class="container">
        <div class="error-icon">🚫</div>
        <h1>Access Denied</h1>
        <p>You do not have permission to access this page. Please contact your administrator if you believe this is an error.</p>
        <a href="index.php" class="btn">Return to Dashboard</a>
    </div>
</body>
</html>';
    }
}

/**
 * EXAMPLE USAGE:
 * 
 * 1. At the top of each page (e.g., list_patients.php):
 * 
 * <?php
 * session_start();
 * include 'layouts/dbconn.php';
 * include 'includes/page_access_control.php';
 * 
 * // Protect this page
 * $pac = protectPage($conn);
 * ?>
 * 
 * 2. In your layouts/menu.php file:
 * 
 * <?php
 * include_once 'includes/page_access_control.php';
 * echo generateUserMenu($conn, $_SESSION['user_id']);
 * ?>
 * 
 * 3. To check access conditionally:
 * 
 * <?php if (checkPageAccess($conn, 'add_user.php')): ?>
 *     <a href="add_user.php" class="btn btn-primary">Add User</a>
 * <?php endif; ?>
 */
?>