<?php
// ============================================================
//  MediCore — Shared Layout Header
//  File: includes/header.php
//  Usage: require_once 'includes/header.php';
//         $page = 'dashboard';   // set $page BEFORE including
//         $title = 'Dashboard';  // optional, used in <title>
// ============================================================

require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/notify.php';
require_once __DIR__ . '/po_approval.php';
require_once __DIR__ . '/form_icons.php';
require_once __DIR__ . '/customer_portal.php';
require_once __DIR__ . '/reporting.php';
require_login();

$settings = get_settings();
ensure_topbar_tables();
ensure_po_approval_columns();
ensure_customer_portal_schema();
ensure_categories_schema();
ensure_reporting_schema();
$__page   = $page  ?? 'dashboard';
$__title  = $title ?? ucfirst(str_replace('-', ' ', $__page));
// A page can set $hidePageHeader = true before including this file to skip
// the thin title/actions bar entirely — for pages (like dashboard.php) that
// build their own richer header treatment and would otherwise show two
// stacked headers.
$__hidePageHeader = !empty($hidePageHeader);

// Sidebar nav groups — matches original HTML exactly
// Nav items — each has [slug, icon, label, module_key, optional_badge]
// module_key maps to APP_MODULES permission keys
$nav = [
    '' => [
        ['dashboard',             '📊', 'Dashboard',          'dashboard'],
    ],
    'Product' => [
        ['product/list',          '📋', 'Product',             'product_list'],
        ['product/companies',     '🏭', 'Companies',           'companies'],
        ['product/generics',      '🧬', 'Generics',            'generics'],
        ['product/categories',    '🏷️', 'Categories',          'categories'],
        ['product/smart-requisition','🤖', 'Smart Requisition',  'requisition'],
        ['product/requisition',   '📝', 'Manual Requisition',  'requisition'],
        ['product/req-record',    '🗂',  'Requisition Record',  'req_record'],
        ['product/expired',       '⏰', 'Expired Products',    'expired', 'exp-badge'],
    ],
    'Supplier' => [
        ['supplier/list',         '🏢', 'Supplier List',       'supplier'],
        ['purchase/list',         '📥', 'Purchase Record',     'purchase_list'],
        ['purchase/approvals',    '🧾', 'PO Approvals',        'purchase_list', 'po-approval-badge'],
        ['purchase/return-list',  '↩',  'Purchase Returns',    'purchase_list'],
    ],
    'Customer' => [
        ['customer/list',         '👤', 'Customer List',       'customer'],
        ['sale/list',             '📤', 'Sale Record',         'sale_list'],
        ['sale/return-list',      '↩',  'Sale Returns',        'sale_list'],
        ['sale/online-orders',    '🌐', 'Online Orders',       'sale_list', 'online-order-badge'],
    ],
    'Cash' => [
        ['accounting/cash',       '💵', 'Cash Balance',        'cash'],
        ['accounting/investment', '🏦', 'Investment',          'investment'],
    ],
    'Accounting' => [
        ['accounting/accounts',   '💰', 'Income / Expense',   'accounts'],
    ],
    '' . PHP_EOL => [
        ['settings',              '⚙️', 'Settings',            'settings'],
        ['recycle/index',         '🗑', 'Recycle Bin',         'admin'],
    ],
];

// Color-coded icon chips — a distinct accent per section so nav items
// are identifiable by color at a glance, not just icon shape (also
// carries the sidebar's "identity" when collapsed to icon-only). Keyed
// by slug rather than group so a couple of items can intentionally
// break from their group's color where it reads more intuitively
// (Expired Products / Recycle Bin in red for urgency/deletion, even
// though they otherwise sit in the Product/admin groups).
$navIconColor = [
    'dashboard'                => 'brand',
    'product/list'              => 'purple',
    'product/companies'         => 'purple',
    'product/generics'          => 'purple',
    'product/categories'        => 'purple',
    'product/smart-requisition' => 'purple',
    'product/requisition'       => 'purple',
    'product/req-record'        => 'purple',
    'product/expired'           => 'danger',
    'supplier/list'              => 'teal',
    'purchase/list'              => 'teal',
    'purchase/approvals'         => 'teal',
    'purchase/return-list'       => 'teal',
    'customer/list'              => 'pink',
    'sale/list'                  => 'pink',
    'sale/return-list'           => 'pink',
    'sale/online-orders'         => 'pink',
    'accounting/cash'            => 'accent',
    'accounting/investment'      => 'accent',
    'accounting/accounts'        => 'warn',
    'settings'                   => 'brand',
    'recycle/index'               => 'danger',
];

// ── Active-menu aliasing ─────────────────────────────────────────
// Some real pages (Create/Edit/Detail-style workflow screens) don't
// have their own sidebar entry — they're reached FROM one of the pages
// above and belong to the same module, but $__page won't exact-match
// any $nav slug for them, so without this map NOTHING would highlight
// while a user is on one of these screens. Keyed by the page's own
// $page value, mapped to the sidebar slug that should stay active for
// the whole time the user is working in that workflow.
$navPageAliases = [
    // Sale Entry is where a sale is actually built — same module as
    // Sale Record (both gated by the 'sale_list' permission).
    'sale/entry'         => 'sale/list',
    // Purchase Entry (PO creation) — same module as Purchase Record,
    // and reached from it / from PO Approvals / Smart Requisition.
    'purchase/entry'     => 'purchase/list',
    // Low Stock Alert Qty lives on the Requisition tab bar alongside
    // Smart/Manual Requisition and Requisition Record — treat it as
    // part of that same workflow for sidebar purposes.
    'product/stock-alert' => 'product/smart-requisition',
];
// The slug actually used for every "is this the active menu?" check
// below — the real $__page for everything else, so page titles etc.
// elsewhere in this file still reflect the real page.
$__navActivePage = $navPageAliases[$__page] ?? $__page;

// Count expired products for badge
$expiredCount = (int) db_val(
    "SELECT COUNT(DISTINCT p.id)
       FROM products p
       JOIN purchase_items pi ON pi.product_id = p.id
      WHERE pi.exp != '' AND pi.exp < DATE_FORMAT(NOW(),'%Y-%m')"
) ?? 0;

// Count purchase orders awaiting approval, for the PO Approvals nav badge
$poApprovalPending = (int) db_val(
    "SELECT COUNT(*) FROM purchases WHERE is_deleted = 0 AND approval_status = 'pending'"
) ?? 0;

// Count online orders awaiting staff review, for the Online Orders nav badge
$onlineOrderPending = (int) db_val(
    "SELECT COUNT(*) FROM online_orders WHERE status = 'pending'"
) ?? 0;

// ── Reports submenu (used in sidebar dropdown + requisition-tabs.php) ──
$reportLinks = [
    // Profit Report entry only included for users with the "Profit
    // Visibility" permission — the other reports in this list stay
    // controlled purely by the existing 'profit' module permission
    // below (which gates the whole Reports submenu), so a cashier
    // who can see Inventory/Sales/Purchase/Financial reports doesn't
    // lose that just because they lack profit_view.
    ...(can_view_profit() ? [['accounting/profit', '📈', 'Profit Report']] : []),
    ['accounting/reports-inventory', '📋', 'Inventory Reports'],
    ['accounting/reports-sales',     '💊', 'Sales Reports'],
    ['accounting/reports-purchase',  '📦', 'Purchase Reports'],
    ['accounting/reports-financial', '💰', 'Financial Reports'],
    ['accounting/returns-report',    '↩',  'Returns Report'],
];
$__reportPages = array_column($reportLinks, 0);
$__reportsActive = in_array($__page, $__reportPages);
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title><?= htmlspecialchars($__title) ?> — <?= htmlspecialchars($settings['shop_name']) ?></title>
  <link rel="stylesheet" href="<?= base_url('assets/style.css') ?>">
  <!-- Theme variables from Settings (overrides CSS defaults) -->
  <?php
  $__brand   = $settings['theme_brand']   ?? '#2d3a8c';
  $__brand2  = $settings['theme_brand2']  ?? '#3d4eb3';
  $__accent  = $settings['theme_accent']  ?? '#1a9e6e';
  $__sidebar = $settings['theme_sidebar'] ?? '#1e2660';
  // Only inject if customised
  if ($__brand !== '#2d3a8c' || $__brand2 !== '#3d4eb3'
   || $__accent !== '#1a9e6e' || $__sidebar !== '#1e2660'):
  ?>
  <style>
    :root {
      --brand:   <?= htmlspecialchars($__brand)   ?>;
      --brand2:  <?= htmlspecialchars($__brand2)  ?>;
      --accent:  <?= htmlspecialchars($__accent)  ?>;
      --topbar:  <?= htmlspecialchars($__brand)   ?>;
      --sidebar: <?= htmlspecialchars($__sidebar) ?>;
      --sidebar2:<?= htmlspecialchars($__brand2)  ?>;
      --brand-xlight: <?= htmlspecialchars($__brand) ?>22;
      --brand-light:  <?= htmlspecialchars($__brand) ?>44;
      --accent-xlight:<?= htmlspecialchars($__accent) ?>22;
      --accent-light: <?= htmlspecialchars($__accent) ?>66;
    }
  </style>
  <?php endif; ?>
  <!-- Layout + flash overrides -->
  <style>
    .app{display:flex;flex-direction:column;height:100vh;overflow:hidden}
    .flash-success{background:#d4f0e6;border:1px solid #1a9e6e;color:#0d6e49;padding:8px 14px;border-radius:5px;font-size:12px;margin-bottom:10px}
    .flash-error  {background:#fde8e8;border:1px solid #d32f2f;color:#b91c1c;padding:8px 14px;border-radius:5px;font-size:12px;margin-bottom:10px}
  </style>
<script>
// ── Sidebar collapse / expand ──────────────────────────────────
// Runs before body renders to apply saved state immediately (no flash).
(function(){
  const sidebar = document.getElementById('sidebar');
  if (!sidebar) return; // sidebar not yet in DOM — handled in DOMContentLoaded
  if (localStorage.getItem('sidebar_collapsed') === '1') sidebar.classList.add('collapsed');
})();
function toggleSidebar() {
  const sidebar  = document.getElementById('sidebar');
  const btn      = document.getElementById('sidebar-toggle');
  const collapsed = sidebar.classList.toggle('collapsed');
  localStorage.setItem('sidebar_collapsed', collapsed ? '1' : '0');
  btn.textContent = collapsed ? '▶' : '☰';
}
document.addEventListener('DOMContentLoaded', function() {
  const sidebar = document.getElementById('sidebar');
  const btn     = document.getElementById('sidebar-toggle');
  if (!sidebar || !btn) return;
  const collapsed = localStorage.getItem('sidebar_collapsed') === '1';
  if (collapsed) sidebar.classList.add('collapsed');
  btn.textContent = collapsed ? '▶' : '☰';
});
</script>
<style>
/* ── Offline badge (kept for assets/offline.js compatibility, but no
   longer rendered — the whole top bar changes colour instead; see
   .topbar.state-* rules in style.css) ────────────────────────── */
.offline-badge{display:none}
</style>

<!-- Offline module (before page scripts) -->
<script>
window.MEDI_API_BASE = '<?= rtrim(base_url('api'), '/') . '/' ?>';
</script>
<script src="<?= base_url('assets/offline.js') ?>"></script>

<!-- Service Worker registration -->
<script>
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('<?= base_url('assets/sw.js') ?>', {
      scope: '<?= base_url('') ?>/'
    }).catch(() => {}); // non-fatal
  });
}
</script>

<!-- Medicine form-type icons (assets/form-icons.js) —
     mirrors includes/form_icons.php, used by any page's JS that
     renders product names (search dropdowns, cart rows, etc). -->
<script src="<?= base_url('assets/form-icons.js') ?>"></script>

<!-- Smart Top Status Bar module — server health, notifications,
     push messages, tasks (assets/topbar.js) -->
<script src="<?= base_url('assets/topbar.js') ?>"></script>

<!-- Live Stock Sync — polls for stock changes made by other open
     terminals and patches [data-stock-id] elements + fires
     medi:stock-sync so pages can react (assets/stock-sync.js) -->
<script src="<?= base_url('assets/stock-sync.js') ?>"></script>

</head>
<body>
<div class="app">

<!-- ── TOP BAR ──────────────────────────────────────── -->
<div class="topbar state-online">
  <button class="sidebar-toggle" id="sidebar-toggle" onclick="toggleSidebar()"
          title="Collapse / expand menu">☰</button>
  <div class="tb-brand">
    <div class="tb-logo" id="tb-logo-box">
      <?php if (!empty($settings['logo'])): ?>
        <img src="<?= htmlspecialchars($settings['logo']) ?>"
             style="width:100%;height:100%;object-fit:cover;border-radius:6px">
      <?php else: ?><span>💊</span><?php endif; ?>
    </div>
    <span id="tb-shop-name"><?= htmlspecialchars($settings['shop_name']) ?></span>
  </div>

  <div class="tb-sep"></div>
  <a class="tb-btn <?= $__page==='sale/entry'  ?'active':'' ?>"
     href="<?= base_url('sale/entry.php') ?>">🛒 Sale</a>
  <a class="tb-btn <?= $__page==='purchase/entry' ?'active':'' ?>"
     href="<?= base_url('purchase/entry.php') ?>">📦 Purchase</a>
  <a class="tb-btn <?= $__page==='accounting/cash' ?'active':'' ?>"
     href="<?= base_url('accounting/cash.php') ?>">💵 Cash Count</a>
  <!-- Running alerts / announcements (Smart Top Status Bar) -->
  <div id="topbar-ticker"></div>

  <div class="tb-right">

    <!-- Notification bell -->
    <div class="tb-icon-wrap">
      <button class="tb-icon-btn" id="tb-notif-btn" title="Notifications">
        🔔<span class="tb-badge" id="tb-notif-count"></span>
      </button>
      <div class="tb-panel" id="tb-notif-panel">
        <div class="tb-panel-hd">
          <span>🔔 Notifications</span>
          <div class="tb-panel-hd-actions">
            <button class="btn btn-xs" id="tb-notif-markall">Mark all read</button>
          </div>
        </div>
        <div class="tb-panel-body" id="tb-notif-body"></div>
        <div class="tb-panel-ft">
          <label class="tb-sound-label">
            <input type="checkbox" id="tb-sound-toggle"> 🔊 Sound
          </label>
          <span>Newest first</span>
        </div>
      </div>
    </div>

    <!-- Push messages -->
    <div class="tb-icon-wrap">
      <button class="tb-icon-btn" id="tb-push-btn" title="Push Messages">
        📨<span class="tb-badge" id="tb-push-count"></span>
      </button>
      <div class="tb-panel" id="tb-push-panel">
        <div class="tb-panel-hd">
          <span>📨 Messages</span>
          <?php if (is_admin()): ?>
          <div class="tb-panel-hd-actions">
            <button class="btn btn-xs" id="tb-push-compose">+ New</button>
          </div>
          <?php endif; ?>
        </div>
        <div class="tb-panel-body" id="tb-push-body"></div>
      </div>
    </div>

    <!-- Tasks -->
    <div class="tb-icon-wrap">
      <button class="tb-icon-btn" id="tb-task-btn" title="Tasks">
        ✅<span class="tb-badge" id="tb-task-count"></span>
      </button>
      <div class="tb-panel" id="tb-task-panel">
        <div class="tb-panel-hd">
          <span>✅ Tasks</span>
          <?php if (is_admin() || current_user_role() === 'manager'): ?>
          <div class="tb-panel-hd-actions">
            <button class="btn btn-xs" id="tb-task-compose">+ New</button>
          </div>
          <?php endif; ?>
        </div>
        <div class="tb-panel-body" id="tb-task-body"></div>
      </div>
    </div>

    <a href="<?= base_url('profile.php') ?>" class="tb-user" style="text-decoration:none" title="My Profile">
      <div class="tb-av">
        <?php $__uPhoto = current_user_photo(); ?>
        <?php if ($__uPhoto): ?>
          <img src="<?= htmlspecialchars($__uPhoto) ?>" alt="">
        <?php else: ?>
          <?= htmlspecialchars(current_user_av()) ?>
        <?php endif; ?>
      </div>
      <span><?= htmlspecialchars(current_user_name()) ?></span>
    </a>
    <a href="<?= base_url('logout.php') ?>" class="tb-logout" title="Log out"
       onclick="return confirm('Log out?')">
      <svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor"
           stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
        <polyline points="16 17 21 12 16 7"></polyline>
        <line x1="21" y1="12" x2="9" y2="12"></line>
      </svg>
      <span>Logout</span>
    </a>
  </div>
</div><!-- /topbar -->

<div class="main-row">

<!-- ── SIDEBAR ──────────────────────────────────────── -->
<div class="sidebar" id="sidebar">
<?php foreach ($nav as $group => $items):
    $visibleItems = array_filter($items, fn($item) => can($item[3] ?? 'dashboard'));
    if (!$visibleItems) continue;

    $label        = trim($group);
    $groupSlugs   = array_column($items, 0);
    $groupActive  = in_array($__navActivePage, $groupSlugs);
    $isAccounting = ($label === 'Accounting');
    if ($isAccounting && $__reportsActive) $groupActive = true;
    $groupId = $label ? 'ng-' . preg_replace('/\W+/', '', strtolower($label)) : 'ng-top';
?>
  <div class="ni-group<?= $groupActive ? ' group-active' : '' ?>" id="<?= $groupId ?>">
    <?php if ($label): ?>
    <div class="ni-group-label<?= $groupActive ? ' active' : '' ?>" onclick="toggleNavGroup('<?= $groupId ?>')">
      <?= htmlspecialchars($label) ?>
      <span class="ng-chevron">&#9662;</span>
    </div>
    <?php endif; ?>
    <div class="ni-group-items">
    <?php foreach ($visibleItems as $item):
        [$slug, $icon, $text, $moduleKey] = array_pad($item, 4, '');
        $badge    = $item[4] ?? null;
        $href     = base_url($slug . '.php');
        $active   = ($__navActivePage === $slug) ? ' active' : '';
        $viewOnly = !is_admin() && can($moduleKey, 'view') && !can($moduleKey, 'full');
        $icColor  = $navIconColor[$slug] ?? 'brand';
    ?>
      <a class="ni<?= $active ?>" href="<?= $href ?>"
         title="<?= $viewOnly ? 'View Only' : '' ?>"
         data-tip="<?= htmlspecialchars($text) ?>">
        <span class="ni-ic ic-<?= $icColor ?>"><?= $icon ?></span>
        <?= htmlspecialchars($text) ?>
        <?php if ($viewOnly): ?>
          <span style="font-size:9px;opacity:.5;margin-left:auto">&#128065;</span>
        <?php endif; ?>
        <?php if ($badge === 'exp-badge' && $expiredCount > 0): ?>
          <div class="ni-badge" id="exp-badge"><?= $expiredCount ?></div>
        <?php endif; ?>
        <?php if ($badge === 'online-order-badge'): ?>
          <div class="ni-badge" id="online-order-badge"
               style="<?= $onlineOrderPending > 0 ? '' : 'display:none' ?>">
            <?= $onlineOrderPending ?>
          </div>
        <?php endif; ?>
        <?php if ($badge === 'po-approval-badge'): ?>
          <div class="ni-badge" id="po-approval-badge"
               style="<?= $poApprovalPending > 0 ? '' : 'display:none' ?>">
            <?= $poApprovalPending ?>
          </div>
        <?php endif; ?>
      </a>
    <?php endforeach; ?>

    <?php if ($isAccounting && can('profit')): ?>
    <div class="ni-submenu<?= $__reportsActive ? ' open' : '' ?>">
      <button type="button" class="ni ni-submenu-toggle<?= $__reportsActive ? ' active' : '' ?>"
              onclick="toggleReportsMenu(this)">
        <span class="ni-ic ic-teal">&#128202;</span>
        Reports
        <span class="ni-chevron">&#9662;</span>
      </button>
      <div class="ni-submenu-list" style="<?= $__reportsActive ? '' : 'display:none' ?>">
        <?php foreach ($reportLinks as [$rSlug, $rIcon, $rLabel]):
          $rActive = ($__page === $rSlug) ? ' active' : '';
          $rHref   = base_url($rSlug . '.php');
        ?>
        <a class="ni ni-submenu-item<?= $rActive ?>" href="<?= $rHref ?>">
          <span class="ni-ic ic-teal"><?= $rIcon ?></span>
          <?= htmlspecialchars($rLabel) ?>
        </a>
        <?php endforeach; ?>
      </div>
    </div>
    <?php endif; ?>
    </div><!-- /ni-group-items -->
  </div><!-- /ni-group -->
<?php endforeach; ?>

<?php
// Reporting Engine sidebar entry removed per request (2026-07-18).
// The underlying feature (custom_reports table, reporting/view.php,
// api/reporting.php, the 'reporting_engine' permission, and the
// Reporting Engine tab in Settings) is untouched — this just stops
// rendering its dynamic nav group, so it's no longer reachable from
// the sidebar. Re-add the block from git history / prior session if
// it needs to come back.
?>

<script>
function toggleNavGroup(id) {
  const group = document.getElementById(id);
  if (!group) return;
  const closed = group.classList.toggle('closed');
  const stored = (localStorage.getItem('nav_closed') || '').split(',').filter(Boolean);
  if (closed) { if (!stored.includes(id)) stored.push(id); }
  else { const i = stored.indexOf(id); if (i > -1) stored.splice(i, 1); }
  localStorage.setItem('nav_closed', stored.join(','));
}
(function() {
  const stored = (localStorage.getItem('nav_closed') || '').split(',').filter(Boolean);
  stored.forEach(function(id) {
    const group = document.getElementById(id);
    if (!group) return;
    // Never close the group that contains the current active page
    if (!group.querySelector('.ni.active, .ni-submenu-toggle.active'))
      group.classList.add('closed');
  });
})();

// Initialise offline module (non-blocking, runs after page ready)
if (window.MediOffline) {
  document.addEventListener('DOMContentLoaded', () => {
    MediOffline.init(window.MEDI_API_BASE).catch(() => {});
  });
}
</script>
</div><!-- /sidebar -->

<!-- ── CONTENT AREA ─────────────────────────────────── -->
<div class="content-area">
  <?php if (!$__hidePageHeader): ?>
  <div class="page-header" id="page-header">
    <div class="ph-title"><?= htmlspecialchars($__title) ?></div>
    <div id="ph-actions" style="display:flex;gap:7px;align-items:center">
      <?php /* each page echoes its own action buttons here */ ?>
    </div>
  </div>
  <?php endif; ?>

  <?php /* flash messages */ ?>
  <?php if (!empty($_SESSION['flash_success'])): ?>
    <div class="flash-success"><?= htmlspecialchars($_SESSION['flash_success']) ?></div>
    <?php unset($_SESSION['flash_success']); ?>
  <?php endif; ?>
  <?php if (!empty($_SESSION['flash_error'])): ?>
    <div class="flash-error"><?= htmlspecialchars($_SESSION['flash_error']) ?></div>
    <?php unset($_SESSION['flash_error']); ?>
  <?php endif; ?>

  <div class="content" id="content">
<!-- ── page content starts here ─────────────────────── -->
