/* global React, Icons, AppContext */
const { useState, useEffect, useContext, useMemo, createElement: h, Fragment } = React;

const normalizeDisplayNumber = (value) => {
  const number = Number(value) || 0;
  return Math.round(number * 10) / 10;
};

const formatDisplayNumber = (value) => {
  const rounded = normalizeDisplayNumber(value);
  return new Intl.NumberFormat('en-US', {
    minimumFractionDigits: Number.isInteger(rounded) ? 0 : 1,
    maximumFractionDigits: 1,
  }).format(rounded);
};

window.fmtNum = (value) => formatDisplayNumber(value);
window.fmtEGP = (value) => `${formatDisplayNumber(value)} ج.م`;
window.fmtPercent = (value) => `${formatDisplayNumber(Math.max(0, Number(value) || 0))}%`;
window.fmtDate = (dateValue) => {
  try {
    const date = new Date(dateValue);
    if (Number.isNaN(date.getTime())) return String(dateValue || '—');
    const day = String(date.getDate()).padStart(2, '0');
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const year = date.getFullYear();
    return `${day}/${month}/${year}`;
  } catch {
    return String(dateValue || '—');
  }
};
window.fmtMonthYear = (dateValue) => {
  try {
    const date = new Date(dateValue);
    if (Number.isNaN(date.getTime())) return String(dateValue || '—');
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const year = date.getFullYear();
    return `${month}/${year}`;
  } catch {
    return String(dateValue || '—');
  }
};

const escapeHtml = (value) => String(value ?? '')
  .replace(/&/g, '&amp;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;')
  .replace(/"/g, '&quot;')
  .replace(/'/g, '&#39;');

const openPrintWindow = ({ title = 'طباعة', bodyHtml = '', features = 'width=960,height=820' } = {}) => {
  const popup = window.open('', '_blank', features);
  if (!popup) return null;
  popup.document.open();
  popup.document.write(`<!doctype html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>${escapeHtml(title)}</title>
  <style>
    :root { color-scheme: light; }
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: Arial, Helvetica, sans-serif;
      background: #ffffff;
      color: #111827;
      direction: rtl;
      text-align: right;
    }
    img { max-width: 100%; }
    table { width: 100%; border-collapse: collapse; }
    th, td { vertical-align: top; }
    @page { size: auto; margin: 12mm; }
  </style>
</head>
<body>${bodyHtml}</body>
</html>`);
  popup.document.close();
  setTimeout(() => {
    try {
      popup.focus();
      popup.print();
    } catch (error) {
      console.warn('[Senan] print popup failed:', error);
    }
  }, 120);
  return popup;
};

window.escapeHtml = escapeHtml;
window.openPrintWindow = openPrintWindow;

const DEFAULT_DATE_RANGE_PRESETS = [
  ['today', 'اليوم'],
  ['yesterday', 'أمس'],
  ['current_week', 'الأسبوع الحالي'],
  ['current_month', 'الشهر الحالي'],
  ['previous_month', 'الشهر السابق'],
  ['last_3_months', 'آخر 3 شهور'],
  ['last_6_months', 'آخر 6 شهور'],
  ['current_year', 'السنة الحالية'],
  ['previous_year', 'السنة السابقة'],
];

const dateKeyFromDate = (date) => {
  if (!(date instanceof Date) || Number.isNaN(date.getTime())) return '';
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
};

const parseDateKey = (value) => {
  const parts = String(value || '').slice(0, 10).split('-').map(Number);
  if (parts.length !== 3 || parts.some(Number.isNaN)) return null;
  return new Date(parts[0], parts[1] - 1, parts[2]);
};

const getConfiguredClinicTimeZone = () => {
  const configured = window.SENAN_CLINIC_TIMEZONE || window.localStorage?.getItem('senan-clinic-timezone') || 'Africa/Cairo';
  return configured === 'local' ? undefined : configured;
};

const getCurrentClinicDateKey = () => {
  try {
    const timeZone = getConfiguredClinicTimeZone();
    return new Intl.DateTimeFormat('en-CA', timeZone ? { timeZone } : {}).format(new Date());
  } catch {
    return new Date().toISOString().slice(0, 10);
  }
};

const resolveDateRangePreset = (presetKey, baseDateValue = getCurrentClinicDateKey()) => {
  const today = parseDateKey(baseDateValue) || new Date();
  const startOfMonth = (date) => new Date(date.getFullYear(), date.getMonth(), 1);
  const endOfMonth = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0);
  const startOfYear = (date) => new Date(date.getFullYear(), 0, 1);
  const endOfYear = (date) => new Date(date.getFullYear(), 11, 31);
  const addDays = (date, days) => {
    const next = new Date(date);
    next.setDate(next.getDate() + days);
    return next;
  };
  let fromValue = '';
  let toValue = '';
  switch (presetKey) {
    case 'today':
      fromValue = dateKeyFromDate(today);
      toValue = dateKeyFromDate(today);
      break;
    case 'yesterday': {
      const yesterday = addDays(today, -1);
      fromValue = dateKeyFromDate(yesterday);
      toValue = dateKeyFromDate(yesterday);
      break;
    }
    case 'current_week': {
      const weekStart = addDays(today, -today.getDay());
      fromValue = dateKeyFromDate(weekStart);
      toValue = dateKeyFromDate(today);
      break;
    }
    case 'current_month':
      fromValue = dateKeyFromDate(startOfMonth(today));
      toValue = dateKeyFromDate(today);
      break;
    case 'previous_month': {
      const previousMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
      fromValue = dateKeyFromDate(startOfMonth(previousMonth));
      toValue = dateKeyFromDate(endOfMonth(previousMonth));
      break;
    }
    case 'last_3_months':
      fromValue = dateKeyFromDate(startOfMonth(new Date(today.getFullYear(), today.getMonth() - 2, 1)));
      toValue = dateKeyFromDate(today);
      break;
    case 'last_6_months':
      fromValue = dateKeyFromDate(startOfMonth(new Date(today.getFullYear(), today.getMonth() - 5, 1)));
      toValue = dateKeyFromDate(today);
      break;
    case 'current_year':
      fromValue = dateKeyFromDate(startOfYear(today));
      toValue = dateKeyFromDate(today);
      break;
    case 'previous_year': {
      const previousYear = new Date(today.getFullYear() - 1, 0, 1);
      fromValue = dateKeyFromDate(startOfYear(previousYear));
      toValue = dateKeyFromDate(endOfYear(previousYear));
      break;
    }
    default:
      fromValue = '';
      toValue = '';
  }
  return { fromValue, toValue };
};

const getDateRangeLabel = (dateFrom, dateTo) => {
  if (!dateFrom && !dateTo) return 'كل التواريخ';
  if (dateFrom && dateTo && dateFrom === dateTo) return window.fmtDate(dateFrom);
  if (dateFrom && dateTo) return `${window.fmtDate(dateFrom)} - ${window.fmtDate(dateTo)}`;
  if (dateFrom) return `من ${window.fmtDate(dateFrom)}`;
  return `حتى ${window.fmtDate(dateTo)}`;
};

function DateRangeFilter({
  title = 'فلتر التاريخ',
  subtitle = 'اختر فترة جاهزة أو حدّد من يوم إلى يوم',
  dateFrom = '',
  dateTo = '',
  open = false,
  onToggle,
  onClose,
  onFromChange,
  onToChange,
  onPresetSelect,
  activePreset = 'all',
  onClear,
  onApply,
  presets = DEFAULT_DATE_RANGE_PRESETS,
  buttonWidth = 'min(300px, 100%)',
  menuWidth = 'min(380px, calc(100vw - 64px))',
  align = 'start',
}) {
  const selectedRangeLabel = getDateRangeLabel(dateFrom, dateTo);
  const justifyContent = align === 'start' ? 'flex-start' : 'flex-end';
  const menuAnchorStyle = align === 'start' ? { left: 0, right: 'auto' } : { right: 0, left: 'auto' };

  return h('div', { style: { position: 'relative', marginBottom: 12, display: 'flex', justifyContent, direction: 'ltr' } },
    h('button', {
      className: 'btn outline',
      onClick: () => onToggle && onToggle(),
      style: {
        minHeight: 42,
        paddingInline: 12,
        justifyContent: 'space-between',
        width: buttonWidth,
        direction: 'rtl',
      },
    },
      h('span', { className: 'flex gap-8 ai-c' },
        h(Icons.Calendar, { size: 15 }),
        h('span', null, selectedRangeLabel),
      ),
      h(Icons.ChevronDown, { size: 14 }),
    ),
    open ? h('div', {
      className: 'fade-in',
      style: {
        position: 'absolute',
        top: 'calc(100% + 10px)',
        width: menuWidth,
        background: '#ffffff',
        border: '1px solid var(--border)',
        borderRadius: 18,
        boxShadow: '0 18px 40px rgba(15, 23, 42, .14)',
        padding: 12,
        opacity: 1,
        overflow: 'hidden',
        isolation: 'isolate',
        zIndex: 120,
        direction: 'rtl',
        ...menuAnchorStyle,
      },
    },
      h('div', { className: 'flex jc-sb ai-c', style: { marginBottom: 12 } },
        h('div', null,
          h('div', { style: { fontWeight: 800, fontSize: 15 } }, title),
          h('div', { style: { fontSize: 12, color: 'var(--text-secondary)' } }, subtitle),
        ),
        h('button', {
          className: 'icon-btn',
          title: 'إغلاق',
          onClick: () => onClose && onClose(),
        }, h(Icons.X, { size: 14 })),
      ),
      h('div', {
        style: {
          display: 'grid',
          gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
          gap: 8,
          marginBottom: 12,
        },
      },
        presets.map(([value, label]) => h('button', {
          key: value,
          className: 'btn ' + (activePreset === value ? 'primary' : 'outline'),
          style: { minHeight: 32, padding: '6px 8px', fontSize: 12, justifyContent: 'center' },
          onClick: () => onPresetSelect && onPresetSelect(value),
        }, label)),
      ),
      h('div', {
        style: {
          display: 'grid',
          gridTemplateColumns: '1fr 1fr',
          gap: 10,
          marginBottom: 12,
        },
      },
        h('div', null,
          h('div', { className: 'label', style: { marginBottom: 6 } }, 'من تاريخ'),
          h('input', {
            className: 'input',
            type: 'date',
            value: dateFrom,
            max: dateTo || undefined,
            onChange: e => onFromChange && onFromChange(e.target.value),
          }),
        ),
        h('div', null,
          h('div', { className: 'label', style: { marginBottom: 6 } }, 'إلى تاريخ'),
          h('input', {
            className: 'input',
            type: 'date',
            value: dateTo,
            min: dateFrom || undefined,
            onChange: e => onToChange && onToChange(e.target.value),
          }),
        ),
      ),
      h('div', { className: 'flex jc-sb ai-c', style: { gap: 10, flexWrap: 'wrap' } },
        h('div', {
          style: {
            fontSize: 12,
            color: 'var(--text-secondary)',
            background: 'var(--bg-subtle)',
            borderRadius: 999,
            padding: '8px 12px',
          },
        }, selectedRangeLabel),
        h('div', { className: 'flex gap-8' },
          h('button', {
            className: 'btn outline',
            disabled: !dateFrom && !dateTo,
            onClick: () => onClear && onClear(),
          }, 'مسح الفترة'),
          h('button', {
            className: 'btn primary',
            onClick: () => onApply && onApply(),
          }, 'تطبيق'),
        ),
      ),
    ) : null,
  );
}

window.DEFAULT_DATE_RANGE_PRESETS = DEFAULT_DATE_RANGE_PRESETS;
window.toDateKey = dateKeyFromDate;
window.parseDateKey = parseDateKey;
window.getCurrentClinicDateKey = getCurrentClinicDateKey;
window.resolveDateRangePreset = resolveDateRangePreset;
window.getDateRangeLabel = getDateRangeLabel;

const DEFAULT_CLINIC_TIME_ZONE = 'Africa/Cairo';

const getClinicNow = () => new Date();

const formatClinicClock = (dateValue = getClinicNow(), timeZone = getConfiguredClinicTimeZone()) => {
  try {
    return new Intl.DateTimeFormat('en-US', {
      ...(timeZone ? { timeZone } : {}),
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: true,
    }).format(dateValue);
  } catch {
    return new Date(dateValue).toLocaleTimeString('ar-EG');
  }
};

const formatClinicDate = (dateValue = getClinicNow(), timeZone = getConfiguredClinicTimeZone()) => {
  try {
    return new Intl.DateTimeFormat('ar-EG-u-nu-latn', {
      ...(timeZone ? { timeZone } : {}),
      weekday: 'short',
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
    }).format(dateValue);
  } catch {
    return window.fmtDate ? window.fmtDate(dateValue) : String(dateValue || '');
  }
};

window.DEFAULT_CLINIC_TIME_ZONE = DEFAULT_CLINIC_TIME_ZONE;
window.getConfiguredClinicTimeZone = getConfiguredClinicTimeZone;
window.getClinicNow = getClinicNow;
window.formatClinicClock = formatClinicClock;
window.formatClinicDate = formatClinicDate;
window.EGYPT_TIME_ZONE = DEFAULT_CLINIC_TIME_ZONE;
window.getEgyptNow = getClinicNow;
window.formatEgyptClock = formatClinicClock;
window.formatEgyptDate = formatClinicDate;

const ACCESS_SCREEN_LABELS = [
  ['dashboard', 'لوحة التحكم'],
  ['reception', 'الاستقبال'],
  ['appointments', 'المواعيد'],
  ['new-appointment', 'حجز موعد'],
  ['sessions', 'الجلسات'],
  ['patients', 'المرضى'],
  ['patient-file', 'ملف المريض'],
  ['billing', 'الفواتير'],
  ['new-invoice', 'فاتورة جديدة'],
  ['accounting', 'المحاسبة'],
  ['pricing', 'التسعير والربحية'],
  ['inventory', 'المخزون والخدمات'],
  ['reports', 'التقارير'],
  ['staff', 'الموظفين'],
  ['whatsapp-reminders', 'تذكيرات واتساب'],
  ['lab-orders', 'الطلبات المخبرية'],
  ['settings', 'الإعدادات'],
];

const ACCESS_ROLE_PRESETS = {
  'إدارة': null,
  'مدير': null,
  admin: null,
  owner: null,
  'استقبال': ['reception', 'appointments', 'new-appointment'],
  'طبيب': ['reception', 'sessions', 'patients', 'patient-file', 'dental-chart', 'prescriptions', 'xrays'],
  'تمريض': ['reception', 'sessions', 'patients', 'patient-file'],
  'مساعد طبيب': ['reception', 'sessions', 'patients', 'patient-file'],
  'محاسبة': ['billing', 'new-invoice', 'accounting', 'reports'],
  'مخزون': ['inventory', 'pricing', 'reports'],
  'تعقيم': ['inventory'],
};

const normalizeAccessRole = (role) => {
  const clean = String(role || '').trim();
  if (!clean) return 'استقبال';
  if (['admin', 'owner', 'manager', 'مدير', 'إداري', 'ادارة', 'إدارة'].includes(clean)) return 'إدارة';
  if (['doctor', 'دكتور', 'طبيب'].includes(clean)) return 'طبيب';
  if (['reception', 'receptionist', 'استقبال'].includes(clean)) return 'استقبال';
  if (['accounting', 'accountant', 'محاسب', 'محاسبة'].includes(clean)) return 'محاسبة';
  if (['inventory', 'stock', 'مخزون'].includes(clean)) return 'مخزون';
  return clean;
};

const getAccessScreensForRole = (role, allowedScreens) => {
  const normalized = normalizeAccessRole(role);
  if (normalized === 'أخرى') {
    const custom = Array.isArray(allowedScreens) ? allowedScreens.filter(Boolean) : [];
    return custom.length ? custom : ['dashboard'];
  }
  return Object.prototype.hasOwnProperty.call(ACCESS_ROLE_PRESETS, normalized)
    ? ACCESS_ROLE_PRESETS[normalized]
    : ['dashboard'];
};

const getUserAccessProfile = ({ user, staff = [], doctors = [] } = {}) => {
  const email = String(user?.email || '').trim().toLowerCase();
  const staffMatch = email ? (staff || []).find(s => String(s.email || '').trim().toLowerCase() === email) : null;
  const doctorMatch = email ? (doctors || []).find(d => String(d.email || '').trim().toLowerCase() === email) : null;
  const member = staffMatch || doctorMatch;
  if (!member) return { role: 'إدارة', label: 'إدارة', screens: null, memberType: 'owner' };
  const role = normalizeAccessRole(member.access_role || member.accessRole || member.role || (doctorMatch ? 'طبيب' : 'استقبال'));
  return {
    role,
    label: role,
    screens: getAccessScreensForRole(role, member.allowed_screens || member.allowedScreens),
    member,
    memberType: staffMatch ? 'staff' : 'doctor',
  };
};

window.SENAN_ACCESS_SCREEN_LABELS = ACCESS_SCREEN_LABELS;
window.SENAN_ACCESS_ROLE_PRESETS = ACCESS_ROLE_PRESETS;
window.normalizeAccessRole = normalizeAccessRole;
window.getAccessScreensForRole = getAccessScreensForRole;
window.getUserAccessProfile = getUserAccessProfile;

// ==================== Sidebar ====================
function Sidebar() {
  const { currentScreen, setScreen, unreadMessages, setLoggedIn, user, clinicName, appointments, sessions, canAccessScreen } = useContext(AppContext);
  const todayStr = getCurrentClinicDateKey();
  const appointmentCount = (Array.isArray(appointments) ? appointments : (window.APPOINTMENTS || []))
    .filter(a => a && a.date === todayStr)
    .length;
  const sessionCount = (Array.isArray(sessions) ? sessions : (window.SESSIONS || []))
    .filter(s => s && s.date === todayStr)
    .length;

  // Priority 1: Daily core operations
  const coreNav = [
    { id: 'dashboard',           label: 'لوحة التحكم',        icon: Icons.Home },
    { id: 'reception',           label: 'الاستقبال',           icon: Icons.Zap, badge: appointmentCount },
    { id: 'sessions',            label: 'الجلسات',             icon: Icons.FileText, badge: sessionCount },
    { id: 'patients',            label: 'المرضى',              icon: Icons.Users },
    { id: 'billing',             label: 'الفواتير والمدفوعات', icon: Icons.CreditCard },
    { id: 'whatsapp-reminders',  label: 'تذكيرات واتساب',     icon: Icons.MessageCircle },
    { id: 'lab-orders',          label: 'الطلبات المخبرية',   icon: Icons.Package },
  ];

  const SHOW_INSURANCE_SECTION = false;

  // Priority 2: Financial control
  const financeNav = [
    { id: 'accounting', label: 'المحاسبة', icon: Icons.Calculator },
    { id: 'pricing', label: 'التسعير والربحية', icon: Icons.TrendingUp },
    { id: 'inventory', label: 'المخزون والخدمات', icon: Icons.Package },
    { id: 'insurance', label: 'التأمين الطبي', icon: Icons.Shield },
  ];

  // Priority 3: System & analytics
  const systemNav = [
    { id: 'reports', label: 'التقارير', icon: Icons.BarChart },
    { id: 'staff', label: 'الموظفين', icon: Icons.Briefcase },
    { id: 'settings', label: 'الإعدادات', icon: Icons.Settings },
  ];

  const allowed = (items) => items.filter(item => !canAccessScreen || canAccessScreen(item.id));

  const renderItem = (item) => h('button', {
    key: item.id,
    className: 'nav-item' + (currentScreen === item.id ? ' active' : ''),
    onClick: () => setScreen(item.id),
  },
    h('span', { className: 'icon-box' }, h(item.icon, { size: 18 })),
    h('span', null, item.label),
    item.badge ? h('span', { className: 'badge-count' }, item.badge) : null,
  );

  return h('aside', { className: 'sidebar' },
    h('div', { className: 'sidebar-logo' },
      h('a', { href: '/', className: 'logo-wrap', 'aria-label': 'Modirify Home' },
        h('img', { src: '/assets/modirify-logo.png', alt: 'Modirify Logo' }),
      ),
    ),
    h('div', { className: 'sidebar-group-label' }, 'العمليات اليومية'),
    h('nav', { className: 'nav-items' }, allowed(coreNav).map(renderItem)),
    h('div', { className: 'sidebar-group-label' }, 'الإدارة المالية'),
    h('nav', { className: 'nav-items' }, allowed(financeNav.filter(item => SHOW_INSURANCE_SECTION || item.id !== 'insurance')).map(renderItem)),
    h('div', { className: 'sidebar-group-label' }, 'النظام والتحليل'),
    h('nav', { className: 'nav-items' }, allowed(systemNav).map(renderItem)),
    h('div', { style: { flex: '0 0 auto' } }),
    h('div', { className: 'sidebar-footer' },
      h('div', { className: 'avatar' }, (() => { const n = (clinicName || 'عيادة').replace(/Modirify|سِنان|كلينيك/gi,'').trim(); const w = n.split(' ').filter(Boolean); return w.length >= 2 ? w[0][0] + w[1][0] : n.substring(0,2) || 'مد'; })()),
      h('div', { style: { flex: 1, minWidth: 0 } },
        h('div', { style: { fontSize: 13, fontWeight: 700, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, clinicName || 'عيادتي'),
        h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, user?.email || ''),
      ),
      h('button', {
        className: 'icon-btn',
        title: 'تسجيل الخروج',
        style: { width: 32, height: 32 },
        onClick: () => { if (confirm('هل تريد تسجيل الخروج؟')) setLoggedIn(false); },
      },
        h(Icons.LogOut, { size: 16 }),
      ),
    ),
  );
}

// ==================== Theme Picker ====================
const ALL_THEMES = [
  { key: 'clean',    label: 'طبي',      color: '#0891b2' },
  { key: 'luxe',     label: 'فاخر',     color: '#d4af6f' },
  { key: 'warm',     label: 'دافئ',     color: '#c2675b' },
  { key: 'sage',     label: 'زيتوني',   color: '#4a7c59' },
  { key: 'ocean',    label: 'أوشن',     color: '#0070cc' },
  { key: 'blush',    label: 'وردي',     color: '#d4547a' },
  { key: 'midnight', label: 'منتصف الليل', color: '#e84545' },
  { key: 'desert',   label: 'صحراوي',   color: '#c47c2a' },
  { key: 'violet',   label: 'بنفسجي',   color: '#7c3aed' },
];

function ThemePicker({ onClose }) {
  const { theme, setTheme } = useContext(AppContext);
  return h(Fragment, null,
    h('div', { style: { position: 'fixed', inset: 0, zIndex: 299 }, onClick: onClose }),
    h('div', { className: 'theme-picker-drop scale-in' },
      h('div', { className: 'tpd-title' }, 'اختر المظهر'),
      h('div', { className: 'tpd-grid' },
        ALL_THEMES.map(t => h('div', {
          key: t.key,
          className: 'tpd-item' + (theme === t.key ? ' active' : ''),
          onClick: () => { setTheme(t.key); onClose(); },
        },
          h('div', { className: 'tpd-swatch', style: { background: t.color } }),
          h('div', { className: 'tpd-label' }, t.label),
        )),
      ),
    ),
  );
}

// ==================== Topbar ====================
function Topbar({ title, subtitle, actions }) {
  const {
    dataLoading, setScreen, clinicTimezone, canAccessScreen,
    patients, appointments, invoices, inventory, services, doctors,
    currentScreen,
  } = useContext(AppContext);
  const [showNotifs, setShowNotifs] = useState(false);
  const [showThemes, setShowThemes] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [searchOpen, setSearchOpen] = useState(false);
  const [now, setNow] = useState(() => getClinicNow());

  useEffect(() => {
    const timer = setInterval(() => setNow(getClinicNow()), 1000);
    return () => clearInterval(timer);
  }, []);

  const normalize = (value) => String(value || '').toLowerCase().trim();
  const allPatients = Array.isArray(patients) ? patients : (window.PATIENTS || []);
  const allAppointments = Array.isArray(appointments) ? appointments : (window.APPOINTMENTS || []);
  const allInvoices = Array.isArray(invoices) ? invoices : (window.INVOICES || []);
  const allInventory = Array.isArray(inventory) ? inventory : (window.INVENTORY || []);
  const allServices = Array.isArray(services) ? services : (window.TREATMENT_TYPES || []);
  const allDoctors = Array.isArray(doctors) ? doctors : (window.DOCTORS || []);

  const searchResults = useMemo(() => {
    const q = normalize(searchQuery);
    if (!q) return [];
    const contains = (...parts) => normalize(parts.filter(Boolean).join(' ')).includes(q);
    const rows = [];

    allPatients.forEach(p => {
      if (contains(p.name, p.phone, p.id)) {
        rows.push({ key: `patient-${p.id}`, type: 'مريض', title: p.name || 'مريض بدون اسم', meta: p.phone || p.id || '', icon: Icons.User, screen: 'patient-file', params: { patientId: p.id } });
      }
    });

    allInvoices.forEach(inv => {
      const invoiceCode = typeof inv.id === 'string' && inv.id.startsWith('INV') ? inv.id : `INV-${String(inv.id || '').slice(-6)}`;
      if (contains(invoiceCode, inv.patient, inv.doctorName, inv.status, inv.total)) {
        rows.push({ key: `invoice-${inv.id}`, type: 'فاتورة', title: invoiceCode, meta: `${inv.patient || 'بدون مريض'} · ${window.fmtEGP ? window.fmtEGP(inv.total) : inv.total}`, icon: Icons.CreditCard, screen: 'billing' });
      }
    });

    allAppointments.forEach(appt => {
      if (contains(appt.patient, appt.doctor, appt.date, appt.time, appt.type, appt.room)) {
        rows.push({ key: `appointment-${appt.id}`, type: 'موعد', title: appt.patient || 'موعد', meta: `${appt.date || ''} ${appt.time || ''} · ${appt.doctor || ''}`, icon: Icons.Calendar, screen: 'appointments' });
      }
    });

    allInventory.forEach(item => {
      if (contains(item.name, item.category, item.unit, item.supplier)) {
        rows.push({ key: `inventory-${item.id}`, type: 'مخزون', title: item.name || 'صنف', meta: `${item.category || 'عام'} · ${window.fmtNum ? window.fmtNum(item.stock) : item.stock} ${item.unit || ''}`, icon: Icons.Package, screen: 'inventory' });
      }
    });

    allServices.forEach(service => {
      if (contains(service.name, service.category, service.price)) {
        rows.push({ key: `service-${service.id}`, type: 'خدمة', title: service.name || 'خدمة', meta: `${service.category || 'عام'} · ${window.fmtEGP ? window.fmtEGP(service.price) : service.price}`, icon: Icons.TrendingUp, screen: 'pricing' });
      }
    });

    allDoctors.forEach(doctor => {
      if (contains(doctor.name, doctor.specialty, doctor.status)) {
        rows.push({ key: `doctor-${doctor.id}`, type: 'طبيب', title: doctor.name || 'طبيب', meta: doctor.specialty || doctor.status || '', icon: Icons.Stethoscope, screen: 'staff' });
      }
    });

    return rows.filter(row => !canAccessScreen || canAccessScreen(row.screen)).slice(0, 9);
  }, [searchQuery, allPatients, allAppointments, allInvoices, allInventory, allServices, allDoctors, canAccessScreen]);

  const openSearchResult = (result) => {
    if (!result) return;
    setScreen(result.screen, result.params || {});
    setSearchQuery('');
    setSearchOpen(false);
  };

  return h('header', { className: 'topbar' },
    h('div', null,
      h('div', { style: { fontWeight: 800, fontSize: 18, color: 'var(--text-primary)', display: 'flex', alignItems: 'center', gap: 8 } },
        title,
        dataLoading ? h('div', { style: { width: 14, height: 14, border: '2px solid var(--border)', borderTopColor: 'var(--accent)', borderRadius: '50%', animation: 'spin 0.8s linear infinite', flexShrink: 0 } }) : null,
      ),
      subtitle ? h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 } }, subtitle) : null,
    ),
    h('div', { className: 'search' },
      h('input', {
        placeholder: 'بحث عن مريض، موعد، فاتورة، صنف، خدمة...',
        type: 'text',
        value: searchQuery,
        onFocus: () => setSearchOpen(true),
        onChange: (e) => {
          setSearchQuery(e.target.value);
          setSearchOpen(true);
        },
        onKeyDown: (e) => {
          if (e.key === 'Enter') openSearchResult(searchResults[0]);
          if (e.key === 'Escape') setSearchOpen(false);
        },
      }),
      h('span', { className: 'search-icon' }, h(Icons.Search, { size: 16 })),
      searchOpen && searchQuery.trim() ? h(Fragment, null,
        h('div', { style: { position: 'fixed', inset: 0, zIndex: 180 }, onClick: () => setSearchOpen(false) }),
        h('div', {
          className: 'card scale-in',
          style: {
            position: 'absolute',
            top: 'calc(100% + 8px)',
            left: 0,
            right: 0,
            zIndex: 220,
            padding: 6,
            boxShadow: 'var(--shadow-lg)',
            overflow: 'hidden',
          },
        },
          searchResults.length ? searchResults.map(result => h('button', {
            key: result.key,
            type: 'button',
            onMouseDown: (e) => e.preventDefault(),
            onClick: () => openSearchResult(result),
            style: {
              width: '100%',
              border: 0,
              background: 'transparent',
              padding: '10px 12px',
              borderRadius: 12,
              display: 'flex',
              alignItems: 'center',
              gap: 10,
              textAlign: 'right',
              cursor: 'pointer',
              color: 'var(--text-primary)',
            },
          },
            h('span', { className: 'avatar xs' }, h(result.icon, { size: 13 })),
            h('span', { style: { flex: 1, minWidth: 0 } },
              h('span', { style: { display: 'block', fontSize: 13, fontWeight: 800, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, result.title),
              h('span', { style: { display: 'block', fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, result.meta || result.type),
            ),
            h('span', { className: 'chip', style: { fontSize: 10 } }, result.type),
          )) : h('div', { style: { padding: 14, color: 'var(--text-tertiary)', fontSize: 13, textAlign: 'center' } }, 'لا توجد نتائج مطابقة'),
        ),
      ) : null,
    ),
    h('div', { className: 'topbar-actions' },
      actions || null,
      h('div', {
        title: clinicTimezone === 'local' ? 'توقيت الجهاز' : 'توقيت العيادة',
        style: {
          display: 'grid',
          minWidth: 132,
          padding: '7px 12px',
          border: '1px solid var(--border)',
          borderRadius: 14,
          background: 'var(--bg-subtle)',
          textAlign: 'center',
          lineHeight: 1,
        },
      },
        h('div', {
          style: {
            fontSize: 18,
            fontWeight: 900,
            color: 'var(--text-primary)',
            fontVariantNumeric: 'tabular-nums',
            letterSpacing: '.01em',
            direction: 'ltr',
          },
        }, formatClinicClock(now, clinicTimezone === 'local' ? undefined : clinicTimezone)),
      ),
      // Technical support (WhatsApp)
      h('a', {
        href: 'https://wa.me/201020142568',
        target: '_blank',
        rel: 'noopener',
        title: 'الدعم الفني — واتساب',
        style: {
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          width: 34, height: 34,
          borderRadius: '50%',
          background: '#25d366',
          color: '#fff',
          textDecoration: 'none',
          flexShrink: 0,
        },
      }, h(Icons.MessageCircle, { size: 16 })),
      h('div', { style: { position: 'relative' } },
        h('button', {
          className: 'icon-btn',
          title: 'تغيير المظهر',
          onClick: () => setShowThemes(!showThemes),
        }, h(Icons.Palette, { size: 18 })),
        showThemes ? h(ThemePicker, { onClose: () => setShowThemes(false) }) : null,
      ),
      h('div', { style: { position: 'relative' } },
        h('button', {
          className: 'icon-btn',
          onClick: () => setShowNotifs(!showNotifs),
        },
          h(Icons.Bell, { size: 18 }),
          h('span', { className: 'pulse-dot' }),
        ),
        showNotifs ? h(NotificationsDropdown, { onClose: () => setShowNotifs(false) }) : null,
      ),
      h('div', { style: { width: 1, height: 24, background: 'var(--border)', margin: '0 4px' } }),
      h('div', { className: 'avatar sm' }, 'مد'),
    ),
  );
}

function NotificationsDropdown({ onClose }) {
  const { setScreen, inventory, invoices, appointments, patients } = useContext(AppContext);

  const notifs = useMemo(() => {
    const list = [];
    const today = getCurrentClinicDateKey();

    // Low stock
    const allInv = Array.isArray(inventory) ? inventory : (window.INVENTORY || []);
    allInv.filter(i => i.stock != null && i.minStock != null && i.stock < i.minStock)
      .slice(0, 5)
      .forEach(i => list.push({
        id: 'inv-' + i.id, type: 'warning',
        text: `مخزون منخفض: ${i.name} (${i.stock} ${i.unit || ''} متبقي)`,
        time: 'المخزون',
        screen: 'inventory',
      }));

    // Unpaid invoices with debt > 0
    const allInv2 = Array.isArray(invoices) ? invoices : (window.INVOICES || []);
    const highDebt = allInv2
      .filter(i => (i.total||0) > (i.paid||0) && ((i.total||0)-(i.paid||0)) > 100)
      .sort((a,b) => ((b.total||0)-(b.paid||0)) - ((a.total||0)-(a.paid||0)))
      .slice(0, 4);
    highDebt.forEach(i => list.push({
      id: 'inv-debt-' + i.id, type: 'warning',
      text: `مديونية: ${i.patient||'مريض'} — ${window.fmtEGP ? window.fmtEGP((i.total||0)-(i.paid||0)) : ((i.total||0)-(i.paid||0))+' ج.م'}`,
      time: 'الفواتير',
      screen: 'billing',
    }));

    // Today's appointments
    const allAppts = Array.isArray(appointments) ? appointments : (window.APPOINTMENTS || []);
    const todayAppts = allAppts.filter(a => a.date === today && a.status !== 'cancelled');
    if (todayAppts.length > 0) list.unshift({
      id: 'appts-today', type: 'info',
      text: `${todayAppts.length} موعد اليوم (${todayAppts.filter(a=>a.status==='done').length} مكتمل)`,
      time: 'اليوم',
      screen: 'appointments',
    });

    // New patients this week
    const allPts = Array.isArray(patients) ? patients : (window.PATIENTS || []);
    const weekAgo = new Date(); weekAgo.setDate(weekAgo.getDate()-7);
    const weekAgoStr = weekAgo.toISOString().slice(0,10);
    const newPts = allPts.filter(p => (p.created_at||'').slice(0,10) >= weekAgoStr).length;
    if (newPts > 0) list.unshift({
      id: 'new-pts', type: 'success',
      text: `${newPts} مريض جديد هذا الأسبوع`,
      time: 'هذا الأسبوع',
      screen: 'patients',
    });

    return list.slice(0, 10);
  }, [inventory, invoices, appointments, patients]);

  const icons = { warning: Icons.AlertTriangle, success: Icons.Check, info: Icons.Info };

  return h(Fragment, null,
    h('div', { style: { position: 'fixed', inset: 0, zIndex: 40 }, onClick: onClose }),
    h('div', {
      className: 'card scale-in',
      style: {
        position: 'fixed', top: 60, insetInlineEnd: 60,
        width: 340, zIndex: 200, boxShadow: 'var(--shadow-lg)', padding: 0, overflow: 'hidden',
      },
    },
      h('div', { style: { padding: '14px 16px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' } },
        h('div', { style: { fontWeight: 800, fontSize: 14 } }, 'الإشعارات'),
        notifs.length > 0 && h('span', { className: 'chip accent' }, notifs.length + ' إشعار'),
      ),
      h('div', { style: { maxHeight: 380, overflowY: 'auto' } },
        notifs.length === 0
          ? h('div', { style: { padding: '28px 16px', textAlign: 'center', color: 'var(--text-tertiary)', fontSize: 13 } }, '✅ لا توجد إشعارات')
          : notifs.map(n => h('div', {
              key: n.id,
              onClick: () => { if (n.screen) { setScreen(n.screen); onClose(); } },
              style: {
                padding: '11px 16px', borderBottom: '1px solid var(--border)',
                display: 'flex', gap: 10, alignItems: 'flex-start',
                cursor: n.screen ? 'pointer' : 'default',
                transition: 'background 0.12s',
              },
              onMouseEnter: (e) => { if (n.screen) e.currentTarget.style.background = 'var(--bg-subtle)'; },
              onMouseLeave: (e) => { e.currentTarget.style.background = ''; },
            },
            h('div', {
              style: {
                width: 30, height: 30, borderRadius: 8, display: 'grid', placeItems: 'center', flexShrink: 0,
                background: `var(--${n.type}-soft)`, color: `var(--${n.type})`,
              },
            }, h(icons[n.type] || Icons.Info, { size: 15 })),
            h('div', { style: { flex: 1, minWidth: 0 } },
              h('div', { style: { fontSize: 12, color: 'var(--text-primary)', fontWeight: 500, lineHeight: 1.4 } }, n.text),
              h('div', { style: { fontSize: 10, color: 'var(--text-tertiary)', marginTop: 2 } }, n.time),
            ),
          )),
      ),
    ),
  );
}

// ==================== Toast ====================
function Toast({ message, onDone }) {
  useEffect(() => {
    if (!message) return;
    const t = setTimeout(onDone, 2800);
    return () => clearTimeout(t);
  }, [message]);
  if (!message) return null;
  return h('div', { className: 'toast success' },
    h('div', { className: 'toast-icon' }, h(Icons.Check, { size: 16 })),
    h('div', null, message),
  );
}

// ==================== Modal ====================
function Modal({ open, onClose, title, children, footer, size = 'md' }) {
  useEffect(() => {
    if (!open) return;
    const onEsc = (e) => e.key === 'Escape' && onClose && onClose();
    window.addEventListener('keydown', onEsc);
    return () => window.removeEventListener('keydown', onEsc);
  }, [open, onClose]);
  if (!open) return null;
  return h('div', { className: 'modal-backdrop', onClick: onClose },
    h('div', {
      className: 'modal ' + (size === 'lg' ? 'lg' : size === 'xl' ? 'xl' : ''),
      onClick: (e) => e.stopPropagation(),
    },
      h('div', { className: 'modal-header' },
        h('div', { className: 'modal-title' }, title),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 18 })),
      ),
      h('div', { className: 'modal-body' }, children),
      footer ? h('div', { className: 'modal-footer' }, footer) : null,
    ),
  );
}

// ==================== Tweaks Panel ====================
function TweaksPanel() {
  const { theme, setTheme, density, setDensity, clinicName, setClinicName, showTweaks, toggleTweaks } = useContext(AppContext);
  if (!showTweaks) return null;

  return h('div', { className: 'tweaks-panel' },
    h('h4', null,
      h('span', null, '⚙  إعدادات التخصيص'),
      h('button', { className: 'icon-btn', style: { width: 26, height: 26 }, onClick: toggleTweaks },
        h(Icons.X, { size: 14 }),
      ),
    ),
    h('div', { className: 'tweak-row' },
      h('span', { className: 'label-txt' }, 'الكثافة'),
      h('div', { style: { display: 'flex', gap: 4 } },
        ['مدمجة', 'مريحة'].map((d, i) => h('button', {
          key: d,
          className: 'btn sm ' + (density === (i === 0 ? 'compact' : 'comfortable') ? 'primary' : 'outline'),
          onClick: () => setDensity(i === 0 ? 'compact' : 'comfortable'),
        }, d)),
      ),
    ),
    h('div', { className: 'tweak-row', style: { flexDirection: 'column', alignItems: 'stretch', gap: 6 } },
      h('span', { className: 'label-txt' }, 'اسم العيادة'),
      h('input', {
        className: 'input',
        style: { padding: '6px 10px', fontSize: 12 },
        value: clinicName,
        onChange: (e) => setClinicName(e.target.value),
      }),
    ),
  );
}

window.Shell = { Sidebar, Topbar, Toast, Modal, TweaksPanel, DateRangeFilter, escapeHtml, openPrintWindow };
