<?php

require_once DENTAL_ROOT . '/app/help_support.php';
require_once DENTAL_ROOT . '/app/flow_guidance.php';

function dental_asset_version(string $relativePath): string
{
    $relativePath=ltrim($relativePath,'/');
    $modified=@filemtime(DENTAL_ROOT . '/' . $relativePath);
    return app_release_version() . '-' . ($modified!==false?(string)$modified:'0');
}

function dental_icon(string $name, string $class = 'icon'): string
{
    $paths = [
        'home' => '<path d="M3 11.5 12 4l9 7.5"/><path d="M5 10.5V20h5v-6h4v6h5v-9.5"/>',
        'dashboard' => '<rect x="3" y="3" width="7" height="7" rx="2"/><rect x="14" y="3" width="7" height="7" rx="2"/><rect x="3" y="14" width="7" height="7" rx="2"/><rect x="14" y="14" width="7" height="7" rx="2"/>',
        'patients' => '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
        'patient' => '<path d="M20 21a8 8 0 0 0-16 0"/><circle cx="12" cy="7" r="4"/>',
        'user-plus' => '<path d="M15 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="8" cy="7" r="4"/><path d="M19 8v6M22 11h-6"/>',
        'inbox' => '<path d="M4 4h16v16H4z"/><path d="M4 13h4l2 3h4l2-3h4"/>',
        'repeat' => '<path d="m17 1 4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="m7 23-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/>',
        'message' => '<path d="M21 15a4 4 0 0 1-4 4H8l-5 3V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"/>',
        'help' => '<circle cx="12" cy="12" r="9"/><path d="M9.8 9a2.4 2.4 0 1 1 3.6 2.1c-.9.5-1.4 1-1.4 2.2"/><path d="M12 17h.01"/>',
        'support' => '<path d="M4 13v-1a8 8 0 0 1 16 0v1"/><path d="M4 13a2 2 0 0 0 2 2h1v-5H6a2 2 0 0 0-2 2v1ZM20 13a2 2 0 0 1-2 2h-1v-5h1a2 2 0 0 1 2 2v1Z"/><path d="M17 15v1a4 4 0 0 1-4 4h-2"/>',
        'phone' => '<path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.4 19.4 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 2 .7 2.9a2 2 0 0 1-.5 2.1L8 10a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2.1-.5c.9.3 1.9.6 2.9.7a2 2 0 0 1 1.7 2Z"/>',
        'timeline' => '<circle cx="6" cy="5" r="2"/><circle cx="6" cy="12" r="2"/><circle cx="6" cy="19" r="2"/><path d="M10 5h11M10 12h11M10 19h11"/>',
        'calendar' => '<rect x="3" y="5" width="18" height="16" rx="2"/><path d="M16 3v4M8 3v4M3 10h18"/>',
        'queue' => '<path d="M4 6h16M4 12h10M4 18h7"/><circle cx="19" cy="17" r="3"/>',
        'clock' => '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',
        'clinical' => '<path d="M7 3v5a5 5 0 0 0 10 0V3"/><path d="M5 3h4M15 3h4"/><path d="M12 13v3a5 5 0 0 0 5 5h1"/><circle cx="20" cy="18" r="2"/>',
        'tooth' => '<path d="M8.5 3C5.5 3 4 5.6 4 8.1c0 2.2 1.2 4.1 2 5.9.9 2 .8 5 2.3 6.5.7.7 1.8.6 2.3-.3L12 17l1.4 3.2c.5.9 1.6 1 2.3.3 1.5-1.5 1.4-4.5 2.3-6.5.8-1.8 2-3.7 2-5.9C20 5.6 18.5 3 15.5 3c-1.4 0-2.5.8-3.5.8S9.9 3 8.5 3Z"/>',
        'clipboard' => '<rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V2h6v2M9 10h6M9 14h6M9 18h4"/>',
        'pill' => '<path d="m10.5 20.5 10-10a4.95 4.95 0 0 0-7-7l-10 10a4.95 4.95 0 0 0 7 7Z"/><path d="m8.5 8.5 7 7"/>',
        'doctor' => '<circle cx="12" cy="7" r="4"/><path d="M5 21a7 7 0 0 1 14 0M9 14l3 3 3-3"/>',
        'referral' => '<path d="M4 4h8v8H4zM12 16h8v4h-8z"/><path d="M12 8h5a3 3 0 0 1 3 3v5M16 13l4 3 4-3"/>',
        'lab' => '<path d="M9 3h6M10 3v6l-5 9a2 2 0 0 0 2 3h10a2 2 0 0 0 2-3l-5-9V3"/><path d="M8 15h8"/>',
        'finance' => '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 10h18M7 15h3"/>',
        'receipt' => '<path d="M6 2h12v20l-3-2-3 2-3-2-3 2Z"/><path d="M9 7h6M9 11h6M9 15h4"/>',
        'shield' => '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/><path d="m9 12 2 2 4-4"/>',
        'check' => '<path d="m5 12 4 4L19 6"/>',
        'operations' => '<path d="M3 7h18M5 7V4h14v3M6 7v13h12V7"/><path d="M9 11h6M9 15h6"/>',
        'inventory' => '<path d="m21 8-9 5-9-5 9-5 9 5Z"/><path d="m3 8 9 5 9-5M3 12l9 5 9-5M3 16l9 5 9-5"/>',
        'sterilization' => '<path d="M7 3h10M9 3v4l-4 7a5 5 0 0 0 4.4 7h5.2A5 5 0 0 0 19 14l-4-7V3"/><path d="M7 15h10M10 11h4"/>',
        'chart' => '<path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/>',
        'printer' => '<path d="M6 9V2h12v7M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/>',
        'settings' => '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3V2.8h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z"/>',
        'building' => '<path d="M3 21h18M5 21V5l7-3 7 3v16M9 9h1M14 9h1M9 13h1M14 13h1M10 21v-4h4v4"/>',
        'mail' => '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/>',
        'palette' => '<circle cx="12" cy="12" r="9"/><circle cx="8" cy="9" r="1"/><circle cx="12" cy="7" r="1"/><circle cx="16" cy="9" r="1"/><path d="M17 15c-1.4 0-2.5 1-2.5 2.2 0 .7.4 1.3 1 1.8"/>',
        'upload' => '<path d="M12 16V3M7 8l5-5 5 5"/><path d="M4 15v5h16v-5"/>',
        'database' => '<ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/>',
        'backup' => '<path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 3v5h5M12 7v5l3 2"/>',
        'package' => '<path d="m12 3 8 4-8 4-8-4 8-4Z"/><path d="m4 7 8 4 8-4M4 12l8 4 8-4M4 17l8 4 8-4"/>',
        'eye' => '<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12Z"/><circle cx="12" cy="12" r="2.5"/>',
        'key' => '<circle cx="8" cy="15" r="4"/><path d="m11 12 9-9M17 6l3 3M14 9l3 3"/>',
        'search' => '<circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/>',
        'plus' => '<path d="M12 5v14M5 12h14"/>',
        'menu' => '<path d="M4 6h16M4 12h16M4 18h16"/>',
        'panel-left' => '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 3v18M14 9l-3 3 3 3"/>',
        'more' => '<circle cx="5" cy="12" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/>',
        'external' => '<path d="M14 3h7v7M10 14 21 3"/><path d="M21 14v6H4V3h6"/>',
        'fullscreen' => '<path d="M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5"/><path d="M3 8l5-5M16 3l5 5M21 16l-5 5M8 21l-5-5"/>',
        'logout' => '<path d="M10 17l5-5-5-5M15 12H3"/><path d="M15 3h5v18h-5"/>',
        'chevron-down' => '<path d="m6 9 6 6 6-6"/>',
        'arrow-left' => '<path d="m15 18-6-6 6-6"/><path d="M9 12h12"/>',
        'chevron-right' => '<path d="m9 18 6-6-6-6"/>',
    ];
    $content = $paths[$name] ?? $paths['more'];
    return '<svg class="' . e($class) . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' . $content . '</svg>';
}

function brand_mark(array $brand, string $class = 'mark'): string
{
    if (!empty($brand['logo'])) {
        return '<span class="' . e($class) . ' brand-logo"><img src="' . e((string) $brand['logo']) . '" alt=""></span>';
    }
    return '<span class="' . e($class) . '">' . dental_icon('tooth', 'brand-icon') . '</span>';
}

function sidebar_item(string $url, string $label, bool $visible = true, string $badge = '', string $icon = 'more'): ?array
{
    if (function_exists('dental_clean_url')) $url = dental_clean_url($url);
    return $visible ? ['url'=>$url,'label'=>$label,'badge'=>$badge,'icon'=>$icon] : null;
}

function task_sidebar_item(string $route, string $url, string $label, ?string $permission = null, array|string $fallbackRoles = [], string $badge = '', string $icon = 'more'): ?array
{
    if (!task_context_page_allowed($route)) return null;
    if (!task_link_allowed($url)) return null;
    if ($permission !== null && !navigation_can($permission, $fallbackRoles)) return null;
    return sidebar_item($url, $label, true, $badge, $icon);
}

function dental_sidebar_route_key_from_path(string $path): string
{
    $leaf = basename((string)(parse_url($path, PHP_URL_PATH) ?: $path));
    $leaf = preg_replace('/\.php$/i', '', $leaf) ?: $leaf;
    if (function_exists('dental_slug_to_route')) return dental_slug_to_route($leaf);
    return str_replace('-', '_', $leaf);
}

function sidebar_url_is_active(string $url, string $current): bool
{
    $parts = parse_url($url);
    $path = (string) ($parts['path'] ?? $url);
    $routePath = dental_sidebar_route_key_from_path($path);
    $currentRoute = dental_sidebar_route_key_from_path($current);
    if ($currentRoute !== $routePath) return false;
    $itemQuery = [];
    if (!empty($parts['query'])) parse_str((string) $parts['query'], $itemQuery);
    unset($itemQuery['nav_area']);
    if ($itemQuery) {
        foreach ($itemQuery as $key => $value) {
            if ((string) ($_GET[$key] ?? '') !== (string) $value) return false;
        }
        return true;
    }
    if ($routePath === 'system_setup' && isset($_GET['tab']) && $_GET['tab'] !== 'overview') return false;
    if ($routePath === 'billing' && isset($_GET['view']) && (string)$_GET['view'] !== 'register') return false;
    return true;
}

function dental_navigation_url_with_area(string $url, string $area): string
{
    $url = trim($url);
    $area = trim($area);
    if ($url === '' || $area === '' || preg_match('#^(?:https?:)?//#i', $url) || str_starts_with($url, '#') || str_starts_with($url, 'mailto:') || str_starts_with($url, 'tel:')) {
        return $url;
    }
    if (function_exists('dental_clean_url')) $url = dental_clean_url($url);
    $parts = parse_url($url);
    if ($parts === false) return $url;
    $path = (string)($parts['path'] ?? '');
    if ($path === '') return $url;
    $query = [];
    if (!empty($parts['query'])) parse_str((string)$parts['query'], $query);
    $query['nav_area'] = preg_replace('/[^a-zA-Z0-9_-]/', '', $area);
    $fragment = (string)($parts['fragment'] ?? '');
    return $path . ($query ? '?' . http_build_query($query) : '') . ($fragment !== '' ? '#' . $fragment : '');
}

function dental_navigation_groups(string $role, string $actualRole, bool $isOwnerHost): array
{
    $breakGlassReviewCount = function_exists('dental_break_glass_pending_review_count') ? dental_break_glass_pending_review_count() : 0;
    $canBuildInstallers = !function_exists('dental_distribution_feature_allowed') || dental_distribution_feature_allowed('package_builder');
    $canIssueLicenses = $isOwnerHost && (!function_exists('dental_distribution_feature_allowed') || dental_distribution_feature_allowed('license_issuer'));
    $showInternalQa = function_exists('dental_internal_qa_visible') ? dental_internal_qa_visible() : true;
    $productionMode = function_exists('dental_production_mode') ? dental_production_mode() : false;
    $showDemoOrientation = !$productionMode || $showInternalQa;
    $realDentistWorkspace = $role === 'dentist' && active_role_can_operate('dentist');
    $dentistWorkspaceLabel = $realDentistWorkspace ? 'My Treatment Dashboard' : 'Doctor Treatment Dashboard';
    $doctorProfileLabel = $realDentistWorkspace ? 'Professional Credentials' : 'Dentist Credentials';
    $availabilityLabel = $realDentistWorkspace ? 'My Schedule Builder' : 'Doctor Schedule Builder';
    $appointmentsLabel = $realDentistWorkspace ? 'Appointment List' : 'Weekly Schedule';

    $todayItems = $realDentistWorkspace
        ? [
            task_sidebar_item('doctor_treatment','doctor_treatment.php',$dentistWorkspaceLabel,'clinical.view',['super_admin','clinic_admin','dentist'],'','clinical'),
            sidebar_item('dashboard.php','Clinical Overview',true,'','dashboard'),
        ]
        : [
            sidebar_item('dashboard.php','Dashboard',true,'','dashboard'),
            task_sidebar_item('doctor_treatment','doctor_treatment.php',$dentistWorkspaceLabel,'clinical.view',['super_admin','clinic_admin','dentist'],'','clinical'),
        ];

    $groups = [
        'today' => ['label'=>$realDentistWorkspace?'Clinical Day':'Today','short'=>'Today','icon'=>'home','primary_count'=>2,'items'=>$todayItems],
        'patients' => ['label'=>'Patients','short'=>'Patients','icon'=>'patients','primary_count'=>3,'items'=>[
            task_sidebar_item('patients','patients.php','Directory','patients.view',['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant'],'','patients'),
            task_sidebar_item('appointment_requests','appointment_requests.php','Online Requests','appointments.manage',['super_admin','clinic_admin','receptionist','staff'],'','inbox'),
            task_sidebar_item('portal_requests','portal_requests.php',$realDentistWorkspace?'Dental Safety Updates':'Patient Portal Requests','appointments.manage',['super_admin','clinic_admin','receptionist','staff','dentist'],'','message'),
            task_sidebar_item('record_requests','record_requests.php','Record Copy Requests',null,['super_admin','clinic_admin','receptionist','staff','dentist','cashier'],'','printer'),
            task_sidebar_item('waitlist','waitlist.php','Appointment Waitlist','appointments.manage',['super_admin','clinic_admin','receptionist','staff'],'','clock'),
            task_sidebar_item('followups','followups.php','Follow-Ups',null,['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant'],'','repeat'),
            task_sidebar_item('communications','communications.php','Communications','communications.manage',['super_admin','clinic_admin','receptionist','staff','dentist'],'','message'),
            task_sidebar_item('visit_workflow','visit_workflow.php','Patient Journey',null,['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant'],'','timeline'),
        ]],
        'schedule' => ['label'=>'Schedule','short'=>'Schedule','icon'=>'calendar','primary_count'=>3,'items'=>[
            task_sidebar_item('appointments','appointments.php',$appointmentsLabel,'appointments.manage',['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant'],'','calendar'),
            task_sidebar_item('queue','queue.php','Clinic Queue','queue.manage',['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant'],'','queue'),
            task_sidebar_item('inhouse_checkups','inhouse_checkups.php','Dental Support Services',null,['super_admin','clinic_admin','receptionist','staff','dental_assistant'],'','clipboard'),
            task_sidebar_item('doctor_schedule','doctor_schedule.php',$availabilityLabel,null,[],'','clock'),
        ]],
        'clinical' => ['label'=>'Clinical','short'=>'Clinical','icon'=>'clinical','primary_count'=>4,'items'=>[
            task_sidebar_item('clinical','clinical.php','Encounters','clinical.view',['super_admin','clinic_admin','dentist','dental_assistant'],'','clinical'),
            task_sidebar_item('odontogram','odontogram.php','Odontogram & Tooth Findings','clinical.view',['super_admin','clinic_admin','dentist','dental_assistant'],'','tooth'),
            task_sidebar_item('treatment','treatment.php','Treatment Plans','clinical.view',['super_admin','clinic_admin','dentist','dental_assistant'],'','clipboard'),
            task_sidebar_item('clinical_tasks','clinical_tasks.php','Clinical Tasks','clinical.view',['super_admin','clinic_admin','dentist'],'','clipboard'),
            task_sidebar_item('prescriptions','prescriptions.php','Prescriptions','clinical.view',['super_admin','clinic_admin','dentist'],'','pill'),
            task_sidebar_item('doctor_profile','doctor_profile.php',$doctorProfileLabel,'dentist_profile.view',['super_admin','clinic_admin','dentist'],'','doctor'),
            task_sidebar_item('referrals','referrals.php','Referrals','clinical.view',['super_admin','clinic_admin','dentist'],'','referral'),
            task_sidebar_item('laboratory','laboratory.php','Laboratory','clinical.view',['super_admin','clinic_admin','dentist','dental_assistant'],'','lab'),
        ]],
        'finance' => ['label'=>'Finance','short'=>'Finance','icon'=>'finance','primary_count'=>3,'items'=>[
            task_sidebar_item('billing','billing.php',role_context_has(['cashier','staff'])?'Cashier Register':'Billing & Cashier','billing.manage',['super_admin','clinic_admin','cashier','staff'],'','receipt'),
            sidebar_item('billing.php?view=exceptions','Cashier Exceptions',in_array($actualRole,['super_admin','clinic_admin'],true)&&task_context_page_allowed('billing')&&task_link_allowed('billing.php?view=exceptions'),'','shield'),
            task_sidebar_item('insurance','insurance.php','Insurance & HMO','insurance.manage',['super_admin','clinic_admin'],'','shield'),
        ]],
        'operations' => ['label'=>'Operations','short'=>'Operations','icon'=>'operations','primary_count'=>4,'items'=>[
            task_sidebar_item('inventory','inventory.php','Inventory','inventory.manage',['super_admin','clinic_admin','inventory_officer'],'','inventory'),
            task_sidebar_item('sterilization','sterilization.php','Sterilization','sterilization.manage',['super_admin','clinic_admin','dentist','dental_assistant','inventory_officer'],'','sterilization'),
            task_sidebar_item('visit_exceptions','visit_exceptions.php','Reconciliation Center',null,['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant','inventory_officer'],'','shield'),
            task_sidebar_item('reports','reports.php','Reports','reports.view',['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant','inventory_officer'],'','chart'),
            task_sidebar_item('print_center','print_center.php','Records & Printing','records.print',['super_admin','clinic_admin','dentist','receptionist','staff','dental_assistant','cashier','inventory_officer'],'','printer'),
        ]],
        'website' => ['label'=>'Website & Communications','short'=>'Website','icon'=>'palette','primary_count'=>4,'items'=>[
            task_sidebar_item('settings','settings.php','Landing Page Editor','configuration.manage',['super_admin','clinic_admin'],'','building'),
            task_sidebar_item('branding','branding.php','Branding & Identity','configuration.manage',['super_admin','clinic_admin'],'','palette'),
            task_sidebar_item('website_pages','website_pages.php','Pages & Navigation','configuration.manage',['super_admin','clinic_admin'],'','layout'),
            task_sidebar_item('website_media','website_media.php','Media Library','configuration.manage',['super_admin','clinic_admin'],'','upload'),
            task_sidebar_item('email_settings','email_settings.php','Email & SMTP','smtp.manage',['super_admin','clinic_admin'],'','mail'),
            task_sidebar_item('email_templates','email_templates.php','Email Templates','smtp.manage',['super_admin','clinic_admin'],'','message'),
            task_sidebar_item('sms_settings','sms_settings.php','SMS Readiness','smtp.manage',['super_admin','clinic_admin'],'','message'),
            task_sidebar_item('reminders','reminders.php','Patient Reminders',null,['super_admin','clinic_admin'],'','clock'),
        ]],
        'clinic_setup' => ['label'=>'Clinic Setup','short'=>'Setup','icon'=>'building','primary_count'=>4,'items'=>[
            task_sidebar_item('setup_wizard','setup_wizard.php','Clinic Setup Wizard','configuration.manage',['super_admin','clinic_admin'],'','settings'),
            task_sidebar_item('patient_numbering','patient_numbering.php','Patient Numbering','configuration.manage',['super_admin','clinic_admin'],'','settings'),
            task_sidebar_item('services','services.php','Dental Services','configuration.manage',['super_admin','clinic_admin'],'','clinical'),
            task_sidebar_item('chairs','chairs.php','Chairs & Resources','configuration.manage',['super_admin','clinic_admin'],'','tooth'),
            task_sidebar_item('inhouse_team','inhouse_team.php','In-house Care Team','configuration.manage',['super_admin','clinic_admin'],'','doctor'),
            task_sidebar_item('operation_hours','operation_hours.php','Operation Hours','configuration.manage',['super_admin','clinic_admin'],'','clock'),
            task_sidebar_item('uploads','uploads.php','Files & Uploads','uploads.manage',['super_admin','clinic_admin'],'','upload'),
        ]],
        'administration' => ['label'=>'Administration & Governance','short'=>'Admin','icon'=>'settings','primary_count'=>4,'items'=>[
            task_sidebar_item('administration','administration.php','Operations Control Center','configuration.manage',['super_admin','clinic_admin'],'','settings'),
            task_sidebar_item('staff','staff.php','Staff Accounts & Roles','staff.manage',['super_admin','clinic_admin'],'','doctor'),
            task_sidebar_item('permission_matrix','permission_matrix.php','Permission Matrix','configuration.manage',['super_admin','clinic_admin'],'','shield'),
            task_sidebar_item('break_glass','break_glass.php','Emergency Access Review',null,['super_admin','clinic_admin'],$breakGlassReviewCount > 0 ? (string)$breakGlassReviewCount : '','shield'),
            task_sidebar_item('privacy_governance','privacy_governance.php','Privacy & Audit Center','privacy.governance.manage',['super_admin','clinic_admin'],'','shield'),
            task_sidebar_item('transaction_integrity','transaction_integrity.php','Transaction Integrity','system.transaction_integrity.view',['super_admin','clinic_admin'],'','shield'),
            task_sidebar_item('data_integrity_center','data_integrity_center.php','Data Integrity Center','system.data_integrity.view',['super_admin','clinic_admin'],'','shield'),
        ]],
        'system_recovery' => ['label'=>'System & Recovery','short'=>'System','icon'=>'shield','primary_count'=>4,'items'=>[
            task_sidebar_item('operational_health','operational_health.php','Operational Health','system.manage',['super_admin'],'','shield'),
            task_sidebar_item('system_setup','system_setup.php','System Control Center','system.manage',['super_admin'],($actualRole==='super_admin'&&app_update_pending())?'Update':'','settings'),
            task_sidebar_item('production_monitoring','production_monitoring.php','Production Monitor','system.manage',['super_admin'],'','chart'),
            task_sidebar_item('backup_restore','backup_restore.php','Backup & Restore','system.manage',['super_admin'],'','backup'),
            task_sidebar_item('navigation_diagnostics','navigation_diagnostics.php','Navigation & Role Integrity','system.manage',['super_admin'],'','shield'),
            task_sidebar_item('hardening_center','hardening_center.php','Hardening Center','system.manage',['super_admin'],'','shield'),
        ]],
        'help' => ['label'=>'Help','short'=>'Help','icon'=>'help','primary_count'=>1,'items'=>[
            task_sidebar_item('my_profile','my_profile.php','Profile Center',null,['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant','cashier','inventory_officer'],'','patient'),
            task_sidebar_item('help_support','help_support.php','Help & Support',null,['super_admin','clinic_admin','receptionist','staff','dentist','dental_assistant','cashier','inventory_officer'],'','help'),
        ]],
        'super' => ['label'=>'Super','short'=>'Super','icon'=>'key','primary_count'=>5,'items'=>[
            $showInternalQa ? task_sidebar_item('system_smoke_test','system_smoke_test.php','QA Smoke Test','system.manage',['super_admin'],'','shield') : null,
            task_sidebar_item('kiosk','kiosk.php','Kiosk Mode / Launcher','system.manage',['super_admin'],'','fullscreen'),
            $showInternalQa ? task_sidebar_item('go_live_checklist','go_live_checklist.php','Go-Live Checklist','system.manage',['super_admin'],'','shield') : null,
            $showDemoOrientation ? task_sidebar_item('demo_accounts','demo_accounts.php','Demo Data & Orientation','system.manage',['super_admin'],'','doctor') : null,
            task_sidebar_item('data_tools','data_tools.php','Data Import & Reset','system.manage',['super_admin'],'','database'),
            $canBuildInstallers ? task_sidebar_item('installer_builder','installer_builder.php','Installer Builder',null,['super_admin'],'','package') : null,
            $canIssueLicenses ? task_sidebar_item('license_manager','license_manager.php','License Manager',null,['super_admin'],'','key') : null,
        ]],
    ];

    // Role-first navigation: expose one canonical operating lane and keep
    // specialist tools contextual instead of presenting every module as an
    // equal starting point.
    $itemRegistry = [];
    foreach ($groups as $groupRow) {
        foreach ((array)($groupRow['items'] ?? []) as $itemRow) {
            if (!$itemRow) continue;
            $itemRegistry[dental_sidebar_route_key_from_path((string)$itemRow['url'])] = $itemRow;
        }
    }
    $buildGroup = static function (string $label, string $short, string $icon, array $routes) use ($itemRegistry): array {
        $items = [];
        foreach ($routes as $route) if (isset($itemRegistry[$route])) $items[] = $itemRegistry[$route];
        return ['label'=>$label,'short'=>$short,'icon'=>$icon,'primary_count'=>min(4,count($items)),'items'=>$items];
    };
    if ($role === 'receptionist') {
        $groups = [
            'today'=>$buildGroup('Front Desk','Front Desk','home',['dashboard','queue']),
            'patients'=>$buildGroup('Patient Services','Patients','patients',['patients','appointment_requests','portal_requests','record_requests','waitlist','followups','communications','visit_workflow']),
            'schedule'=>$buildGroup('Appointments & Dental Support','Schedule','calendar',['appointments','inhouse_checkups']),
            'operations'=>$buildGroup('Front-Desk Controls','Controls','operations',['visit_exceptions','reports','print_center']),
            'help'=>$buildGroup('Help','Help','help',['my_profile','help_support']),
        ];
    } elseif ($role === 'staff') {
        $groups = [
            'today'=>$buildGroup('General Staff Workspace','General Staff','home',['dashboard','queue','billing']),
            'patients'=>$buildGroup('Reception & Patient Services','Patients','patients',['patients','appointment_requests','portal_requests','record_requests','waitlist','followups','communications','visit_workflow']),
            'schedule'=>$buildGroup('Appointments & Dental Support','Schedule','calendar',['appointments','inhouse_checkups']),
            'finance'=>$buildGroup('Cashier Register','Cashier','receipt',['billing']),
            'operations'=>$buildGroup('Front-Desk Controls','Controls','operations',['visit_exceptions','reports','print_center']),
            'help'=>$buildGroup('Help','Help','help',['my_profile','help_support']),
        ];
    } elseif ($role === 'dentist') {
        $groups = [
            'today'=>$buildGroup('My Clinical Day','Today','clinical',['doctor_treatment','dashboard']),
            'patients'=>$buildGroup('Patient Records','Patients','patients',['patients','portal_requests','record_requests','followups','communications','visit_workflow']),
            'schedule'=>$buildGroup('My Schedule','Schedule','calendar',['appointments','doctor_schedule']),
            'clinical'=>$buildGroup('Clinical Records','Clinical','clinical',['clinical','treatment','clinical_tasks','prescriptions','referrals','laboratory','doctor_profile']),
            'operations'=>$buildGroup('Clinical Oversight','Oversight','operations',['visit_exceptions','reports','print_center']),
            'help'=>$buildGroup('Help','Help','help',['my_profile','help_support']),
        ];
    } elseif ($role === 'dental_assistant') {
        $groups = [
            'today'=>$buildGroup('Chairside Tasks','Chairside','clinical',['dashboard','queue']),
            'patients'=>$buildGroup('Assigned Patient Records','Patients','patients',['patients','visit_workflow','followups']),
            'schedule'=>$buildGroup('Assigned Dental Work','Schedule','calendar',['appointments','inhouse_checkups']),
            'clinical'=>$buildGroup('Clinical Drafts','Clinical','clipboard',['clinical','odontogram','treatment','laboratory']),
            'operations'=>$buildGroup('Chairs, Instruments & Sterilization','Operations','sterilization',['sterilization','visit_exceptions','print_center']),
            'help'=>$buildGroup('Help','Help','help',['my_profile','help_support']),
        ];
    } elseif ($role === 'cashier') {
        $groups = [
            'today'=>$buildGroup('Cashier Register','Cashier','receipt',['dashboard','billing']),
            'operations'=>$buildGroup('Receipts & Print Activity','Printing','printer',['print_center']),
            'help'=>$buildGroup('Help','Help','help',['my_profile','help_support']),
        ];
    } elseif ($role === 'inventory_officer') {
        $groups = [
            'today'=>$buildGroup('Inventory Work Queue','Inventory','inventory',['dashboard','inventory']),
            'operations'=>$buildGroup('Stock & Sterilization','Operations','operations',['inventory','sterilization','visit_exceptions','reports','print_center']),
            'help'=>$buildGroup('Help','Help','help',['my_profile','help_support']),
        ];
    } elseif ($role === 'clinic_admin') {
        $groups['today'] = $buildGroup('Operations Control','Today','home',['dashboard','administration','visit_exceptions']);
        $groups['clinical'] = $buildGroup('Clinical Oversight','Clinical','clinical',['clinical','clinical_tasks','doctor_profile']);
        unset($groups['super']);
    } elseif ($role === 'super_admin' && $actualRole === 'super_admin') {
        // The owner dashboard remains an overview. System Control is kept in
        // one dedicated Superuser-only area instead of being duplicated as the
        // first everyday workspace.
        $groups['today'] = $buildGroup('Owner Overview','Overview','home',['dashboard','administration','visit_exceptions']);
        $groups['clinical'] = $buildGroup('Clinical Oversight','Clinical','clinical',['clinical','clinical_tasks','doctor_profile']);
        if (isset($groups['super'])) {
            $groups['super']['label'] = 'System Control';
            $groups['super']['short'] = 'System';
        }
    }

    // System-level controls belong to the signed-in Superuser account only.
    // An active task view or an edited role permission must never expose this
    // navigation group to Clinic Administrators or operational staff.
    // Focused workspaces hide unrelated owner navigation, but the signed-in
    // Superuser retains full server authority and can return at any time.
    if ($role !== 'super_admin') unset($groups['super']);

    foreach ($groups as $key => &$group) {
        $group['items'] = array_values(array_filter($group['items']));
        if (!$group['items']) unset($groups[$key]);
    }
    unset($group);
    return $groups;
}


function dental_active_treatment_context(): ?array
{
    static $loaded = false;
    static $context = null;
    if ($loaded) return $context;
    $loaded = true;

    $actual = actual_role();
    $active = active_role();
    $isDentist = $active === 'dentist' && active_role_can_operate('dentist');
    $isAssistant = $active === 'dental_assistant' && active_role_can_operate('dental_assistant');
    if (!current_user() || (!$isDentist && !$isAssistant)) return null;
    if (!schema_table_exists(table('queue_entries')) || !schema_table_exists(table('patients')) || !schema_table_exists(table('clinical_encounters'))) return null;

    try {
        if ($isAssistant) {
            if (!encounter_assistant_schema_ready()) return null;
            $stmt = db()->prepare(
                'SELECT q.id queue_entry_id,q.patient_id,q.branch_id,q.queue_no,q.chair_name,q.service_name,q.treatment_started_at,q.updated_at,'
                . 'p.patient_no,p.first_name,p.middle_name,p.last_name,c.id encounter_id,c.dentist_name,c.assistant_name '
                . 'FROM `' . table('clinical_encounters') . '` c '
                . 'JOIN `' . table('queue_entries') . '` q ON q.id=c.queue_entry_id '
                . 'JOIN `' . table('patients') . '` p ON p.id=c.patient_id '
                . 'WHERE c.assistant_user_id=? AND c.status IN ("draft","pending_review") AND q.status="in_treatment" '
                . 'ORDER BY COALESCE(q.treatment_started_at,q.updated_at,q.checked_in_at) DESC,c.id DESC LIMIT 2'
            );
        } else {
            $stmt = db()->prepare(
                'SELECT q.id queue_entry_id,q.patient_id,q.branch_id,q.queue_no,q.chair_name,q.service_name,q.treatment_started_at,q.updated_at,'
                . 'p.patient_no,p.first_name,p.middle_name,p.last_name,'
                . '(SELECT c.id FROM `' . table('clinical_encounters') . '` c WHERE c.queue_entry_id=q.id AND c.status IN ("draft","pending_review") ORDER BY c.id DESC LIMIT 1) encounter_id '
                . 'FROM `' . table('queue_entries') . '` q JOIN `' . table('patients') . '` p ON p.id=q.patient_id '
                . 'WHERE q.dentist_user_id=? AND q.status="in_treatment" '
                . 'ORDER BY COALESCE(q.treatment_started_at,q.updated_at,q.checked_in_at) DESC,q.id DESC LIMIT 2'
            );
        }
        $stmt->execute([(int)(current_user()['id'] ?? 0)]);
        $rows = $stmt->fetchAll();
        if (!$rows) return null;
        $context = $rows[0];
        $context['active_count'] = count($rows);
        $context['viewer_role'] = $isAssistant ? 'dental_assistant' : 'dentist';
        $context['patient_name'] = trim(implode(' ', array_filter([
            (string)($context['first_name'] ?? ''),
            (string)($context['middle_name'] ?? ''),
            (string)($context['last_name'] ?? ''),
        ])));
        $encounterId = (int)($context['encounter_id'] ?? 0);
        $patientId = (int)($context['patient_id'] ?? 0);
        $context['resume_url'] = $encounterId > 0 ? 'clinical_workspace.php?encounter_id=' . $encounterId : ($isAssistant ? 'dashboard.php' : 'doctor_treatment.php');
        $context['patient_url'] = 'patients.php?action=view&id=' . $patientId . '&tab=clinical';
        $context['chart_url'] = 'odontogram.php?patient_id=' . $patientId . ($encounterId > 0 ? '&encounter_id=' . $encounterId : '');
        $context['plan_url'] = 'treatment.php?patient_id=' . $patientId . ($encounterId > 0 ? '&encounter_id=' . $encounterId : '');
        $context['imaging_url'] = 'documents.php?patient_id=' . $patientId . ($encounterId > 0 ? '&encounter_id=' . $encounterId : '');
        return $context;
    } catch (Throwable $exception) {
        error_log('DentalCare active treatment navigation fallback: ' . $exception->getMessage());
        return null;
    }
}

function dental_safe_back_url(string $fallback = 'dashboard.php'): string
{
    $fallback = task_link_allowed($fallback) ? $fallback : 'dashboard.php';
    $referrer = trim((string)($_SERVER['HTTP_REFERER'] ?? ''));
    if ($referrer === '') return $fallback;
    $parts = parse_url($referrer);
    if (!is_array($parts)) return $fallback;
    $refHost = strtolower((string)($parts['host'] ?? ''));
    $currentHost = strtolower(preg_replace('/:\d+$/', '', (string)($_SERVER['HTTP_HOST'] ?? '')));
    if ($refHost === '' || $currentHost === '' || $refHost !== $currentHost) return $fallback;
    $path = basename((string)($parts['path'] ?? ''));
    $current = function_exists('dental_request_script') ? dental_request_script() : basename((string)($_SERVER['PHP_SELF'] ?? ''));
    if ($path === '' || $path === $current || in_array($path, ['login.php','logout.php','install.php','license.php'], true)) return $fallback;
    if (!preg_match('/^[A-Za-z0-9_.-]+\.php$/', $path)) return $fallback;
    $url = $path;
    if (!empty($parts['query'])) $url .= '?' . (string)$parts['query'];
    $result = task_link_allowed($url) ? $url : $fallback;
    return function_exists('dental_clean_url') ? dental_clean_url($result) : $result;
}

function dental_active_navigation_group(array $groups): string
{
    $current = function_exists('dental_request_script') ? dental_request_script() : basename((string) ($_SERVER['PHP_SELF'] ?? ''));
    $requestedArea = trim((string)($_GET['nav_area'] ?? ''));
    if ($requestedArea !== '' && isset($groups[$requestedArea])) {
        foreach ($groups[$requestedArea]['items'] as $item) {
            if (sidebar_url_is_active((string)$item['url'], $current)) return $requestedArea;
        }
    }
    foreach ($groups as $key => $group) {
        foreach ($group['items'] as $item) {
            if (sidebar_url_is_active((string) $item['url'], $current)) return (string) $key;
        }
    }
    return (string) (array_key_first($groups) ?? 'today');
}

function dental_configured_route_for_url(string $url): ?string
{
    $url=html_entity_decode(trim($url),ENT_QUOTES|ENT_HTML5,'UTF-8');
    if($url===''||str_starts_with($url,'#')||str_starts_with($url,'?')||preg_match('#^(?:https?:)?//#i',$url)||str_starts_with($url,'mailto:')||str_starts_with($url,'tel:')||str_starts_with($url,'javascript:'))return null;
    $path=(string)(parse_url($url,PHP_URL_PATH)?:'');
    if($path==='')return null;
    $route=task_route_key($path);
    static $configured=null;
    if($configured===null){
        $routes=is_file(DENTAL_ROOT.'/config/routes.php')?(require DENTAL_ROOT.'/config/routes.php'):[];
        $configured=is_array($routes)?array_fill_keys(array_keys($routes),true):[];
    }
    return isset($configured[$route])?$route:null;
}

function dental_filter_task_preview_post_forms(string $html): string
{
    if (!task_preview_mode() || $html === '') return $html;
    return (string)preg_replace_callback(
        '~<form\b(?P<attrs>[^>]*)>(?P<body>.*?)</form>~is',
        static function(array $match): string {
            $attrs = (string)$match['attrs'];
            $method = 'get';
            if (preg_match('/\bmethod\s*=\s*(["\']?)([^\s"\'>]+)\1/i', $attrs, $methodMatch)) {
                $method = strtolower((string)$methodMatch[2]);
            }
            if ($method !== 'post') return (string)$match[0];

            $action = '';
            if (preg_match('/\baction\s*=\s*(["\'])(.*?)\1/is', $attrs, $actionMatch)) {
                $action = html_entity_decode((string)$actionMatch[2], ENT_QUOTES | ENT_HTML5, 'UTF-8');
            }
            $target = basename((string)(parse_url($action !== '' ? $action : dental_request_script(), PHP_URL_PATH) ?: ''));
            if (in_array($target, ['role_switch.php','my_profile.php'], true)) return (string)$match[0];

            if (!preg_match('/\bdata-task-preview-locked\s*=/i', $attrs)) $attrs .= ' data-task-preview-locked="1"';
            if (!preg_match('/\baria-readonly\s*=/i', $attrs)) $attrs .= ' aria-readonly="true"';
            if (!preg_match('/\bonsubmit\s*=/i', $attrs)) $attrs .= ' onsubmit="return false"';

            $body = (string)$match['body'];
            $body = (string)preg_replace_callback(
                '~<button\b([^>]*)>.*?</button>~is',
                static function(array $button): string {
                    $buttonAttrs = (string)$button[1];
                    if (!preg_match('/\btype\s*=\s*(["\']?)(button|reset)\1/i', $buttonAttrs)) return '';
                    return (string)$button[0];
                },
                $body
            );
            $body = (string)preg_replace('~<input\b[^>]*\btype\s*=\s*(["\']?)submit\1[^>]*>~is', '', $body);
            $body = (string)preg_replace_callback(
                '~<(input|select|textarea)\b([^>]*)>~is',
                static function(array $control): string {
                    $tag = strtolower((string)$control[1]);
                    $controlAttrs = (string)$control[2];
                    if ($tag === 'input' && preg_match('/\btype\s*=\s*(["\']?)hidden\1/i', $controlAttrs)) return (string)$control[0];
                    if (!preg_match('/\bdisabled\b/i', $controlAttrs)) $controlAttrs .= ' disabled';
                    if (!preg_match('/\baria-disabled\s*=/i', $controlAttrs)) $controlAttrs .= ' aria-disabled="true"';
                    return '<' . $tag . $controlAttrs . '>';
                },
                $body
            );
            return '<form' . $attrs . '>' . $body . '</form>';
        },
        $html
    );
}

function dental_filter_unauthorized_task_links(string $html): string
{
    if(!current_user()||$html==='')return $html;
    $html = (string)preg_replace_callback(
        '~<a\\b(?P<before>[^>]*?\\bhref\\s*=\\s*)(?P<quote>["\\\'])(?P<url>.*?)(?P=quote)(?P<after>[^>]*)>~is',
        static function(array $match): string {
            $url=html_entity_decode((string)$match['url'],ENT_QUOTES|ENT_HTML5,'UTF-8');
            if(dental_configured_route_for_url($url)===null||task_link_allowed($url))return (string)$match[0];
            $attributes=(string)$match['before'].(string)$match['quote'].'#'.(string)$match['quote'].(string)$match['after'];
            if(!preg_match('/\\bhidden\\b/i',$attributes))$attributes.=' hidden';
            if(!preg_match('/\\baria-hidden\\s*=/i',$attributes))$attributes.=' aria-hidden="true"';
            if(!preg_match('/\\btabindex\\s*=/i',$attributes))$attributes.=' tabindex="-1"';
            $attributes.=' data-task-link-blocked="1"';
            return '<a'.$attributes.'>';
        },
        $html
    );
    return dental_filter_task_preview_post_forms($html);
}

function dental_quick_actions(): array
{
    $actions = [];
    $activeTreatment = dental_active_treatment_context();
    if (task_context_page_allowed('patients') && navigation_can('patients.manage',['super_admin','clinic_admin','receptionist','staff'])) $actions[]=['url'=>'patients.php?action=new','label'=>'Register Patient','icon'=>'user-plus'];
    if (task_context_page_allowed('appointments') && navigation_can('appointments.manage',['super_admin','clinic_admin','receptionist','staff'])) $actions[]=['url'=>'appointments.php?new=1','label'=>'Book Appointment','icon'=>'calendar'];
    if (task_context_page_allowed('queue') && navigation_can('queue.manage',['super_admin','clinic_admin','receptionist','staff'])) $actions[]=['url'=>'queue.php?walkin=1','label'=>'Register Walk-In','icon'=>'queue'];
    if (task_context_page_allowed('doctor_treatment') && navigation_can('clinical.view',['super_admin','clinic_admin','dentist'])) $actions[]=['url'=>'doctor_treatment.php','label'=>'Open Treatment Dashboard','icon'=>'clinical'];
    if (active_role_is('dental_assistant') && $activeTreatment) $actions[]=['url'=>(string)$activeTreatment['resume_url'],'label'=>'Open Assigned Treatment','icon'=>'clinical'];
    if (task_context_page_allowed('billing') && navigation_can('billing.manage',['super_admin','clinic_admin','cashier','staff'])) $actions[]=['url'=>'billing.php','label'=>'Open Cashier','icon'=>'receipt'];
    if (task_context_page_allowed('inventory') && navigation_can('inventory.manage',['super_admin','clinic_admin','inventory_officer'])) $actions[]=['url'=>'inventory.php','label'=>'Inventory Transaction','icon'=>'inventory'];
    return array_values(array_filter($actions, static fn(array $action): bool => task_link_allowed((string)$action['url'])));
}

function render_header(string $title, bool $public = false): void
{
    $user = current_user();
    if(!$public&&$user&&!defined('DENTAL_TASK_LINK_FILTER_ACTIVE')){
        define('DENTAL_TASK_LINK_FILTER_ACTIVE',true);
        ob_start('dental_filter_unauthorized_task_links');
    }
    if($user)$user['display_name']=user_full_name($user);
    if (!$public && $user && !app_demo_read_only() && !(function_exists('app_orientation_mode_active') && app_orientation_mode_active()) && function_exists('maybe_run_automatic_email_queue') && !defined('DENTAL_EMAIL_QUEUE_SHUTDOWN_REGISTERED')) {
        define('DENTAL_EMAIL_QUEUE_SHUTDOWN_REGISTERED', true);
        register_shutdown_function(static function (): void {
            if (function_exists('fastcgi_finish_request')) { @fastcgi_finish_request(); }
            maybe_run_automatic_email_queue();
        });
    }
    $flashes = take_flashes();
    $brand = branding_profile();
    $routeKey = function_exists('task_route_key') ? task_route_key() : '';
    $clinicalPreviewRoutes = ['clinical','clinical_day','doctor_treatment','clinical_workspace','doctor_profile','odontogram','periodontal','treatment','clinical_tasks','prescriptions','documents','consents','referrals','laboratory','availability'];
    $clinicalTaskPreview = !$public && task_preview_mode() && role_context_has(['dentist','dental_assistant']) && in_array($routeKey,$clinicalPreviewRoutes,true);
    $clinicalWorkspacePage = !$public && $routeKey === 'clinical_workspace';
    $activeTreatment = !$public && $user ? dental_active_treatment_context() : null;
    $pagePatientContext = !$public && $user ? dental_flow_patient_context($routeKey) : null;
    $currentWorkspaceEncounterId = $clinicalWorkspacePage ? (int)($_GET['encounter_id'] ?? $_POST['encounter_id'] ?? 0) : 0;
    $activeTreatmentEncounterId = (int)($activeTreatment['encounter_id'] ?? 0);
    $showActiveTreatmentReturn = $activeTreatment && !in_array($routeKey,['doctor_treatment'],true)
        && (!$clinicalWorkspacePage || $currentWorkspaceEncounterId !== $activeTreatmentEncounterId);
    $breakGlassSession = !$public && $user && function_exists('dental_break_glass_active_session') ? dental_break_glass_active_session() : null;
    $cashierTransactionLocked=false;
    if(!$public&&$user&&role_context_has('cashier')&&schema_table_exists(table('cashier_sessions'))&&schema_column_exists(table('cashier_sessions'),'locked_patient_id')){
        require_once DENTAL_ROOT . '/app/revenue_integrity.php';
        $session=revenue_active_cashier_session(db(),(int)($user['branch_id']??0),(int)($user['id']??0));
        $cashierTransactionLocked=(int)($session['locked_patient_id']??0)>0;
    }
    ?><!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="theme-color" content="<?= e((string)$brand['primary']) ?>">
    <title><?= e($title) ?> · <?= e((string) $brand['name']) ?></title>
    <?php $favicon = (string)($brand['favicon'] ?: 'public/favicon.svg'); ?>
    <link rel="icon" href="<?= e($favicon) ?>" type="image/svg+xml">
    <link rel="alternate icon" href="public/favicon.ico">
    <link rel="stylesheet" href="public/assets/css/app.css?v=<?= e(dental_asset_version('public/assets/css/app.css')) ?>">
    <style>:root{--primary:<?= e((string)$brand['primary']) ?>;--primary2:<?= e((string)$brand['secondary']) ?>;--brand-secondary:<?= e((string)$brand['secondary']) ?>;--brand-accent:<?= e((string)$brand['accent']) ?>}</style>
</head>
<body data-page-route="<?= e($routeKey) ?>" data-branch-id="<?= (int)($user['branch_id'] ?? 0) ?>" data-patient-context-id="<?= (int)($pagePatientContext['patient_id'] ?? 0) ?>" data-encounter-context-id="<?= (int)($pagePatientContext['encounter_id'] ?? 0) ?>" data-fullscreen-policy="off" class="<?= $public ? 'public-page' : 'app-page' ?><?= (!$public && task_preview_mode()) ? ' task-preview-mode' : '' ?><?= $clinicalTaskPreview ? ' clinical-task-preview' : '' ?><?= $clinicalWorkspacePage ? ' clinical-workspace-page' : '' ?><?= $activeTreatment ? ' doctor-has-active-treatment' : '' ?><?= app_demo_read_only() ? ' demo-read-only' : '' ?><?= $cashierTransactionLocked ? ' transaction-navigation-locked' : '' ?>">
<?php if (!$public):
    $actualRole = actual_role();
    $role = active_role();
    $taskRoleOptions = switchable_task_roles($actualRole);
    $requestHost = strtolower(preg_replace('/:\d+$/', '', (string)($_SERVER['HTTP_HOST'] ?? '')));
    $isOwnerHost = $requestHost === 'apps.syllabuild.org';
    $navigationGroups = dental_navigation_groups($role, $actualRole, $isOwnerHost);
    $activeNavigationGroup = dental_active_navigation_group($navigationGroups);
    $quickActions = app_demo_read_only() ? [] : dental_quick_actions();
    if ($clinicalWorkspacePage) $quickActions = [];
    $roleProfile = role_profile($role);
    $actualProfile = role_profile($actualRole);
    $pageHelp = help_support_context($routeKey,$role);
    $sidebarDentistProfile = $actualRole === 'dentist' ? dentist_profile((int)($user['id'] ?? 0)) : null;
    $brandHomeUrl = $actualRole === 'dentist' && $role === 'dentist' ? 'doctor_treatment.php' : 'dashboard.php';
    ?>
<div class="mobile-nav-scrim" data-menu-close></div>
<aside class="sidebar compact-sidebar" aria-label="Application navigation">
    <div class="sidebar-brand-row">
        <a class="brand" href="<?=e($brandHomeUrl)?>"><?= brand_mark($brand) ?><span class="brand-name"><?= e((string)$brand['name']) ?></span></a>
        <button class="sidebar-collapse" type="button" data-sidebar-collapse aria-label="Collapse sidebar"><?= dental_icon('panel-left') ?></button>
    </div>
    <nav class="primary-nav" aria-label="Main application areas">
        <?php foreach ($navigationGroups as $groupKey => $group): $home = dental_navigation_url_with_area((string)$group['items'][0]['url'], (string)$groupKey); ?>
        <?php $home = dental_flow_contextual_url((string)$home, $pagePatientContext); ?>
        <a href="<?=e((string)$home)?>" class="primary-nav-link <?=$activeNavigationGroup===$groupKey?'active':''?>" data-nav-area="<?=e((string)$groupKey)?>" title="<?=e((string)$group['label'])?>"><?=dental_icon((string)$group['icon'],'nav-icon')?><span class="nav-label"><?=e((string)$group['label'])?></span></a>
        <?php endforeach; ?>
    </nav>
    <div class="sidebar-user">
        <div class="sidebar-user-avatar"><?php if(!empty($sidebarDentistProfile['photo_path'])):?><img src="doctor_asset.php?type=photo&variant=thumbnail&user_id=<?=(int)($user['id']??0)?>" alt="<?=e((string)($user['display_name']??$user['name']??'Dentist'))?>"><?php else:?><?=e(strtoupper(substr((string)($user['display_name']??$user['name']??'U'),0,1)))?><?php endif;?></div>
        <a class="sidebar-user-copy" href="my_profile.php" title="Open my profile"><strong><?= e($user['display_name'] ?? $user['name'] ?? 'User') ?></strong><span><?= e((string) $actualProfile['name']) ?></span><?php if ($role !== $actualRole): ?><span class="sidebar-task-view">Task View: <?= e((string) $roleProfile['name']) ?></span><?php endif; ?></a>
        <a class="sidebar-signout" href="logout.php" title="Sign out"><?=dental_icon('logout')?><span>Sign out</span></a>
    </div>
</aside>
<main class="main">
    <header class="topbar">
        <button class="menu-btn" data-menu aria-label="Open navigation"><?=dental_icon('menu')?></button>
        <div class="topbar-title"><span class="topbar-area"><?=e((string)($navigationGroups[$activeNavigationGroup]['label']??''))?></span><h1><?= e($title) ?></h1></div>
        <?php if (task_context_page_allowed('search')): ?>
        <form class="global-search" action="search.php" method="get" role="search" data-auto-submit>
            <?=dental_icon('search','search-icon')?>
            <input type="search" name="q" value="<?=e((string)($_GET['q']??''))?>" placeholder="Search patient, appointment, invoice, or queue…" autocomplete="off" aria-label="Search clinic records" data-auto-search data-min-length="2">
            <span class="search-auto-label">Auto</span>
        </form>
        <?php else: ?>
        <div class="global-search role-search-disabled" aria-live="polite">
            <?=dental_icon('shield','search-icon')?>
            <span>Search hidden for the <?=e((string)$roleProfile['name'])?> role</span>
        </div>
        <?php endif; ?>
        <div class="topbar-actions">
            <?php if ($showActiveTreatmentReturn): ?><a class="btn primary active-treatment-topbar" href="<?=e((string)$activeTreatment['resume_url'])?>" title="Return to <?=e((string)$activeTreatment['patient_name'])?>"><?=dental_icon('clinical')?> <span>Resume <?=e((string)$activeTreatment['patient_name'])?></span></a><?php endif; ?>
            <?php if ($clinicalWorkspacePage): ?><?php if ($activeTreatment && $currentWorkspaceEncounterId === $activeTreatmentEncounterId): ?><a class="btn ghost clinical-patient-link" href="<?=e((string)$activeTreatment['patient_url'])?>"><?=dental_icon('patient')?> <span>Patient data</span></a><?php endif; ?><button class="btn ghost clinical-next-required" type="button" data-next-clinical-required title="Focus the next incomplete clinical requirement (Alt+N)"><?=dental_icon('check')?> <span>Next required</span><kbd>Alt+N</kbd></button><a class="btn ghost clinical-return-link" href="<?=active_role()==='dental_assistant'?'dashboard.php':'doctor_treatment.php'?>"><?=dental_icon('arrow-left')?> <span>Treatment dashboard</span></a><?php endif; ?>
            <?php if ($quickActions): ?><details class="quick-create"><summary class="btn primary"><?=dental_icon('plus')?> <span>Create</span> <?=dental_icon('chevron-down','tiny-icon')?></summary><div class="quick-create-menu"><?php foreach($quickActions as $action):?><a href="<?=e($action['url'])?>"><?=dental_icon($action['icon'])?><span><?=e($action['label'])?></span></a><?php endforeach;?></div></details><?php endif; ?>
            <?php if ($actualRole === 'super_admin' && $role !== 'super_admin'): ?>
            <a class="btn ghost compact task-role-return" href="role_switch.php?return_primary=1" title="Leave the active workspace and return to the signed-in Superuser role"><?=dental_icon('arrow-left')?> <span>Return to Superuser</span></a>
            <?php endif; ?>
            <?php if ($taskRoleOptions): ?>
            <form class="task-role-switcher" method="post" action="role_switch.php" title="Switch to another assigned role. Patient and task context will not follow you."><input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>"><label><span>Task View</span><select name="task_role" onchange="this.form.submit()" aria-label="Switch Task View"><?php foreach ($taskRoleOptions as $roleCode => $roleLabel): ?><option value="<?= e($roleCode) ?>" <?= $role === $roleCode ? 'selected' : '' ?>><?= e($roleLabel) ?></option><?php endforeach; ?></select></label></form>
            <?php endif; ?>
            <?php if ($actualRole === 'super_admin' && $role === 'super_admin' && app_update_pending()): ?><a class="update-chip" href="system_setup.php?tab=updates">Update</a><?php endif; ?>
            <button class="icon-button global-help-button" type="button" data-open="global-help-dialog" title="Help for this page" aria-label="Help for this page"><?=dental_icon('help')?></button>
            <a class="icon-button public-site-link" href="index.php" title="Open public site"><?=dental_icon('external')?></a>
        </div>
    </header>
    <?php if ($breakGlassSession): ?>
    <section class="alert warning emergency-access-banner" role="status" aria-live="polite">
        <div><strong>Emergency administrative access is active.</strong> Scope: <?=e(implode(', ', (array)($breakGlassSession['scope_permissions'] ?? [])))?> · Expires <?=e((string)($breakGlassSession['expires_at'] ?? ''))?>.</div>
        <a class="btn ghost compact" href="break_glass.php">Review or end access</a>
    </section>
    <?php endif; ?>
    <?php if (!$clinicalWorkspacePage && !empty($navigationGroups[$activeNavigationGroup]['items'])):
        $group = $navigationGroups[$activeNavigationGroup];
        $contextItems = array_values($group['items']);
        $currentScript = function_exists('dental_request_script') ? dental_request_script() : basename((string)($_SERVER['PHP_SELF'] ?? ''));
    ?>
    <div class="context-nav-shell context-nav-expanded" data-context-items="<?=count($contextItems)?>"><nav class="context-tabs" aria-label="<?=e((string)$group['label'])?> tools"><?php foreach ($contextItems as $item): $itemUrl = dental_navigation_url_with_area((string)$item['url'], (string)$activeNavigationGroup); $itemUrl = dental_flow_contextual_url($itemUrl, $pagePatientContext); ?><a href="<?=e($itemUrl)?>" class="<?=sidebar_url_is_active((string)$item['url'],$currentScript)?'active':''?>"><?=dental_icon((string)$item['icon'],'context-icon')?><span><?=e((string)$item['label'])?></span><?php if (($item['badge'] ?? '') !== ''): ?><em><?=e((string)$item['badge'])?></em><?php endif; ?></a><?php endforeach; ?></nav></div>
    <?php endif; ?>
    <?php
        $activeGroupHome = dental_navigation_url_with_area((string)($navigationGroups[$activeNavigationGroup]['items'][0]['url'] ?? 'dashboard.php'), (string)$activeNavigationGroup);
        $currentScriptForTrail = function_exists('dental_request_script') ? dental_request_script() : basename((string)($_SERVER['PHP_SELF'] ?? ''));
        $fallbackBack = sidebar_url_is_active($activeGroupHome,$currentScriptForTrail) ? $brandHomeUrl : $activeGroupHome;
        $forceTreatmentReturn = $showActiveTreatmentReturn && !in_array($routeKey,['dashboard'],true);
        $backUrl = $forceTreatmentReturn ? (string)$activeTreatment['resume_url'] : dental_safe_back_url($fallbackBack);
        $backLabel = $forceTreatmentReturn ? 'Return to treatment' : 'Back';
    ?>
    <div class="page-context-bar">
        <a class="page-back-button<?= $forceTreatmentReturn ? ' treatment-return-back' : '' ?>" href="<?=e($backUrl)?>" aria-label="<?=e($backLabel)?>"><?=dental_icon('arrow-left')?><span><?=e($backLabel)?></span></a>
        <nav class="page-breadcrumb" aria-label="Breadcrumb">
            <a href="<?=e($activeGroupHome)?>"><?=e((string)($navigationGroups[$activeNavigationGroup]['label']??'Workspace'))?></a>
            <?=dental_icon('chevron-right','breadcrumb-icon')?>
            <strong><?=e($title)?></strong>
        </nav>
    </div>
    <?php if ($pagePatientContext):
        $journeySteps=dental_visit_journey_steps();
        $journeyKeys=array_keys($journeySteps);
        $currentJourneyIndex=array_search((string)$pagePatientContext['current_step'],$journeyKeys,true);
        if($currentJourneyIndex===false)$currentJourneyIndex=0;
        $primaryContextUrl=trim((string)($pagePatientContext['primary_url']??$pagePatientContext['patient_url']??''));
        $patientRecordUrl=trim((string)($pagePatientContext['patient_url']??''));
        $journeyContextUrl=trim((string)($pagePatientContext['journey_url']??''));
        $primaryContextAllowed=$primaryContextUrl!=='' && task_link_allowed($primaryContextUrl);
        $patientRecordAllowed=$patientRecordUrl!=='' && task_link_allowed($patientRecordUrl);
        $journeyContextAllowed=$journeyContextUrl!=='' && task_link_allowed($journeyContextUrl);
    ?>
    <?php $patientContextIsWorkflow=(string)($pagePatientContext['mode']??'workflow')==='workflow'; ?>
    <section class="patient-journey-context compact-patient-task-bar<?= $patientContextIsWorkflow ? '' : ' patient-record-view-context' ?>" data-patient-flow-context data-patient-context-mode="<?=e((string)($pagePatientContext['mode']??'workflow'))?>" data-patient-id="<?=(int)$pagePatientContext['patient_id']?>" data-encounter-id="<?=(int)$pagePatientContext['encounter_id']?>" aria-label="<?= $patientContextIsWorkflow ? 'Current patient task' : 'Patient record being viewed' ?>">
        <div class="patient-journey-identity">
            <span class="patient-journey-avatar"><?=e(strtoupper(substr((string)$pagePatientContext['patient_name'],0,1)))?></span>
            <div><span><?=e((string)($pagePatientContext['context_label']??($patientContextIsWorkflow?'Active patient':'Viewing patient')))?></span><strong><?=e((string)$pagePatientContext['patient_name'])?></strong><small><?=e((string)$pagePatientContext['patient_no'])?><?=($patientContextIsWorkflow&&!empty($pagePatientContext['queue_no']))?' · Queue '.e((string)$pagePatientContext['queue_no']):''?><?=($patientContextIsWorkflow&&!empty($pagePatientContext['chair_name']))?' · '.e((string)$pagePatientContext['chair_name']):''?></small></div>
        </div>
        <?php if($patientContextIsWorkflow):?>
        <div class="patient-task-progress"><span>Step <?=($currentJourneyIndex+1)?> of <?=count($journeySteps)?> · <?=e((string)$journeySteps[$pagePatientContext['current_step']])?></span><strong><?=e((string)$pagePatientContext['current_owner'])?> → <?=e((string)$pagePatientContext['next_owner'])?></strong><small><?=e((string)$pagePatientContext['next_action'])?></small></div>
        <?php else:?><div class="patient-task-progress patient-record-view-summary"><span>Record view</span><strong>No active visit</strong><small><?=e((string)$pagePatientContext['next_action'])?></small></div><?php endif;?>
        <div class="patient-task-actions">
            <?php if($primaryContextAllowed):?><a class="btn primary compact" href="<?=e($primaryContextUrl)?>"><?=e((string)($pagePatientContext['primary_label']??'Continue task'))?></a><?php endif;?>
            <?php if($patientRecordAllowed):?><a class="btn ghost compact" href="<?=e($patientRecordUrl)?>">Patient record</a><?php endif;?>
            <?php if($patientContextIsWorkflow):?><details class="patient-journey-popover"><summary class="btn ghost compact">View journey</summary><div class="patient-journey-popover-panel"><ol class="patient-journey-steps"><?php foreach($journeySteps as $journeyKey=>$journeyLabel): $journeyIndex=array_search($journeyKey,$journeyKeys,true); $journeyClass=$journeyIndex<$currentJourneyIndex?'done':($journeyIndex===$currentJourneyIndex?'current':'upcoming'); ?><li class="<?=e($journeyClass)?>"><span><?= $journeyClass==='done'?'✓':($journeyIndex+1) ?></span><small><?=e($journeyLabel)?></small></li><?php endforeach; ?></ol><?php if($journeyContextAllowed):?><a href="<?=e($journeyContextUrl)?>">Open full journey</a><?php endif;?></div></details><?php elseif($journeyContextAllowed):?><a class="btn ghost compact" href="<?=e($journeyContextUrl)?>">View visit history</a><?php endif;?>
            <?php if(!empty($pagePatientContext['allow_manual_clear'])):?><a class="patient-context-clear" href="?clear_patient_context=1">Clear</a><?php endif;?>
        </div>
    </section>
    <?php endif; ?>
    <?php if ($showActiveTreatmentReturn && (!$pagePatientContext || (int)$pagePatientContext['patient_id'] !== (int)$activeTreatment['patient_id'])): ?>
    <section class="active-treatment-return-bar" aria-label="Active patient treatment">
        <div class="active-treatment-return-status">
            <?=dental_icon('clinical','active-treatment-return-icon')?>
            <div><span>Active treatment</span><strong><?=e((string)$activeTreatment['patient_name'])?></strong><small><?=e((string)($activeTreatment['patient_no'] ?? ''))?><?= !empty($activeTreatment['queue_no']) ? ' · Queue ' . e((string)$activeTreatment['queue_no']) : '' ?><?= !empty($activeTreatment['chair_name']) ? ' · ' . e((string)$activeTreatment['chair_name']) : '' ?></small></div>
        </div>
        <div class="active-treatment-return-tools">
            <a href="<?=e((string)$activeTreatment['patient_url'])?>">Patient data</a>
            <a href="<?=e((string)$activeTreatment['chart_url'])?>">Tooth chart</a>
            <a href="<?=e((string)$activeTreatment['plan_url'])?>">Treatment plan</a>
            <a href="<?=e((string)$activeTreatment['imaging_url'])?>">Images / X-rays</a>
            <a class="btn primary" href="<?=e((string)$activeTreatment['resume_url'])?>">Resume treatment</a>
        </div>
        <?php if ((int)($activeTreatment['active_count'] ?? 1) > 1): ?><div class="active-treatment-return-warning">Multiple active treatments were detected. Open the treatment dashboard and resolve the duplicate state.</div><?php endif; ?>
    </section>
    <?php endif; ?>
    <?php $activeClinicalContext=(!$public && function_exists('clinical_context_current'))?clinical_context_current():null; ?>
    <?php if($activeClinicalContext): ?>
    <section class="clinical-context-lock-bar" aria-label="Active clinical patient context">
        <div><span class="eyebrow">Active patient context</span><strong><?=e((string)($activeClinicalContext['patient_name']??'Patient'))?></strong><small><?=e((string)($activeClinicalContext['patient_no']??''))?> · Encounter #<?=(int)$activeClinicalContext['encounter_id']?></small></div>
        <div class="status-actions"><a class="btn primary compact" href="clinical_workspace.php?encounter_id=<?=(int)$activeClinicalContext['encounter_id']?>">Resume encounter</a><a class="btn ghost compact" href="patients.php?action=view&amp;id=<?=(int)$activeClinicalContext['patient_id']?>&amp;tab=clinical&amp;encounter_id=<?=(int)$activeClinicalContext['encounter_id']?>">Patient record</a><a class="btn danger ghost compact" href="clinical_workspace.php?exit_context=1">Exit patient record</a></div>
    </section>
    <?php endif; ?>
    <dialog id="global-help-dialog" class="context-help-dialog"><div class="dialog-body"><button type="button" class="dialog-close" data-close>×</button><span class="eyebrow">Page help · <?=e((string)$pageHelp['role_label'])?></span><h2><?=e((string)$pageHelp['title'])?></h2><p><?=e((string)$pageHelp['summary'])?></p><div class="context-help-actions"><?php foreach(array_slice((array)$pageHelp['actions'],0,4) as $index=>$helpAction):?><div><span><?=($index+1)?></span><p><?=e((string)$helpAction)?></p></div><?php endforeach;?></div><div class="alert context-help-limit"><strong>Role limit</strong><span><?=e((string)$pageHelp['role_limits'])?></span></div><div class="dialog-actions"><a class="btn primary" href="help_support.php?from=<?=rawurlencode($routeKey!==''?$routeKey:'dashboard')?>"><?=dental_icon('support')?> Open Help & Support</a><button class="btn ghost" type="button" data-close>Close</button></div></div></dialog>
    <nav class="mobile-bottom-nav" aria-label="Mobile navigation"><?php $bottomGroups=array_slice($navigationGroups,0,4,true); foreach($bottomGroups as $groupKey=>$group):$home=dental_navigation_url_with_area((string)$group['items'][0]['url'], (string)$groupKey);?><a href="<?=e((string)$home)?>" class="<?=$activeNavigationGroup===$groupKey?'active':''?>"><?=dental_icon((string)$group['icon'])?><span><?=e((string)$group['short'])?></span></a><?php endforeach;?><button type="button" data-menu><?=dental_icon('menu')?><span>More</span></button></nav>
<?php endif; ?>
<?php if (app_demo_read_only()): ?><div class="demo-read-only-banner"><strong>Read-only demonstration</strong><span>This copy contains sample clinic records for evaluation. All data creation, editing, deletion, imports, resets, email delivery, and workflow processing are disabled.</span></div><?php endif; ?>
<?php if (!app_demo_read_only() && function_exists('app_orientation_mode_active') && app_orientation_mode_active()): ?><div class="demo-read-only-banner orientation-mode-banner"><strong>Orientation mode active</strong><span>Use fictional demo records for training. Real email queue delivery is paused and receipts/training workflows should be treated as demo-only.</span></div><?php endif; ?>
<?php foreach ($flashes as $flash): ?><div class="flash <?= e($flash['type']) ?>" data-auto-dismiss="10000" role="status"><?= e($flash['message']) ?></div><?php endforeach; ?>
<?php
}

function render_public_nav(string $active = 'home'): void
{
    $clinic = public_clinic_profile();
    $brand = branding_profile();
    $links = function_exists('public_website_nav_links') ? public_website_nav_links() : [
        ['key'=>'home','url'=>'index.php','label'=>'Home'],
        ['key'=>'information','url'=>'index.php#information','label'=>'Clinic Information'],
        ['key'=>'services','url'=>'index.php#services','label'=>'Services'],
        ['key'=>'appointment','url'=>'index.php#appointment','label'=>'Appointments'],
        ['key'=>'contact','url'=>'index.php#contact','label'=>'Contact'],
    ];
    ?>
<?php $headerSubtitle = trim((string)setting_get('website','header_subtitle','Dental care and appointments')) ?: 'Dental care and appointments'; $patientLabel = trim((string)setting_get('website','header_patient_label','Patient Portal')) ?: 'Patient Portal'; $staffLabel = trim((string)setting_get('website','header_staff_label','Staff Portal')) ?: 'Staff Portal'; ?>
<header class="public-header"><div class="public-nav-wrap"><a class="brand" href="index.php" aria-label="<?= e((string)$clinic['name']) ?> home"><?= brand_mark($brand) ?><span><strong><?= e((string)$brand['name']) ?></strong><small><?=e($headerSubtitle)?></small></span></a><button class="public-menu-button" type="button" data-public-menu aria-label="Open public navigation"><?=dental_icon('menu')?></button><nav class="public-nav" data-public-nav><?php foreach($links as $link): $key=(string)($link['key']??''); $url=(string)($link['url']??'#'); $label=(string)($link['label']??'Link'); ?><a href="<?=e($url)?>" class="<?=$active===$key?'active':''?>"><?=e($label)?></a><?php endforeach;?><a class="btn primary" href="patient-login.php"><?=e($patientLabel)?></a><a class="btn ghost" href="login.php"><?=e($staffLabel)?></a></nav></div></header>
<?php
}

function dental_developer_credit(string $class = 'developer-credit'): string
{
    return '<a class="' . e($class) . '" href="mailto:mtbcustomprints@gmail.com"><span>Developer &amp; Programmer</span><strong>MTBCustoms</strong><small>mtbcustomprints@gmail.com</small></a>';
}

function render_public_footer(): void
{
    $clinic=public_clinic_profile();$brand=branding_profile();
    ?>
<?php $socialLinks = function_exists('public_website_social_links') ? public_website_social_links() : []; $footerNote = trim((string)setting_get('website','footer_note','Records are handled through protected clinic access.')) ?: 'Records are handled through protected clinic access.'; ?>
<footer class="public-footer"><div class="public-footer-grid"><div><a class="brand footer-brand" href="index.php"><?=brand_mark($brand)?><span><?=e((string)$brand['name'])?></span></a><p><?=e((string)$clinic['tagline'])?></p><?php if($socialLinks):?><div class="public-social-links"><?php foreach($socialLinks as $social):?><a href="<?=e((string)$social['url'])?>" target="_blank" rel="noopener"><?=e((string)$social['label'])?></a><?php endforeach;?></div><?php endif;?></div><div><strong>Appointments</strong><a href="appointment-new.php">New patient</a><a href="appointment-returning.php">Returning patient</a></div><div><strong>Clinic</strong><a href="index.php#information">Information</a><a href="index.php#services">Services</a><a href="index.php#contact">Contact</a></div><div><strong>Secure access</strong><a href="patient-login.php">Patient portal</a><a href="login.php">Staff portal</a><span><?=e($footerNote)?></span></div></div><div class="public-footer-bottom"><span>© <?=date('Y')?> <?=e((string)$brand['name'])?></span><span><?=e((string)$brand['footer_text'])?></span><?=dental_developer_credit('public-developer-credit')?></div></footer>
<?php
}

function render_footer(bool $public = false): void
{
    if (!$public) echo '<footer class="app-developer-footer">' . dental_developer_credit('app-developer-credit') . '</footer></main>';
    ?><script src="public/assets/js/app.js?v=<?= e(dental_asset_version('public/assets/js/app.js')) ?>"></script><script src="public/assets/js/vital-signs.js?v=<?= e(dental_asset_version('public/assets/js/vital-signs.js')) ?>"></script><script src="public/assets/js/queue-live.js?v=<?= e(dental_asset_version('public/assets/js/queue-live.js')) ?>"></script><script src="public/assets/js/inventory-workflow.js?v=<?= e(dental_asset_version('public/assets/js/inventory-workflow.js')) ?>"></script><script src="public/assets/js/reconciliation-live.js?v=<?= e(dental_asset_version('public/assets/js/reconciliation-live.js')) ?>"></script><?php if(!$public && task_preview_mode()):?><script src="public/assets/js/task-preview-readonly.js?v=<?= e(dental_asset_version('public/assets/js/task-preview-readonly.js')) ?>"></script><?php endif;?><?php if(app_demo_read_only()):?><script src="public/assets/js/demo-read-only.js?v=<?= e(app_release_version()) ?>"></script><?php endif;?></body></html><?php
}

function stat_card(string $label, string|int $value, string $note = ''): void
{
    ?><div class="stat-card"><span><?= e($label) ?></span><strong><?= e($value) ?></strong><small><?= e($note) ?></small></div><?php
}
