<?php
require_once __DIR__ . '/aclhelper.php';

function abox_menu_value(array $row, array $keys, string $default = ''): string
{
    foreach ($keys as $key) {
        if (isset($row[$key]) && trim((string)$row[$key]) !== '') {
            return trim((string)$row[$key]);
        }
    }
    return $default;
}

function abox_menu_parent_id(array $row): int
{
    foreach (['parent_id', 'parent', 'parent_menu_id', 'menu_parent_id'] as $key) {
        if (isset($row[$key]) && (int)$row[$key] > 0) {
            return (int)$row[$key];
        }
    }
    return 0;
}

function abox_menu_sort_value(array $row): int
{
    foreach (['sort_order', 'ordering', 'menu_order', 'sequence', 'display_order', 'id'] as $key) {
        if (isset($row[$key])) {
            return (int)$row[$key];
        }
    }
    return 0;
}

function abox_menu_link(array $row): string
{
    $link = abox_menu_value($row, ['menu_link', 'url', 'link', 'href'], '#');
    $link = $link === '' ? '#' : $link;

    // Keep grouping, active-state and compatibility rules based on the
    // original HRMS-relative path after moving files into modules/hrms.
    return preg_replace('#^/?modules/hrms/#i', '', $link) ?? $link;
}

function abox_menu_href(array $row): string
{
    // Render the stored URL unchanged so links continue to open the module path.
    $link = abox_menu_value($row, ['menu_link', 'url', 'link', 'href'], '#');
    $link = $link === '' ? '#' : $link;
    if ($link === '#' || preg_match('#^https?://#i', $link)) {
        return $link;
    }

    return '/' . ltrim($link, '/');
}
function abox_allowed_menu_tree(): array
{
    global $con;
    $user = current_user() ?: [];
    $roleId = (int)($user['role_id'] ?? 0);
    if (!$roleId || !isset($con)) {
        return [];
    }

    $rows = [];
    if ($roleId === 1) {
        $result = $con->query('SELECT m.* FROM jos_admin_menus m WHERE m.status=1');
        if ($result) {
            while ($row = $result->fetch_assoc()) {
                $rows[] = $row;
            }
            $result->free();
        }
    } else {
        $stmt = $con->prepare('SELECT m.* FROM jos_admin_menus m INNER JOIN jos_admin_rolemenus rm ON rm.menu_id=m.id AND rm.role_id=? AND rm.status=1 AND rm.can_view=1 WHERE m.status=1 AND COALESCE(m.show_in_menu,1)=1');
        if ($stmt) {
            $stmt->bind_param('i', $roleId);
            $stmt->execute();
            $result = $stmt->get_result();
            while ($row = $result->fetch_assoc()) {
                $rows[] = $row;
            }
            $stmt->close();
        }
    }

    $rows = array_values(array_filter($rows, function ($row) {
        $link = ltrim(abox_menu_link($row), '/');
        return $link !== 'dashboard.php' && abox_menu_value($row, ['menu_name', 'title', 'name'], '') !== '';
    }));

    // Policy Automator starts as a Super User control-plane page. A normal
    // jos_admin_menus/rolemenu record can replace this bootstrap entry later.
    if ($roleId === 1) {
        $hasPolicyAutomator = false;
        foreach ($rows as $row) {
            if (normalize_link(abox_menu_link($row)) === 'payroll-config/policy-automator.php') {
                $hasPolicyAutomator = true;
                break;
            }
        }
        if (!$hasPolicyAutomator) {
            $rows[] = [
                'id' => -301,
                'menu_name' => 'Policy Automator',
                'menu_link' => 'payroll-config/policy-automator.php',
                'remarks' => 'Attendance and payroll policy automation',
                'icon_class' => 'fa-solid fa-diagram-project',
                'sort_order' => 5,
                'status' => 1,
                'show_in_menu' => 1,
            ];
        }
    }

    if ($roleId > 0) {
        $organisationParentId = 0;
        $hasPayrollLocation = false;
        $hasEmployeeCount = false;
        $hasFinancialYear = false;
        $hasJobType = false;
        $hasShiftType = false;
        $hasGeofenceArea = false;
        foreach ($rows as $row) {
            $nameUpper = strtoupper(abox_menu_value($row, ['menu_name', 'title', 'name'], ''));
            $link = strtolower(ltrim(abox_menu_link($row), '/'));
            if ($nameUpper === 'ORGANISATION SETTINGS' || $nameUpper === 'ORGANIZATION SETTINGS' || $link === '#organisation-settings') {
                $organisationParentId = (int)($row['id'] ?? 0);
            }
            if ($nameUpper === 'PAYROLL LOCATION' || $nameUpper === 'PAYROLL LOCATIONS' || $link === 'organization/payroll-location.php' || $link === 'payroll-config/payroll-locations.php') {
                $hasPayrollLocation = true;
            }
            if ($nameUpper === 'EMPLOYEE COUNT' || $link === 'organization/employee-count.php' || strpos($link, 'layout=employeecountform') !== false) {
                $hasEmployeeCount = true;
            }
            if ($nameUpper === 'FINANCIAL YEAR' || $link === 'organization/financial-year.php' || strpos($link, 'layout=finacialyearform') !== false || strpos($link, 'layout=financialyearform') !== false) {
                $hasFinancialYear = true;
            }
            if (($nameUpper === 'ADD JOB TYPE' || $nameUpper === 'ADD JOBTYPE' || $nameUpper === 'JOB TYPE' || $nameUpper === 'JOB TYPES' || $link === 'organization/job-types.php' || strpos($link, 'layout=jobtypeform') !== false || strpos($link, 'jobtype') !== false) && abox_menu_parent_id($row) === $organisationParentId) {
                $hasJobType = true;
            }
            if (($nameUpper === 'ADD SHIFT TYPE' || $nameUpper === 'ADD SHIFTTYPE' || $nameUpper === 'SHIFT TYPE' || $nameUpper === 'SHIFT TYPES' || $link === 'organization/shift-types.php' || strpos($link, 'layout=addshifttype') !== false || strpos($link, 'addshifttype') !== false || strpos($link, 'shift-types.php') !== false) && abox_menu_parent_id($row) === $organisationParentId) {
                $hasShiftType = true;
            }
            if ($nameUpper === 'CONFIGURATION GEOFENCE AREA' || $nameUpper === 'GEOFENCE AREA' || $nameUpper === 'GEOFENCE AREAS' || $link === 'organization/geofence-areas.php' || strpos($link, 'layout=geofence') !== false) {
                $hasGeofenceArea = true;
            }
        }
        if ($organisationParentId > 0) {
            $hasJobType = false;
            $hasShiftType = false;
            foreach ($rows as $row) {
                $nameUpper = strtoupper(abox_menu_value($row, ['menu_name', 'title', 'name'], ''));
                $link = strtolower(ltrim(abox_menu_link($row), '/'));
                if (($nameUpper === 'ADD JOB TYPE' || $nameUpper === 'ADD JOBTYPE' || $nameUpper === 'JOB TYPE' || $nameUpper === 'JOB TYPES' || $link === 'organization/job-types.php' || strpos($link, 'layout=jobtypeform') !== false || strpos($link, 'jobtype') !== false) && abox_menu_parent_id($row) === $organisationParentId) {
                    $hasJobType = true;
                    break;
                }
            }
            foreach ($rows as $row) {
                $nameUpper = strtoupper(abox_menu_value($row, ['menu_name', 'title', 'name'], ''));
                $link = strtolower(ltrim(abox_menu_link($row), '/'));
                if (($nameUpper === 'ADD SHIFT TYPE' || $nameUpper === 'ADD SHIFTTYPE' || $nameUpper === 'SHIFT TYPE' || $nameUpper === 'SHIFT TYPES' || $link === 'organization/shift-types.php' || strpos($link, 'layout=addshifttype') !== false || strpos($link, 'addshifttype') !== false || strpos($link, 'shift-types.php') !== false) && abox_menu_parent_id($row) === $organisationParentId) {
                    $hasShiftType = true;
                    break;
                }
            }
        }
        if (!$hasPayrollLocation && $organisationParentId > 0) {
            $rows[] = [
                'id' => -117001,
                'menu_name' => 'Payroll Location',
                'menu_link' => 'organization/payroll-location.php',
                'url' => 'organization/payroll-location.php',
                'parent_id' => $organisationParentId,
                'icon' => 'fa-solid fa-map-location-dot',
                'remarks' => 'Manage payroll locations.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 117,
            ];
        }
        if (!$hasEmployeeCount && $organisationParentId > 0) {
            $rows[] = [
                'id' => -117002,
                'menu_name' => 'Employee Count',
                'menu_link' => 'organization/employee-count.php',
                'url' => 'organization/employee-count.php',
                'parent_id' => $organisationParentId,
                'icon' => 'fa-solid fa-users',
                'remarks' => 'Manage employee license counts.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 118,
            ];
        }
        if (!$hasFinancialYear && $organisationParentId > 0) {
            $rows[] = [
                'id' => -117003,
                'menu_name' => 'Financial Year',
                'menu_link' => 'organization/financial-year.php',
                'url' => 'organization/financial-year.php',
                'parent_id' => $organisationParentId,
                'icon' => 'fa-solid fa-calendar-days',
                'remarks' => 'Manage payroll financial years.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 120,
            ];
        }
        if (!$hasJobType && $organisationParentId > 0) {
            $rows[] = [
                'id' => -117004,
                'menu_name' => 'Add Job Type',
                'menu_link' => 'organization/job-types.php',
                'url' => 'organization/job-types.php',
                'parent_id' => $organisationParentId,
                'icon' => 'fa-solid fa-briefcase',
                'remarks' => 'Manage job type masters.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 121,
            ];
        }
        if (!$hasShiftType && $organisationParentId > 0) {
            $rows[] = [
                'id' => -117005,
                'menu_name' => 'Add Shift Type',
                'menu_link' => 'organization/shift-types.php',
                'url' => 'organization/shift-types.php',
                'parent_id' => $organisationParentId,
                'icon' => 'fa-solid fa-layer-group',
                'remarks' => 'Manage shift type masters.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 122,
            ];
        }
        if (!$hasGeofenceArea) {
            $rows[] = [
                'id' => -117006,
                'menu_name' => 'Configuration Geofence Area',
                'menu_link' => 'organization/geofence-areas.php',
                'url' => 'organization/geofence-areas.php',
                'parent_id' => 0,
                'section' => 'D. Masters',
                'icon' => 'fa-solid fa-draw-polygon',
                'remarks' => 'Manage configuration geofence areas.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 126,
                'orderby' => 126,
            ];
        }
        if ($organisationParentId > 0) {
            foreach ($rows as &$row) {
                $nameUpper = strtoupper(abox_menu_value($row, ['menu_name', 'title', 'name'], ''));
                $link = strtolower(ltrim(abox_menu_link($row), '/'));
                if ($nameUpper === 'PAYROLL LOCATION' || $nameUpper === 'PAYROLL LOCATIONS' || $link === 'organization/payroll-location.php' || $link === 'payroll-config/payroll-locations.php') {
                    $row['parent_id'] = $organisationParentId;
                    $row['menu_name'] = 'Payroll Location';
                    $row['menu_link'] = 'organization/payroll-location.php';
                    $row['url'] = 'organization/payroll-location.php';
                    $row['sort_order'] = 117;
                    $row['orderby'] = 117;
                }
                if ($nameUpper === 'EMPLOYEE COUNT' || $link === 'organization/employee-count.php' || strpos($link, 'layout=employeecountform') !== false) {
                    $row['parent_id'] = $organisationParentId;
                    $row['menu_name'] = 'Employee Count';
                    $row['menu_link'] = 'organization/employee-count.php';
                    $row['url'] = 'organization/employee-count.php';
                    $row['sort_order'] = 118;
                    $row['orderby'] = 118;
                }
                if ($nameUpper === 'FINANCIAL YEAR' || $link === 'organization/financial-year.php' || strpos($link, 'layout=finacialyearform') !== false || strpos($link, 'layout=financialyearform') !== false) {
                    $row['parent_id'] = $organisationParentId;
                    $row['menu_name'] = 'Financial Year';
                    $row['menu_link'] = 'organization/financial-year.php';
                    $row['url'] = 'organization/financial-year.php';
                    $row['sort_order'] = 120;
                    $row['orderby'] = 120;
                }
                if ($nameUpper === 'ADD JOB TYPE' || $nameUpper === 'ADD JOBTYPE' || $nameUpper === 'JOB TYPE' || $nameUpper === 'JOB TYPES' || $link === 'organization/job-types.php' || strpos($link, 'layout=jobtypeform') !== false || strpos($link, 'jobtype') !== false) {
                    $row['parent_id'] = $organisationParentId;
                    $row['menu_name'] = 'Add Job Type';
                    $row['menu_link'] = 'organization/job-types.php';
                    $row['url'] = 'organization/job-types.php';
                    $row['sort_order'] = 121;
                    $row['orderby'] = 121;
                }
                if ($nameUpper === 'ADD SHIFT TYPE' || $nameUpper === 'ADD SHIFTTYPE' || $nameUpper === 'SHIFT TYPE' || $nameUpper === 'SHIFT TYPES' || $link === 'organization/shift-types.php' || strpos($link, 'layout=addshifttype') !== false || strpos($link, 'addshifttype') !== false || strpos($link, 'shift-types.php') !== false) {
                    $row['parent_id'] = $organisationParentId;
                    $row['menu_name'] = 'Add Shift Type';
                    $row['menu_link'] = 'organization/shift-types.php';
                    $row['url'] = 'organization/shift-types.php';
                    $row['sort_order'] = 122;
                    $row['orderby'] = 122;
                }
                if ($nameUpper === 'CONFIGURATION GEOFENCE AREA' || $nameUpper === 'GEOFENCE AREA' || $nameUpper === 'GEOFENCE AREAS' || $link === 'organization/geofence-areas.php' || strpos($link, 'layout=geofence') !== false) {
                    $row['parent_id'] = 0;
                    $row['section'] = 'D. Masters';
                    $row['menu_name'] = 'Configuration Geofence Area';
                    $row['menu_link'] = 'organization/geofence-areas.php';
                    $row['url'] = 'organization/geofence-areas.php';
                    $row['sort_order'] = 126;
                    $row['orderby'] = 126;
                }
            }
            unset($row);
        }
    }

    if ($roleId === 1) {
        $hasAdditionalRateConfiguration = false;
        foreach ($rows as $row) {
            $link = strtolower(ltrim(abox_menu_link($row), '/'));
            if ($link === 'salary-config/additional-rate-configuration.php') {
                $hasAdditionalRateConfiguration = true;
                break;
            }
        }
        if (!$hasAdditionalRateConfiguration) {
            $rows[] = [
                'id' => -125060,
                'menu_name' => 'Additional Rate Configuration',
                'menu_link' => 'salary-config/additional-rate-configuration.php',
                'url' => 'salary-config/additional-rate-configuration.php',
                'parent_id' => 0,
                'section' => 'Salary Config',
                'icon' => 'fa-solid fa-coins',
                'remarks' => 'Maintain employee monthly OT and allowance rates.',
                'status' => 1,
                'show_in_menu' => 1,
                'sort_order' => 60,
                'orderby' => 60,
            ];
        }
    }

    usort($rows, fn($a, $b) => abox_menu_sort_value($a) <=> abox_menu_sort_value($b));

    $byParent = [];
    foreach ($rows as $row) {
        $byParent[abox_menu_parent_id($row)][] = $row;
    }

    $syntheticTop = [];
    $syntheticChildren = [];
    $groupMap = [
        'Masters' => ['id' => -10, 'remarks' => 'Primary HR master data', 'names' => ['EMPLOYEE REGISTRATION', 'EMPLOYEES', 'DEPARTMENTS', 'ADD DEPARTMENT', 'DESIGNATIONS', 'LOCATIONS', 'QUALIFICATIONS', 'ADD QUALIFICATION', 'EMPLOYEE STATUS', 'ADD EMPLOYMENT STATUS', 'CATEGORIES', 'ADD CATEGORY', 'SUB BRANCHES', 'ADD SUB BRANCH', 'HOLIDAYS', 'BANK TYPES', 'ADD DOCUMENT TYPES', 'DOCUMENT TYPES', 'ADD SKILL LEVELS', 'SKILL LEVELS', 'ADD SHIFT', 'ADD EMPLOYEE SHIFTS', 'EMPLOYEE SHIFTS'], 'prefixes' => ['masters/employee-registration', 'masters/employees', 'masters/departments', 'masters/designations', 'masters/locations', 'masters/qualifications', 'masters/employee-status', 'masters/categories', 'masters/sub-branches', 'masters/holidays', 'masters/bank-types', 'masters/document-types', 'masters/skill-levels', 'masters/employee-shifts', 'modules/crm/masters/']],
        'D. Masters' => ['id' => -20, 'remarks' => 'Daily attendance masters', 'names' => ['ATTENDANCE SETTINGS', 'LEAVE SETTINGS', 'PAYROLL SETTINGS', 'FORM 16 CONFIGURATION', 'FORM 16 TAX SLAB', 'FORM 16 COMPONENT MASTER', 'ORGANISATION SETTINGS', 'ORGANIZATION SETTINGS', 'RESET DATA', 'RESET WEB CONSOLE', 'COMPANY INFORMATION', 'PAYROLL LOCATION', 'PAYROLL LOCATIONS', 'EMPLOYEE COUNT', 'FINANCIAL YEAR', 'ADD JOB TYPE', 'ADD JOBTYPE', 'JOB TYPE', 'JOB TYPES', 'ADD SHIFT TYPE', 'ADD SHIFTTYPE', 'SHIFT TYPE', 'SHIFT TYPES', 'CONFIGURATION GEOFENCE AREA', 'GEOFENCE AREA', 'GEOFENCE AREAS', 'USER MANAGER', 'ADD LEAVE CATEGORY', 'CALENDAR CONFIGURATION', 'PF CONFIGURATION', 'GRATUITY CONFIGURATION', 'ESI CONFIGURATION', 'P-TAX CONFIGURATION', 'TDS SLAB CONFIGURATION', 'MLWF CONFIGURATION', 'SCHEDULE REPORT CONFIGURATION', 'ORGANIZATION SALARY CONFIGURATION', 'ECR CONFIGURATION', 'SHIFTS', 'LEAVE TYPES', 'ATTENDANCE RULES'], 'prefixes' => ['attendance/', 'leave/', 'form16/', 'organization/', 'reset-data/', 'settings/user-manager', 'masters/shifts', 'masters/leave-types', 'masters/attendance-rules']],
        'Salary Config' => ['id' => -25, 'remarks' => 'Employee salary configuration and reports', 'names' => ['SALARY CONFIG', 'ADD GROSS SALARY', 'GROSS SALARY REPORT'], 'prefixes' => ['salary-config/']],
        'Payroll Config' => ['id' => -30, 'remarks' => 'Salary and payroll configuration', 'names' => ['SALARY HEADS', 'PAY GROUPS', 'PAYROLL LOCATIONS', 'STATUTORY SETTINGS'], 'prefixes' => ['payroll-config/']],
        'Operations' => ['id' => -40, 'remarks' => 'Daily HR operations', 'names' => ['ATTENDANCE', 'MANUAL ATTENDANCE', 'SHIFT ASSIGN', 'LEAVE REQUESTS'], 'prefixes' => ['operations/', 'modules/crm/operations/']],
        'Payroll' => ['id' => -50, 'remarks' => 'Payroll processing', 'names' => ['PAYROLL PROCESS', 'SALARY SLIP', 'PAYROLL LOCK', 'BANK EXPORT'], 'prefixes' => ['payroll/']],
        'Reports' => ['id' => -60, 'remarks' => 'HR and payroll reports', 'names' => ['ATTENDANCE REPORT', 'MIS REPORT', 'EMPLOYEE REPORT', 'PAYROLL REPORT', 'STATUTORY REPORT'], 'prefixes' => ['reports/', 'modules/crm/reports/']],
    ];

    foreach ($rows as $row) {
        $nameUpper = strtoupper(abox_menu_value($row, ['menu_name', 'title', 'name'], ''));
        $linkLower = strtolower(ltrim(abox_menu_link($row), '/'));
        foreach ($groupMap as $groupName => $group) {
            $matched = in_array($nameUpper, $group['names'], true);
            if (!$matched) {
                foreach ($group['prefixes'] as $prefix) {
                    if (substr($linkLower, 0, strlen($prefix)) === $prefix) {
                        $matched = true;
                        break;
                    }
                }
            }
            if ($matched) {
                if ($groupName === 'Salary Config' && $nameUpper === 'SALARY CONFIG') {
                    break;
                }
                $syntheticChildren[$group['id']][] = $row;
                break;
            }
        }
    }

    foreach ($groupMap as $groupName => $group) {
        if (!empty($syntheticChildren[$group['id']])) {
            $syntheticTop[] = ['id' => $group['id'], 'menu_name' => $groupName, 'menu_link' => '#', 'remarks' => $group['remarks'], 'sort_order' => abs($group['id'])];
        }
    }

    if ($syntheticTop) {
        return ['top' => $syntheticTop, 'children' => $syntheticChildren];
    }

    return ['top' => $byParent[0] ?? $rows, 'children' => $byParent];
}

function render_desktop_admin_menu(?string $activeLink = null): void
{
    $tree = abox_allowed_menu_tree();
    $activeLink = normalize_link($activeLink);
    $dashboardClass = $activeLink === 'dashboard.php' ? 'font-semibold text-brand-600 border-b-2 border-brand-600 bg-brand-50/50' : 'font-medium text-slate-600 hover:text-brand-600';
    echo '<a href="/dashboard.php" class="h-full flex items-center px-4 text-[13px] ' . $dashboardClass . ' transition-colors">Dashboard</a>';

    foreach (($tree['top'] ?? []) as $parent) {
        $id = (int)($parent['id'] ?? 0);
        $title = abox_menu_value($parent, ['menu_name', 'title', 'name'], 'Menu');
        $remarks = abox_menu_value($parent, ['remarks', 'description', 'sub_title'], '');
        $children = $tree['children'][$id] ?? [];
        if ($children) {
            $activeGroup = false;
            foreach ($children as $child) {
                if (normalize_link(abox_menu_link($child)) === $activeLink) {
                    $activeGroup = true;
                    break;
                }
            }
            $groupClass = $activeGroup ? 'font-semibold text-brand-600 border-b-2 border-brand-600 bg-brand-50/50' : 'font-medium text-slate-600 hover:text-brand-600';
            echo '<div class="group h-full flex items-center relative">';
            echo '<button class="h-full px-4 text-[13px] ' . $groupClass . ' flex items-center gap-1.5 transition-colors">' . h($title) . ' <i class="fa-solid fa-angle-down text-[10px] opacity-70"></i></button>';
            echo '<div class="dropdown-menu absolute top-full left-0 mt-1 w-64 bg-white border border-slate-100 shadow-xl rounded-2xl z-50 overflow-visible origin-top-left">';
            echo '<div class="px-4 py-3 bg-slate-50/80 border-b border-slate-100"><p class="text-[12px] font-bold text-slate-800 uppercase tracking-wide">' . h($title) . '</p>';
            if ($remarks !== '') {
                echo '<p class="text-[11px] font-medium text-slate-500 mt-0.5">' . h($remarks) . '</p>';
            }
            echo '</div><div class="p-2 grid gap-1">';
            $childIds = [];
            foreach ($children as $childRow) {
                $childIds[(int)($childRow['id'] ?? 0)] = true;
            }
            $directChildren = [];
            $nestedChildren = [];
            foreach ($children as $childRow) {
                $childParentId = abox_menu_parent_id($childRow);
                if ($childParentId > 0 && isset($childIds[$childParentId])) {
                    $nestedChildren[$childParentId][] = $childRow;
                } else {
                    $directChildren[] = $childRow;
                }
            }
            foreach ($directChildren as $item) {
                $name = abox_menu_value($item, ['menu_name', 'title', 'name'], 'Menu');
                if (normalize_link(abox_menu_link($item)) === 'masters/employee-shifts.php') {
                    $name = 'Add Shift';
                    $item['menu_link'] = 'masters/employee-shifts-progressive.php?mode=add';
                    $item['url'] = 'masters/employee-shifts-progressive.php?mode=add';
                }
                $icon = abox_menu_value($item, ['icon_class', 'icon', 'fa_icon', 'menu_icon'], 'fa-solid fa-circle-dot');
                $itemActive = normalize_link(abox_menu_link($item)) === $activeLink || ($name === 'Add Shift' && $activeLink === 'masters/employee-shifts.php');
                $subItems = $nestedChildren[(int)($item['id'] ?? 0)] ?? [];
                foreach ($subItems as $subItem) {
                    if (normalize_link(abox_menu_link($subItem)) === $activeLink) {
                        $itemActive = true;
                    }
                }
                $itemClass = $itemActive ? 'font-semibold bg-brand-50 text-brand-600' : 'font-medium text-slate-600 hover:bg-brand-50 hover:text-brand-600';
                if ($subItems) {
                    echo '<div class="menu-subgroup relative">';
                    $itemLink = normalize_link(abox_menu_link($item));
                    if ($itemLink !== '' && $itemLink !== '#' && substr($itemLink, 0, 1) !== '#') {
                        echo '<a href="' . h(abox_menu_href($item)) . '" class="w-full flex items-center gap-3 px-3 py-2 text-[13px] text-left ' . $itemClass . ' rounded-lg transition-colors"><i class="' . h($icon) . ' w-4 text-center"></i><span class="flex-1">' . h($name) . '</span><i class="fa-solid fa-chevron-right text-[9px]"></i></a>';
                    } else {
                        echo '<button type="button" class="w-full flex items-center gap-3 px-3 py-2 text-[13px] text-left ' . $itemClass . ' rounded-lg transition-colors"><i class="' . h($icon) . ' w-4 text-center"></i><span class="flex-1">' . h($name) . '</span><i class="fa-solid fa-chevron-right text-[9px]"></i></button>';
                    }
                    echo '<div class="submenu-flyout absolute left-full top-0 w-64 bg-white border border-slate-100 shadow-xl rounded-2xl z-[60] p-2">';
                    foreach ($subItems as $subItem) {
                        $subName = abox_menu_value($subItem, ['menu_name', 'title', 'name'], 'Menu');
                        $subActive = normalize_link(abox_menu_link($subItem)) === $activeLink;
                        $subClass = $subActive ? 'font-semibold bg-brand-50 text-brand-600' : 'font-medium text-slate-600 hover:bg-brand-50 hover:text-brand-600';
                        echo '<a href="' . h(abox_menu_href($subItem)) . '" class="block px-3 py-2 text-[13px] ' . $subClass . ' rounded-lg transition-colors">' . h($subName) . '</a>';
                    }
                    echo '</div></div>';
                } else {
                    echo '<a href="' . h(abox_menu_href($item)) . '" class="flex items-center gap-3 px-3 py-2 text-[13px] ' . $itemClass . ' rounded-lg transition-colors"><i class="' . h($icon) . ' w-4 text-center"></i> ' . h($name) . '</a>';
                }
            }
            echo '</div></div></div>';
        } else {
            $parentActive = normalize_link(abox_menu_link($parent)) === $activeLink;
            $parentClass = $parentActive ? 'font-semibold text-brand-600 border-b-2 border-brand-600 bg-brand-50/50' : 'font-medium text-slate-600 hover:text-brand-600';
            echo '<a href="' . h(abox_menu_href($parent)) . '" class="h-full flex items-center px-4 text-[13px] ' . $parentClass . ' transition-colors">' . h($title) . '</a>';
        }
    }
}

function render_mobile_admin_menu(?string $activeLink = null): void
{
    $tree = abox_allowed_menu_tree();
    $activeLink = normalize_link($activeLink);
    $dashboardClass = $activeLink === 'dashboard.php' ? 'font-bold text-brand-600 bg-brand-50' : 'font-semibold text-slate-700 hover:bg-slate-50';
    echo '<a href="/dashboard.php" class="block px-4 py-3 rounded-xl text-sm ' . $dashboardClass . '">Dashboard</a>';

    foreach (($tree['top'] ?? []) as $parent) {
        $id = (int)($parent['id'] ?? 0);
        $title = abox_menu_value($parent, ['menu_name', 'title', 'name'], 'Menu');
        $children = $tree['children'][$id] ?? [];
        if ($children) {
            $activeGroup = false;
            foreach ($children as $child) {
                if (normalize_link(abox_menu_link($child)) === $activeLink) {
                    $activeGroup = true;
                    break;
                }
            }
            $subId = 'mob-menu-' . abs($id);
            $groupClass = $activeGroup ? 'font-bold text-brand-600 bg-brand-50' : 'font-semibold text-slate-700 hover:bg-slate-50';
            echo '<button type="button" data-mobile-sub="' . h($subId) . '" class="mobile-submenu-trigger w-full text-left px-4 py-3 rounded-xl text-sm ' . $groupClass . ' flex justify-between items-center transition-colors">' . h($title) . ' <i class="fa-solid fa-chevron-down text-xs text-slate-400 transition-transform duration-200"></i></button>';
            echo '<div id="' . h($subId) . '" class="mobile-submenu px-4 pb-2 space-y-1">';
            $childIds = [];
            foreach ($children as $childRow) {
                $childIds[(int)($childRow['id'] ?? 0)] = true;
            }
            $directChildren = [];
            $nestedChildren = [];
            foreach ($children as $childRow) {
                $childParentId = abox_menu_parent_id($childRow);
                if ($childParentId > 0 && isset($childIds[$childParentId])) {
                    $nestedChildren[$childParentId][] = $childRow;
                } else {
                    $directChildren[] = $childRow;
                }
            }
            foreach ($directChildren as $item) {
                $name = abox_menu_value($item, ['menu_name', 'title', 'name'], 'Menu');
                if (normalize_link(abox_menu_link($item)) === 'masters/employee-shifts.php') {
                    $name = 'Add Shift';
                    $item['menu_link'] = 'masters/employee-shifts-progressive.php?mode=add';
                    $item['url'] = 'masters/employee-shifts-progressive.php?mode=add';
                }
                $itemActive = normalize_link(abox_menu_link($item)) === $activeLink || ($name === 'Add Shift' && $activeLink === 'masters/employee-shifts.php');
                $itemClass = $itemActive ? 'font-bold text-brand-600' : 'font-medium text-slate-500 hover:text-brand-600';
                $subItems = $nestedChildren[(int)($item['id'] ?? 0)] ?? [];
                echo '<a href="' . h(abox_menu_href($item)) . '" class="block px-4 py-2 text-[13px] ' . $itemClass . '">' . h($name) . '</a>';
                foreach ($subItems as $subItem) {
                    $subName = abox_menu_value($subItem, ['menu_name', 'title', 'name'], 'Menu');
                    $subActive = normalize_link(abox_menu_link($subItem)) === $activeLink;
                    $subClass = $subActive ? 'font-bold text-brand-600 bg-brand-50' : 'font-medium text-slate-500 hover:text-brand-600';
                    echo '<a href="' . h(abox_menu_href($subItem)) . '" class="block ml-4 px-4 py-2 text-[12px] rounded-lg border-l-2 border-slate-200 ' . $subClass . '">' . h($subName) . '</a>';
                }
            }
            echo '</div>';
        } else {
            $parentActive = normalize_link(abox_menu_link($parent)) === $activeLink;
            $parentClass = $parentActive ? 'font-bold text-brand-600 bg-brand-50' : 'font-semibold text-slate-700 hover:bg-slate-50';
            echo '<a href="' . h(abox_menu_href($parent)) . '" class="block px-4 py-3 rounded-xl text-sm ' . $parentClass . '">' . h($title) . '</a>';
        }
    }
}

function console_user_context(): array
{
    $user = current_user() ?: [];
    $displayName = $user['name'] ?? ($user['username'] ?? 'Admin');
    $displayRole = $user['role'] ?? 'SUPER USER';
    if ($displayRole === 'Super Admin') {
        $displayRole = 'SUPER USER';
    }
    $displayEmail = $user['email'] ?? '';
    $letters = preg_replace('/[^A-Za-z]/', '', $displayName);
    $initials = strtoupper(substr($letters, 0, 2));
    if ($initials === '') {
        $initials = 'AD';
    }
    return compact('user', 'displayName', 'displayRole', 'displayEmail', 'initials');
}

function console_header(string $pageTitle, string $activeLink): void
{
    extract(console_user_context(), EXTR_SKIP);
    $activeLink = normalize_link($activeLink);
    ?><!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= h($pageTitle) ?> - Attendance Box</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
    <script src="/assets/js/tailwind.config.js"></script>
    <link rel="stylesheet" href="/assets/css/dashboard.css">
</head>
<body class="bg-slate-50 text-slate-800 font-sans antialiased flex flex-col min-h-screen overflow-hidden">
    <div id="app-preloader" class="fixed inset-0 z-[9999] bg-slate-50 flex flex-col justify-center items-center">
        <div class="w-12 h-12 border-4 border-brand-100 border-t-brand-600 rounded-full animate-spin mb-4 shadow-sm"></div>
        <h2 class="text-slate-800 text-lg font-bold tracking-tight">Attendance Box</h2>
        <p class="text-xs text-slate-500 font-medium mt-2 uppercase tracking-widest">Loading Workspace...</p>
    </div>

    <nav class="bg-white border-b border-slate-200 shadow-sm sticky top-0 z-50">
        <div class="bg-brand-900 text-brand-100 text-[11px] font-medium py-1.5 px-4 sm:px-6 flex justify-between items-center tracking-wide">
            <div class="flex items-center gap-2 sm:gap-4">
                <span class="text-emerald-400 flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-emerald-400"></span> <span class="hidden sm:inline">System Online</span></span>
                <span class="text-brand-700 hidden sm:inline">|</span>
                <span>FY: 2026-2027</span>
            </div>
            <a href="#" class="hover:text-white transition-colors flex items-center gap-1.5"><i class="fa-solid fa-headset"></i> <span class="hidden sm:inline">HR Helpdesk</span></a>
        </div>

        <div class="max-w-[1600px] mx-auto px-4 sm:px-6 relative">
            <div class="flex justify-between items-center h-16">
                <div class="flex items-center gap-3">
                    <button type="button" id="mobile-menu-btn" class="lg:hidden text-slate-500 hover:text-brand-600 focus:outline-none p-1"><i class="fa-solid fa-bars text-xl"></i></button>
                    <a href="/dashboard.php" class="flex items-center gap-3 lg:border-r border-slate-200 lg:pr-6 lg:mr-2">
                        <div class="bg-brand-600 text-white font-bold p-1.5 sm:p-2 rounded-lg text-sm tracking-wider shadow-sm flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 border border-brand-700"><i class="fa-solid fa-building text-sm sm:text-base"></i></div>
                        <div class="leading-tight">
                            <div class="font-bold text-slate-900 text-[13px] sm:text-base tracking-tight flex items-center gap-1.5">Inventive Infotech</div>
                            <div class="text-[9px] sm:text-[10px] text-slate-500 font-bold tracking-wider uppercase">HR Workspace</div>
                        </div>
                    </a>
                </div>

                <div class="hidden lg:flex flex-grow items-center h-full space-x-1"><?php render_desktop_admin_menu($activeLink); ?></div>

                <div class="flex items-center gap-3 sm:gap-4 lg:border-l border-slate-200 lg:pl-4">
                    <button class="relative text-slate-400 hover:text-brand-600 transition-colors">
                        <i class="fa-regular fa-bell text-[1.1rem]"></i>
                        <span class="absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full border border-white"></span>
                    </button>

                    <div class="profile-group relative flex items-center gap-3 p-1.5 rounded-lg transition-colors cursor-pointer">
                        <div class="relative">
                            <div class="w-8 h-8 sm:w-9 sm:h-9 rounded-full bg-brand-600 text-white flex items-center justify-center font-bold text-sm shadow-md ring-2 ring-white"><?= h($initials) ?></div>
                            <span class="absolute bottom-0 right-0 w-2.5 h-2.5 bg-emerald-500 border-2 border-white rounded-full"></span>
                        </div>
                        <div class="hidden md:block text-left">
                            <div class="text-[13px] font-bold text-slate-800 leading-none mb-0.5"><?= h($displayName) ?></div>
                            <div class="text-[10px] text-slate-500 font-bold uppercase tracking-wide"><?= h($displayRole) ?></div>
                        </div>
                        <i class="fa-solid fa-chevron-down text-[10px] text-slate-400 hidden md:block"></i>

                        <div class="profile-menu absolute top-full right-0 mt-1 w-56 bg-white border border-slate-100 shadow-xl rounded-2xl z-50 overflow-hidden origin-top-right">
                            <div class="px-5 py-4 bg-slate-50/80 border-b border-slate-100">
                                <p class="text-[13px] font-bold text-slate-800 leading-tight"><?= h($displayName) ?></p>
                                <p class="text-[11px] font-medium text-slate-500 mt-0.5"><?= h($displayEmail) ?></p>
                            </div>
                            <div class="p-2 space-y-1">
                                <a href="#" class="flex items-center gap-3 px-3 py-2 text-[13px] font-medium text-slate-600 hover:bg-brand-50 hover:text-brand-600 rounded-lg transition-colors"><i class="fa-regular fa-user w-4 text-center"></i> My Profile</a>
                                <a href="#" class="flex items-center gap-3 px-3 py-2 text-[13px] font-medium text-slate-600 hover:bg-brand-50 hover:text-brand-600 rounded-lg transition-colors"><i class="fa-solid fa-gear w-4 text-center"></i> Settings</a>
                            </div>
                            <div class="border-t border-slate-100 p-2">
                                <a href="/logout.php" class="w-full flex items-center justify-center gap-2 px-3 py-2 text-[13px] text-red-600 font-semibold hover:bg-red-50 rounded-lg transition-colors"><i class="fa-solid fa-power-off"></i> Sign Out</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div id="mobile-menu" class="hidden lg:hidden bg-white border-t border-slate-100 absolute w-full left-0 shadow-xl z-40 origin-top">
            <div class="px-4 pt-2 pb-4 space-y-1 overflow-y-auto max-h-[80vh]"><?php render_mobile_admin_menu($activeLink); ?></div>
        </div>
    </nav>

    <main class="flex-grow max-w-[1600px] mx-auto px-4 sm:px-6 py-6 sm:py-8 w-full">
    <?php
}

function console_footer(): void
{
    ?>
    </main>
    <script src="/assets/js/dashboard.js?v=202607212200"></script>
    <script>
    document.addEventListener('DOMContentLoaded', function () {
      var group = document.querySelector('.profile-group');
      var menu = document.querySelector('.profile-menu');
      function showMenu() { if (!menu) return; menu.style.opacity = '1'; menu.style.visibility = 'visible'; menu.style.pointerEvents = 'auto'; menu.style.transform = 'translateY(0)'; }
      function hideMenu() { if (!menu) return; menu.style.opacity = ''; menu.style.visibility = ''; menu.style.pointerEvents = ''; menu.style.transform = ''; }
      if (group && menu) {
        group.addEventListener('mouseenter', showMenu);
        group.addEventListener('mouseleave', hideMenu);
        group.addEventListener('click', function (event) { event.stopPropagation(); menu.style.visibility === 'visible' ? hideMenu() : showMenu(); });
        document.addEventListener('click', hideMenu);
      }
    });
    </script>
</body>
</html>
    <?php
}

