/* global React, Icons, AppContext */
const { useState, useEffect, useContext, 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 getCurrentClinicDateKey = () => {
  try {
    return new Intl.DateTimeFormat('en-CA', { timeZone: 'Africa/Cairo' }).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;

// ==================== Sidebar ====================
function Sidebar() {
  const { currentScreen, setScreen, unreadMessages, setLoggedIn, user, clinicName, appointments, sessions } = useContext(AppContext);
  const todayStr = new Intl.DateTimeFormat('en-CA', { timeZone: 'Africa/Cairo' }).format(new Date());
  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: 'today-clinic', label: 'العيادة اليوم', icon: Icons.Clock, badge: appointmentCount },
    { id: 'dashboard', label: 'لوحة التحكم', icon: Icons.Home },
    { id: 'appointments', label: 'المواعيد', icon: Icons.Calendar, badge: appointmentCount },
    { id: 'sessions', label: 'الجلسات', icon: Icons.FileText, badge: sessionCount },
    { id: 'patients', label: 'المرضى', icon: Icons.Users },
    { id: 'billing', label: 'الفواتير والمدفوعات', icon: Icons.CreditCard },
  ];

  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: 'messages', label: 'الدردشة الداخلية', icon: Icons.MessageCircle, badge: unreadMessages },
    { id: 'patient-portal', label: 'بوابة المريض', icon: Icons.User },
    { id: 'settings', label: 'الإعدادات', icon: Icons.Settings },
  ];

  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('div', { className: 'sidebar-logo-mark' }, h(Icons.Smile, { size: 22 })),
      h('div', null,
        h('div', { className: 'sidebar-logo-title' }, 'سِنان كلينيك'),
        h('div', { className: 'sidebar-logo-sub' }, 'إدارة عيادة متكاملة'),
      ),
    ),
    h('div', { className: 'sidebar-group-label' }, 'العمليات اليومية'),
    h('nav', { className: 'nav-items' }, coreNav.map(renderItem)),
    h('div', { className: 'sidebar-group-label' }, 'الإدارة المالية'),
    h('nav', { className: 'nav-items' }, financeNav.filter(item => SHOW_INSURANCE_SECTION || item.id !== 'insurance').map(renderItem)),
    h('div', { className: 'sidebar-group-label' }, 'النظام والتحليل'),
    h('nav', { className: 'nav-items' }, systemNav.map(renderItem)),
    h('div', { style: { flex: '0 0 auto' } }),
    h('div', { className: 'sidebar-footer' },
      h('div', { className: 'avatar' }, (() => { const n = (clinicName || 'عيادة').replace(/سِنان|كلينيك/g,'').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 }),
      ),
    ),
  );
}

// ==================== Topbar ====================
function Topbar({ title, subtitle, actions }) {
  const { setTheme, theme, dataLoading, setScreen, patients, appointments, invoices } = useContext(AppContext);
  const [showNotifs, setShowNotifs] = useState(false);
  const [showSearch, setShowSearch] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const query = String(searchQuery || '').trim().toLowerCase();
  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 patientResults = React.useMemo(() => {
    if (!query) return [];
    return allPatients
      .filter((patient) => [patient.name, patient.phone, patient.email].some((value) => String(value || '').toLowerCase().includes(query)))
      .slice(0, 5);
  }, [allPatients, query]);

  const appointmentResults = React.useMemo(() => {
    if (!query) return [];
    return allAppointments
      .filter((appt) => [appt.patient, appt.doctor, appt.type, appt.date, appt.time].some((value) => String(value || '').toLowerCase().includes(query)))
      .slice(0, 5);
  }, [allAppointments, query]);

  const invoiceResults = React.useMemo(() => {
    if (!query) return [];
    return allInvoices
      .filter((invoice) => [invoice.patient, invoice.doctorName, invoice.date, invoice.id].some((value) => String(value || '').toLowerCase().includes(query)))
      .slice(0, 5);
  }, [allInvoices, query]);

  const totalSearchResults = patientResults.length + appointmentResults.length + invoiceResults.length;

  const openSearchResult = (kind, row) => {
    setShowSearch(false);
    setSearchQuery('');
    if (kind === 'patient') {
      setScreen('patient-file', { patientId: row.id });
      return;
    }
    if (kind === 'appointment') {
      if (row.patientId) setScreen('patient-file', { patientId: row.patientId });
      else setScreen('appointments');
      return;
    }
    setScreen('billing', { invoiceId: row.id });
  };

  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', style: { position: 'relative' } },
      h('input', {
        placeholder: 'ابحث عن مريض، موعد، فاتورة...',
        type: 'text',
        value: searchQuery,
        onFocus: () => setShowSearch(true),
        onChange: (e) => {
          setSearchQuery(e.target.value);
          setShowSearch(true);
        },
        onKeyDown: (e) => {
          if (e.key === 'Escape') {
            setShowSearch(false);
            e.currentTarget.blur();
          }
        },
      }),
      h('span', { className: 'search-icon' }, h(Icons.Search, { size: 16 })),
      showSearch ? h(GlobalSearchDropdown, {
        query: searchQuery,
        patientResults,
        appointmentResults,
        invoiceResults,
        totalSearchResults,
        onClose: () => setShowSearch(false),
        onOpenResult: openSearchResult,
      }) : null,
    ),
    h('div', { className: 'topbar-actions' },
      actions || null,
      h('button', {
        className: 'icon-btn',
        title: 'تبديل الوضع',
        onClick: () => setTheme(theme === 'luxe' ? 'clean' : 'luxe'),
      }, h(theme === 'luxe' ? Icons.Sun : Icons.Moon, { size: 18 })),
      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('button', { className: 'icon-btn', title: 'الدردشة الداخلية', onClick: () => setScreen('messages') }, h(Icons.MessageCircle, { size: 18 })),
      h('div', { style: { width: 1, height: 24, background: 'var(--border)', margin: '0 4px' } }),
      h('div', { className: 'avatar sm' }, 'مد'),
    ),
  );
}

function GlobalSearchDropdown({
  query,
  patientResults,
  appointmentResults,
  invoiceResults,
  totalSearchResults,
  onClose,
  onOpenResult,
}) {
  const hasQuery = String(query || '').trim().length > 0;
  const renderResult = (kind, row, primary, secondary) => h('button', {
    key: `${kind}-${row.id}`,
    type: 'button',
    onClick: () => onOpenResult(kind, row),
    style: {
      width: '100%',
      display: 'flex',
      flexDirection: 'column',
      gap: 2,
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      textAlign: 'right',
      padding: '10px 12px',
      borderRadius: 10,
    },
    onMouseEnter: (e) => { e.currentTarget.style.background = 'var(--bg-hover)'; },
    onMouseLeave: (e) => { e.currentTarget.style.background = 'transparent'; },
  },
    h('div', { style: { fontSize: 13, fontWeight: 700, color: 'var(--text-primary)' } }, primary),
    h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, secondary),
  );

  const Section = ({ title: sectionTitle, rows, kind, getPrimary, getSecondary }) => {
    if (!rows.length) return null;
    return h('div', { style: { padding: 10, borderBottom: '1px solid var(--border)' } },
      h('div', { style: { fontSize: 11, fontWeight: 800, color: 'var(--text-tertiary)', marginBottom: 6 } }, sectionTitle),
      rows.map((row) => renderResult(kind, row, getPrimary(row), getSecondary(row))),
    );
  };

  return h(Fragment, null,
    h('div', { style: { position: 'fixed', inset: 0, zIndex: 80 }, onClick: onClose }),
    h('div', {
      className: 'card scale-in',
      style: {
        position: 'absolute',
        top: 'calc(100% + 10px)',
        left: 0,
        width: 'min(520px, 88vw)',
        zIndex: 120,
        padding: 0,
        overflow: 'hidden',
        boxShadow: 'var(--shadow-lg)',
      },
    },
      !hasQuery ? h('div', { style: { padding: 18, fontSize: 13, color: 'var(--text-tertiary)' } }, 'ابدأ الكتابة للبحث في المرضى والمواعيد والفواتير') :
      totalSearchResults === 0 ? h('div', { style: { padding: 18, fontSize: 13, color: 'var(--text-tertiary)' } }, 'لا توجد نتائج مطابقة') :
      h(Fragment, null,
        h('div', { style: { padding: '12px 14px', borderBottom: '1px solid var(--border)', fontSize: 12, color: 'var(--text-tertiary)' } }, `${totalSearchResults} نتيجة`),
        h(Section, {
          title: 'المرضى',
          rows: patientResults,
          kind: 'patient',
          getPrimary: (row) => row.name || 'مريض',
          getSecondary: (row) => [row.phone, row.doctor].filter(Boolean).join(' · ') || 'ملف المريض',
        }),
        h(Section, {
          title: 'المواعيد',
          rows: appointmentResults,
          kind: 'appointment',
          getPrimary: (row) => `${row.patient || 'موعد'} · ${row.time || ''}`.trim(),
          getSecondary: (row) => [row.date, row.doctor, row.type].filter(Boolean).join(' · '),
        }),
        h(Section, {
          title: 'الفواتير',
          rows: invoiceResults,
          kind: 'invoice',
          getPrimary: (row) => `${row.patient || 'فاتورة'} · ${typeof row.id === 'string' && row.id.startsWith('INV') ? row.id : `INV-${String(row.id || '').slice(-6)}`}`,
          getSecondary: (row) => [row.date, window.fmtEGP(row.total || 0), row.status].filter(Boolean).join(' · '),
        }),
      ),
    ),
  );
}

function NotificationsDropdown({ onClose }) {
  const { setScreen } = useContext(AppContext);
  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 } }, 'الإشعارات'),
        h('span', { className: 'chip accent' }, window.NOTIFICATIONS.length + ' جديد'),
      ),
      h('div', { style: { maxHeight: 360, overflowY: 'auto' } },
        window.NOTIFICATIONS.map(n => h('div', {
          key: n.id,
          style: { padding: '12px 16px', borderBottom: '1px solid var(--border)', display: 'flex', gap: 10, alignItems: 'flex-start', cursor: 'pointer' },
        },
          h('div', {
            style: {
              width: 32, height: 32, borderRadius: 8, display: 'grid', placeItems: 'center', flexShrink: 0,
              background: `var(--${n.type}-soft)`, color: `var(--${n.type})`,
            },
          },
            h(n.type === 'warning' ? Icons.AlertTriangle : n.type === 'success' ? Icons.Check : Icons.Info, { size: 16 }),
          ),
          h('div', { style: { flex: 1, minWidth: 0 } },
            h('div', { style: { fontSize: 13, color: 'var(--text-primary)', fontWeight: 500 } }, n.text),
            h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2 } }, n.time),
          ),
        )),
      ),
      h('div', { style: { padding: 10, textAlign: 'center' } },
        h('button', { className: 'btn ghost sm w-full', onClick: () => { setScreen('messages'); onClose(); } }, 'عرض الكل'),
      ),
    ),
  );
}

// ==================== 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', { className: 'theme-swatches' },
        ['clean', 'luxe', 'warm'].map(t => h('div', {
          key: t,
          className: 'theme-swatch' + (theme === t ? ' active' : ''),
          'data-preview': t,
          onClick: () => setTheme(t),
          title: t === 'clean' ? 'طبي نظيف' : t === 'luxe' ? 'فاخر داكن' : 'دافئ',
        })),
      ),
    ),
    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),
      }),
    ),
    h('div', { style: { fontSize: 10, color: 'var(--text-muted)', marginTop: 8, textAlign: 'center' } },
      'استخدم زر Tweaks في الشريط العلوي للإخفاء',
    ),
  );
}

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