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

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

const printableText = (value, fallback = '—') => {
  const normalized = String(value ?? '').trim();
  return escapePrintableHtml(normalized || fallback);
};

const printableMultiline = (value, fallback = '') => printableText(value, fallback).replace(/\r?\n/g, '<br/>');

const getClinicTodayKey = () => {
  try {
    if (typeof window.getCurrentClinicDateKey === 'function') {
      return window.getCurrentClinicDateKey();
    }
    return new Intl.DateTimeFormat('en-CA', { timeZone: 'Africa/Cairo' }).format(new Date());
  } catch {
    return new Date().toISOString().slice(0, 10);
  }
};

const openPrintableWindow = ({ title, bodyHtml, features }) => {
  if (typeof window.openPrintWindow === 'function') {
    return window.openPrintWindow({ title, bodyHtml, features });
  }
  return null;
};

const GLOBAL_XRAY_STORAGE_KEY = 'senan-global-xrays';

function makeGlobalPreviewDataUrl(title, subtitle) {
  const safeTitle = String(title || '').replace(/[<>&]/g, '');
  const safeSubtitle = String(subtitle || '').replace(/[<>&]/g, '');
  const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="900" viewBox="0 0 1200 900">
      <defs>
        <linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%">
          <stop offset="0%" stop-color="#0891b2" stop-opacity="0.2"/>
          <stop offset="100%" stop-color="#0f172a" stop-opacity="0.92"/>
        </linearGradient>
      </defs>
      <rect width="1200" height="900" rx="40" fill="url(#g)"/>
      <text x="600" y="350" text-anchor="middle" fill="#ffffff" font-size="78" font-family="Arial" font-weight="700">${safeTitle}</text>
      <text x="600" y="440" text-anchor="middle" fill="#dbeafe" font-size="40" font-family="Arial">${safeSubtitle}</text>
      <text x="600" y="580" text-anchor="middle" fill="#e2e8f0" font-size="32" font-family="Arial">SENAN CLINIC</text>
    </svg>`;
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
}

async function readFileAsDataUrl(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(String(reader.result || ''));
    reader.onerror = () => reject(reader.error || new Error('File read failed'));
    reader.readAsDataURL(file);
  });
}

async function compressImageDataUrl(dataUrl, maxSize = 1600, quality = 0.82) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      const scale = Math.min(1, maxSize / Math.max(img.width || maxSize, img.height || maxSize));
      const width = Math.max(1, Math.round((img.width || maxSize) * scale));
      const height = Math.max(1, Math.round((img.height || maxSize) * scale));
      const canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext('2d');
      if (!ctx) {
        resolve(dataUrl);
        return;
      }
      ctx.drawImage(img, 0, 0, width, height);
      try {
        resolve(canvas.toDataURL('image/jpeg', quality));
      } catch (error) {
        resolve(dataUrl);
      }
    };
    img.onerror = reject;
    img.src = dataUrl;
  });
}

async function fileToStoredDataUrl(file) {
  const dataUrl = await readFileAsDataUrl(file);
  return file.type.startsWith('image/') ? compressImageDataUrl(dataUrl) : dataUrl;
}

function loadGlobalXrays() {
  try {
    const raw = window.localStorage.getItem(GLOBAL_XRAY_STORAGE_KEY);
    if (raw) {
      const parsed = JSON.parse(raw);
      if (Array.isArray(parsed) && parsed.length) return parsed;
    }
  } catch (error) {
    console.warn('[Senan] failed to read global xrays:', error);
  }
  return [
    { id: 1, patient: 'أحمد محمد', date: '2026-04-10', type: 'بانوراما', label: 'فحص شامل', dataUrl: makeGlobalPreviewDataUrl('فحص شامل', 'بانوراما · 2026-04-10') },
    { id: 2, patient: 'فاطمة علي', date: '2026-04-15', type: 'ديجيتال', label: 'ضرس 36', dataUrl: makeGlobalPreviewDataUrl('ضرس 36', 'ديجيتال · 2026-04-15') },
    { id: 3, patient: 'محمد عبد الرحمن', date: '2026-04-12', type: 'بانوراما', label: 'قبل التقويم', dataUrl: makeGlobalPreviewDataUrl('قبل التقويم', 'بانوراما · 2026-04-12') },
    { id: 4, patient: 'نورهان إبراهيم', date: '2026-03-28', type: 'ديجيتال', label: 'قناة جذر 26', dataUrl: makeGlobalPreviewDataUrl('قناة جذر 26', 'ديجيتال · 2026-03-28') },
    { id: 5, patient: 'يوسف طارق', date: '2026-04-14', type: 'ديجيتال', label: 'لبنية', dataUrl: makeGlobalPreviewDataUrl('لبنية', 'ديجيتال · 2026-04-14') },
    { id: 6, patient: 'سلمى حسام', date: '2026-04-16', type: 'بانوراما', label: 'تركيب تاج', dataUrl: makeGlobalPreviewDataUrl('تركيب تاج', 'بانوراما · 2026-04-16') },
    { id: 7, patient: 'رنا أشرف', date: '2026-04-17', type: 'ديجيتال', label: 'تسوس أمامي', dataUrl: makeGlobalPreviewDataUrl('تسوس أمامي', 'ديجيتال · 2026-04-17') },
    { id: 8, patient: 'عمر شريف', date: '2026-02-20', type: 'بانوراما', label: 'فحص دوري', dataUrl: makeGlobalPreviewDataUrl('فحص دوري', 'بانوراما · 2026-02-20') },
  ];
}

function saveGlobalXrays(xrays) {
  try {
    window.localStorage.setItem(GLOBAL_XRAY_STORAGE_KEY, JSON.stringify(xrays));
  } catch (error) {
    console.warn('[Senan] failed to save global xrays:', error);
  }
}

function buildWhatsAppUrl(phone, message) {
  const digits = String(phone || '').replace(/\D/g, '');
  if (!digits) return '';
  return `https://wa.me/${digits}?text=${encodeURIComponent(message || '')}`;
}

function extractLegacyInventoryPackMeta(item) {
  const name = String(item?.name || '').trim();
  const match = name.match(/^(.*?)(?:\s*-\s*)(\d+(?:\.\d+)?)\s*حالة$/u);
  if (!match) return { cleanName: name, usageUnitsPerPack: 0 };
  return {
    cleanName: String(match[1] || '').trim() || name,
    usageUnitsPerPack: Math.max(0, Number(match[2]) || 0),
  };
}

function getInventoryUsageUnitsPerPack(item, usageUnitsMap = {}) {
  const mapped = Math.max(0, Number(usageUnitsMap?.[item?.id]) || 0);
  if (mapped > 0) return mapped;
  return extractLegacyInventoryPackMeta(item).usageUnitsPerPack;
}

function getInventoryDisplayName(item) {
  return extractLegacyInventoryPackMeta(item).cleanName;
}

function getInventoryActualUsageUnits(item, usageUnitsMap = {}) {
  const stockQty = Math.max(0, Number(item?.stock) || 0);
  const usageUnitsPerPack = getInventoryUsageUnitsPerPack(item, usageUnitsMap);
  return usageUnitsPerPack > 0 ? stockQty * usageUnitsPerPack : 0;
}

function getInventoryMeasureUnitPrice(item, usageUnitsMap = {}) {
  const packPrice = Math.max(0, Number(item?.price) || 0);
  const usageUnitsPerPack = getInventoryUsageUnitsPerPack(item, usageUnitsMap);
  return usageUnitsPerPack > 0 ? packPrice / usageUnitsPerPack : packPrice;
}

function loadInventoryUsageUnitsMap(clinicId) {
  try {
    const raw = window.localStorage.getItem(`senan-inventory-usage-units:${clinicId || 'default'}`);
    return raw ? JSON.parse(raw) : {};
  } catch (error) {
    console.warn('[Inventory Usage Units] failed to load map:', error);
    return {};
  }
}

// ==================== Quick Add Patient Modal ====================
function QuickAddPatientModal({ onClose, onSaved }) {
  const { toast, clinicId, setPatients, patients } = useContext(AppContext);
  const [form, setForm] = useState({ name: '', phone: '', gender: 'ذكر', age: '', location: '', email: '', notes: '' });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const knownLocations = useMemo(() => [...new Set(
    ((patients && patients.length) ? patients : (window.PATIENTS || []))
      .map(p => (p.location || '').trim())
      .filter(Boolean)
  )].sort(), [patients]);

  const handleSave = async () => {
    if (!form.name.trim()) { toast('الرجاء إدخال اسم المريض'); return; }
    setSaving(true);
    try {
      const newP = await DB.addPatient(clinicId, {
        name: form.name.trim(),
        phone: form.phone.trim() || null,
        gender: form.gender,
        age: parseInt(form.age) || null,
        location: form.location.trim() || null,
        email: form.email.trim() || null,
        notes: form.notes.trim() || null,
        balance: 0,
        status: 'active',
      });
      setPatients(prev => [newP, ...prev]);
      toast('تم إضافة المريض ✅');
      onSaved(newP);
      onClose();
    } catch(e) { console.error(e); toast('خطأ في الحفظ'); }
    finally { setSaving(false); }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.45)',zIndex:400 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:28,width:480,maxWidth:'calc(100vw - 24px)',zIndex:401,boxShadow:'var(--shadow-lg)' }, onClick: e => e.stopPropagation() },
      h('div', { style: { display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20 } },
        h('div', { style: { fontWeight:800,fontSize:16 } }, 'إضافة مريض جديد'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, { size:16 })),
      ),
      h('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr', gap:12 } },
        h('div', { style: { gridColumn: '1/-1' } },
          h('div', { className:'label' }, 'الاسم الكامل *'),
          h('input', { className:'input', placeholder:'اسم المريض', value:form.name, onChange:e=>set('name',e.target.value) }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'العمر'),
          h('input', { className:'input', type:'number', placeholder:'25', value:form.age, onChange:e=>set('age',e.target.value) }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'الجنس'),
          h('select', { className:'input', value:form.gender, onChange:e=>set('gender',e.target.value) },
            h('option', { value:'ذكر' }, 'ذكر'),
            h('option', { value:'أنثى' }, 'أنثى'),
          ),
        ),
        h('div', null,
          h('div', { className:'label' }, 'رقم الهاتف'),
          h('input', { className:'input', placeholder:'07XX XXX XXXX', value:form.phone, onChange:e=>set('phone',e.target.value), dir:'ltr' }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'المنطقة'),
          h('input', {
            className:'input',
            placeholder:'الرحمانية، دسوق...',
            value:form.location,
            onChange:e=>set('location',e.target.value),
            list:'quick-patient-locations',
          }),
          h('datalist', { id:'quick-patient-locations' }, knownLocations.map(loc => h('option', { key: loc, value: loc }))),
        ),
        h('div', null,
          h('div', { className:'label' }, 'البريد الإلكتروني'),
          h('input', { className:'input', type:'email', placeholder:'email@...', value:form.email, onChange:e=>set('email',e.target.value) }),
        ),
        h('div', { style: { gridColumn: '1/-1' } },
          h('div', { className:'label' }, 'ملاحظات'),
          h('textarea', { className:'textarea', rows:2, placeholder:'أي ملاحظات...', value:form.notes, onChange:e=>set('notes',e.target.value) }),
        ),
      ),
      h('div', { style: { display:'flex',gap:10 } },
        h('button', { className:'btn outline', style:{flex:1}, onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', style:{flex:2}, disabled:saving, onClick:handleSave }, saving ? 'جاري الحفظ...' : '✅ حفظ وتحديد المريض'),
      ),
    ),
  );
}

// ==================== New Appointment ====================
function NewAppointment() {
  const { setScreen, toast, clinicId, setAppointments, appointments, screenParams, patients, doctors, invoices } = useContext(AppContext);
  const allPatientsForAppt = (patients && patients.length) ? patients : (window.PATIENTS || []);
  const allDoctorsForAppt  = (doctors  && doctors.length)  ? doctors  : (window.DOCTORS  || []);
  const allAppointmentsForAppt = (appointments && appointments.length) ? appointments : (window.APPOINTMENTS || []);
  const allInvoicesForAppt = (invoices && invoices.length) ? invoices : (window.INVOICES || []);
  const [saving, setSaving] = useState(false);
  const [showQuickAdd, setShowQuickAdd] = useState(false);
  const today = new Date().toISOString().split('T')[0];
  const startHour = parseInt(localStorage.getItem('senan-start-hour') || '9', 10);
  const endHour = parseInt(localStorage.getItem('senan-end-hour') || '17', 10);
  const roomCount = parseInt(localStorage.getItem('senan-rooms') || '1', 10);
  // If coming from patient file, pre-fill patient and skip to step 2
  const initPatientId   = screenParams?.patientId   || null;
  const initPatientName = screenParams?.patientName || '';
  const [step, setStep] = useState(initPatientId ? 2 : 1);
  const [data, setData] = useState({ patient: initPatientName, patientId: initPatientId, doctor: '', doctorId: null, type: '', date: today, time: String(startHour).padStart(2, '0') + ':00', room: roomCount === 1 ? 'الغرفة' : 'غرفة 1', notes: '', reminder: true, duration: 30 });
  const steps = ['المريض', 'الحالة', 'الموعد', 'تأكيد'];
  const normalizeRoomKey = (roomName) => {
    const raw = String(roomName || '').trim();
    if (!raw) return roomCount === 1 ? 'room-1' : '';
    if (raw === 'الغرفة' || raw === 'غرفة 1') return 'room-1';
    const match = raw.match(/\d+/);
    return match ? 'room-' + match[0] : raw;
  };
  const availableRooms = useMemo(() => (
    Array.from({ length: Math.max(1, roomCount) }, (_, i) => roomCount === 1 ? 'الغرفة' : 'غرفة ' + (i + 1))
  ), [roomCount]);
  const availableTimeSlots = useMemo(() => {
    const slotMinutes = 30;
    const duration = Math.max(slotMinutes, parseInt(data.duration || 30, 10) || 30);
    const startMinutes = startHour * 60;
    const endMinutes = endHour * 60;
    const lastStart = Math.max(startMinutes, endMinutes - duration);
    const slots = [];

    for (let mins = startMinutes; mins <= lastStart; mins += slotMinutes) {
      const hours = String(Math.floor(mins / 60)).padStart(2, '0');
      const minutes = String(mins % 60).padStart(2, '0');
      slots.push(hours + ':' + minutes);
    }

    return slots.length ? slots : [String(startHour).padStart(2, '0') + ':00'];
  }, [data.duration, startHour, endHour]);
  const selectedRoomKey = normalizeRoomKey(data.room);
  const occupiedTimeSlots = useMemo(() => {
    return new Set(
      allAppointmentsForAppt
        .filter(appt => appt.date === data.date)
        .filter(appt => appt.status !== 'cancelled')
        .filter(appt => normalizeRoomKey(appt.room) === selectedRoomKey)
        .map(appt => String(appt.time || '').substring(0, 5))
        .filter(Boolean)
    );
  }, [allAppointmentsForAppt, data.date, selectedRoomKey]);
  const firstFreeTimeSlot = useMemo(() => (
    availableTimeSlots.find(slot => !occupiedTimeSlots.has(slot)) || null
  ), [availableTimeSlots, occupiedTimeSlots]);

  const latestInvoice = useMemo(() => {
    if (!data.patientId && !data.patient) return null;
    const patientKey = String(data.patientId || data.patient || '').trim().toLowerCase();
    const matches = allInvoicesForAppt.filter(inv => {
      const invPatientId = String(inv.patientId || inv.patient_id || '').trim().toLowerCase();
      const invPatientName = String(inv.patient || '').trim().toLowerCase();
      return (patientKey && invPatientId === patientKey) || (patientKey && invPatientName === patientKey);
    });
    matches.sort((a, b) => {
      const dateDelta = new Date(b.date || b.created_at || 0) - new Date(a.date || a.created_at || 0);
      if (dateDelta !== 0) return dateDelta;
      return new Date(b.created_at || 0) - new Date(a.created_at || 0);
    });
    return matches[0] || null;
  }, [allInvoicesForAppt, data.patientId, data.patient]);

  const latestInvoiceTotal = latestInvoice ? (parseFloat(latestInvoice.total) || 0) : 0;
  const latestInvoicePaid = latestInvoice ? (parseFloat(latestInvoice.paid) || 0) : 0;
  const latestInvoiceRemaining = latestInvoice ? Math.max(0, latestInvoiceTotal - latestInvoicePaid) : 0;
  const latestInvoiceServices = latestInvoice ? (latestInvoice.items || []).map(item => item.name).filter(Boolean) : [];
  const latestInvoiceServiceChips = latestInvoiceServices.length ? latestInvoiceServices : ['خدمة غير محددة'];

  useEffect(() => {
    if (!availableTimeSlots.includes(data.time)) {
      setData(prev => ({ ...prev, time: availableTimeSlots[0] }));
    }
  }, [availableTimeSlots, data.time]);

  useEffect(() => {
    if (!availableRooms.includes(data.room)) {
      setData(prev => ({ ...prev, room: availableRooms[0] }));
    }
  }, [availableRooms, data.room]);

  useEffect(() => {
    if (occupiedTimeSlots.has(data.time) && firstFreeTimeSlot && firstFreeTimeSlot !== data.time) {
      setData(prev => ({ ...prev, time: firstFreeTimeSlot }));
    }
  }, [occupiedTimeSlots, data.time, firstFreeTimeSlot]);

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', { className: 'flex gap-12 ai-c' },
        h('button', { className: 'icon-btn', onClick: () => setScreen('appointments') }, h(Icons.ChevronRight, { size: 18 })),
        h('div', null,
          h('div', { className: 'page-title' }, 'حجز موعد جديد'),
          h('div', { className: 'page-subtitle' }, `الخطوة ${step} من ${steps.length}: ${steps[step-1]}`),
        ),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { style: { maxWidth: 800, margin: '0 auto' } },
        // Stepper
        h('div', { className: 'flex ai-c mb-24', style: { gap: 0 } },
          steps.map((s, i) => h(Fragment, { key: i },
            h('div', { className: 'flex ai-c gap-8' },
              h('div', {
                style: {
                  width: 32, height: 32, borderRadius: '50%', display: 'grid', placeItems: 'center',
                  background: i + 1 <= step ? 'var(--accent)' : 'var(--bg-subtle)',
                  color: i + 1 <= step ? '#fff' : 'var(--text-tertiary)',
                  fontWeight: 800, fontSize: 14,
                },
              }, i + 1 < step ? h(Icons.Check, { size: 16 }) : i + 1),
              h('div', { style: { fontSize: 13, fontWeight: 600, color: i + 1 <= step ? 'var(--text-primary)' : 'var(--text-tertiary)' } }, s),
            ),
            i < steps.length - 1 ? h('div', { style: { flex: 1, height: 2, background: i + 1 < step ? 'var(--accent)' : 'var(--border)', margin: '0 12px' } }) : null,
          )),
        ),

        h('div', { className: 'card p-24' },
          step === 1 && h('div', null,
            h('div', { className: 'label' }, 'ابحث عن مريض'),
            h('input', { className: 'input mb-16', placeholder: 'اسم، رقم هاتف، أو ID...', value: data.patient, onChange: (e) => setData({ ...data, patient: e.target.value }) }),
            h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 8 } }, 'مرضى مقترحون'),
            h('div', { className: 'grid', style: { gap: 8 } },
              allPatientsForAppt.filter(p => !data.patient || p.name.includes(data.patient) || (p.phone||'').includes(data.patient)).slice(0, 4).map(p => h('div', {
                key: p.id,
                onClick: () => setData({ ...data, patient: p.name, patientId: p.id }),
                style: {
                  padding: 12, border: '1px solid ' + (data.patient === p.name ? 'var(--accent)' : 'var(--border)'),
                  background: data.patient === p.name ? 'var(--accent-soft)' : 'transparent',
                  borderRadius: 'var(--radius)', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 12,
                },
              },
                h('div', { className: 'avatar sm' }, p.avatar),
                h('div', { style: { flex: 1 } },
                  h('div', { style: { fontWeight: 700, fontSize: 14 } }, p.name),
                  h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, `${p.phone} · ${p.id}`),
                ),
              )),
            ),
            h('button', { className: 'btn outline mt-16', style: { width: '100%' }, onClick: () => setShowQuickAdd(true) }, h(Icons.UserPlus, { size: 16 }), 'إضافة مريض جديد'),
            showQuickAdd ? h(QuickAddPatientModal, {
              onClose: () => setShowQuickAdd(false),
              onSaved: (newP) => { setData(d => ({ ...d, patient: newP.name, patientId: newP.id })); },
            }) : null,
          ),
          step === 2 && h('div', null,
            h('div', { className: 'label' }, 'هل هو كشف جديد أم مريض متابعة؟'),
            h('div', { className: 'grid cols-2 mb-16', style: { gap: 12 } },
              [
                { key: 'كشف جديد', title: 'كشف جديد', subtitle: 'حجز سريع بدون تفاصيل إضافية' },
                { key: 'مريض متابعة', title: 'مريض متابعة', subtitle: 'عرض آخر فاتورة والرصيد المتبقي' },
              ].map(option => h('button', {
                key: option.key,
                type: 'button',
                onClick: () => setData(prev => ({ ...prev, type: option.key })),
                className: 'card',
                style: {
                  textAlign: 'right',
                  padding: 18,
                  border: '1px solid ' + (data.type === option.key ? 'var(--accent)' : 'var(--border)'),
                  background: data.type === option.key ? 'var(--accent-soft)' : 'var(--bg-elevated)',
                  boxShadow: 'none',
                  cursor: 'pointer',
                },
              },
                h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 6 } }, option.title),
                h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, option.subtitle),
              )),
            ),
            data.type === 'مريض متابعة' ? h('div', {
              style: {
                border: '1px solid var(--border)',
                borderRadius: 'var(--radius-lg)',
                background: 'var(--bg-subtle)',
                padding: 16,
                marginBottom: 16,
              },
            },
              latestInvoice ? [
                h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 6 } }, 'آخر فاتورة'),
                h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 4 } },
                  latestInvoiceServiceChips.map((service, index) => h('span', {
                    key: index,
                    style: {
                      display: 'inline-flex',
                      alignItems: 'center',
                      padding: '4px 10px',
                      borderRadius: 999,
                      background: 'var(--bg-elevated)',
                      border: '1px solid var(--border)',
                      fontSize: 12,
                      fontWeight: 700,
                      color: 'var(--text-primary)',
                      lineHeight: 1.4,
                    },
                  }, service)),
                ),
                h('div', { style: { fontSize: 13, color: 'var(--text-secondary)', marginBottom: 4 } }, latestInvoice.date ? `التاريخ: ${latestInvoice.date}` : 'التاريخ غير متاح'),
                h('div', { style: { fontSize: 14, fontWeight: 700 } }, `المبلغ المتبقي: ${window.fmtEGP(latestInvoiceRemaining)}`),
              ] : h('div', { style: { fontSize: 13, color: 'var(--text-secondary)' } }, 'لا توجد فاتورة سابقة مسجلة لهذا المريض.'),
            ) : null,
          ),
            step === 3 && h('div', null,
              h('div', { className: 'label' }, 'الطبيب'),
              h('div', { className: 'grid cols-2 mb-16', style: { gap: 8 } },
                allDoctorsForAppt.map(d => h('div', {
                  key: d.id,
                  onClick: () => setData({ ...data, doctor: d.name, doctorId: d.id }),
                  style: {
                    padding: 10, border: '1px solid ' + (data.doctor === d.name ? 'var(--accent)' : 'var(--border)'),
                    background: data.doctor === d.name ? 'var(--accent-soft)' : 'transparent',
                    borderRadius: 'var(--radius)', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 10,
                  },
                },
                  h('div', { className: 'avatar sm', style: { background: d.color } }, d.avatar),
                  h('div', null,
                    h('div', { style: { fontWeight: 700, fontSize: 13 } }, d.name),
                    h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, d.specialty),
                  ),
                )),
              ),
              h('div', { className: 'grid cols-2 mb-16', style: { gap: 12 } },
                h('div', null, h('div', { className: 'label' }, 'التاريخ'), h('input', { className: 'input', type: 'date', value: data.date, onChange: (e) => setData({ ...data, date: e.target.value }) })),
                h('div', null, h('div', { className: 'label' }, 'الوقت'), h('input', { className: 'input', type: 'time', min: availableTimeSlots[0], max: availableTimeSlots[availableTimeSlots.length - 1], step: 1800, value: data.time, onChange: (e) => setData({ ...data, time: e.target.value }) })),
              ),
              h('div', { className: 'label' }, 'الأوقات المتاحة'),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 10 } }, `حسب إعدادات العيادة: من ${availableTimeSlots[0]} إلى ${availableTimeSlots[availableTimeSlots.length - 1]}`),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 10 } }, 'الوقت المحجوز في نفس الغرفة يظهر بعلامة × ولا يمكن اختياره.'),
              h('div', { className: 'flex gap-8 wrap mb-16' },
                availableTimeSlots.map(t => {
                  const isBooked = occupiedTimeSlots.has(t);
                  return h('button', {
                    key: t,
                    disabled: isBooked,
                    className: 'btn sm ' + (data.time === t && !isBooked ? 'primary' : 'outline'),
                    style: isBooked ? {
                      color: 'var(--danger)',
                      borderColor: 'color-mix(in oklab, var(--danger) 45%, var(--border))',
                      background: 'var(--danger-soft)',
                      opacity: 0.7,
                      cursor: 'not-allowed',
                      textDecoration: 'line-through',
                    } : null,
                    onClick: () => {
                      if (isBooked) return;
                      setData({ ...data, time: t });
                    },
                  }, isBooked ? '× ' + t : t);
                }),
              ),
              h('div', { className: 'label' }, 'الغرفة'),
              h('div', { className: 'flex gap-8 mb-16' },
                availableRooms.map(r => h('button', {
                  key: r,
                  className: 'btn sm ' + (data.room === r ? 'primary' : 'outline'),
                  onClick: () => setData({ ...data, room: r }),
                }, r)),
            ),
            h('div', { className: 'label' }, 'ملاحظات'),
            h('textarea', { className: 'textarea', rows: 3, placeholder: 'أي ملاحظات خاصة بالموعد...', value: data.notes, onChange: (e) => setData({ ...data, notes: e.target.value }) }),
            h('label', { className: 'flex ai-c gap-8 mt-16', style: { cursor: 'pointer' } },
              h('input', { type: 'checkbox', checked: data.reminder, onChange: (e) => setData({ ...data, reminder: e.target.checked }) }),
              h('span', { style: { fontSize: 13 } }, 'إرسال تذكير تلقائي عبر WhatsApp قبل الموعد بـ 24 ساعة'),
            ),
          ),
          step === 4 && h('div', null,
            h('div', { style: { textAlign: 'center', marginBottom: 20 } },
              h('div', { style: { width: 64, height: 64, borderRadius: '50%', background: 'var(--success-soft)', color: 'var(--success)', display: 'grid', placeItems: 'center', margin: '0 auto 12px' } },
                h(Icons.Check, { size: 32 })),
              h('div', { style: { fontSize: 18, fontWeight: 800 } }, 'تأكيد الموعد'),
              h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, 'راجع التفاصيل قبل الحفظ'),
            ),
            h('div', { style: { padding: 16, background: 'var(--bg-subtle)', borderRadius: 'var(--radius)' } },
              [
                { label: 'المريض', value: data.patient || '—' },
                { label: 'حالة المريض', value: data.type || '—' },
                { label: 'الطبيب', value: data.doctor },
                { label: 'التاريخ والوقت', value: `${data.date} · ${data.time}` },
                { label: 'الغرفة', value: data.room },
              ].map((r, i) => h('div', { key: i, style: { display: 'flex', justifyContent: 'space-between', padding: '10px 0', borderBottom: i < 5 ? '1px solid var(--border)' : 'none' } },
                h('span', { style: { fontSize: 13, color: 'var(--text-tertiary)' } }, r.label),
                h('span', { style: { fontSize: 13, fontWeight: 700 } }, r.value),
              )),
            ),
          ),

          h('div', { className: 'flex jc-sb mt-24' },
            h('button', { className: 'btn outline', onClick: () => step > 1 ? setStep(step - 1) : setScreen('appointments') }, step === 1 ? 'إلغاء' : 'السابق'),
              h('button', {
                className: 'btn primary',
                disabled: saving,
                onClick: async () => {
                  if (step < 4) { setStep(step + 1); return; }
                  if (!data.patientId) { toast('اختر مريضاً أولاً'); return; }
                  if (!data.type) { toast('اختار هل هو كشف جديد أم مريض متابعة'); return; }
                  if (!data.doctorId) { toast('اختار الطبيب أولاً'); return; }
                  if (occupiedTimeSlots.has(data.time)) { toast('هذا الموعد محجوز بالفعل في الغرفة المحددة'); return; }
                  setSaving(true);
                  try {
                    const appt = await DB.addAppointment(clinicId, {
                    patient_id: data.patientId,
                    doctor_id: data.doctorId || (window.DOCTORS[0] && window.DOCTORS[0].id),
                    date: data.date,
                    time: data.time + ':00',
                    duration: data.duration || 30,
                    type: data.type,
                    status: 'pending',
                    room: data.room,
                    notes: data.notes,
                  });
                  setAppointments([appt, ...appointments]);
                  toast('تم حجز الموعد بنجاح 🎉');
                  setScreen('appointments');
                } catch(e) {
                  console.error(e);
                  toast('حدث خطأ أثناء الحفظ');
                } finally { setSaving(false); }
              },
            }, saving ? 'جاري الحفظ...' : step === 4 ? 'تأكيد الحجز' : 'التالي'),
          ),
        ),
      ),
    ),
  );
}

// ==================== Billing ====================

// تسجيل جلسة مع المبلغ المدفوع فيها
function AddSessionModal({ inv, onClose, onSaved }) {
  const { toast, clinicId } = useContext(AppContext);
  const today = getClinicTodayKey();
  const remaining = inv.total - inv.paid;

  const [form, setForm] = useState({
    date: today,
    paid_amount: remaining > 0 ? remaining : 0,
    payment_method: inv.paymentMethod || 'cash',
    work_done: '',
    next_appt: '',
    notes: '',
  });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSave = async () => {
    const amt = parseFloat(form.paid_amount) || 0;
    if (amt < 0) { toast('أدخل مبلغ صحيح'); return; }
    setSaving(true);
    try {
      const result = await DB.addSessionWithPayment(clinicId, {
        invoice_id: inv.id,
        patient_id: inv.patientId,
        doctor_id: inv.doctorId || null,
        date: form.date,
        paid_amount: amt,
        payment_method: form.payment_method || 'cash',
        work_done: form.work_done,
        next_appt: form.next_appt || null,
        doctor_commission: 0,
        notes: form.notes,
      });
      toast('تم تسجيل الجلسة ✅');
      onSaved(result);
      onClose();
    } catch(e) { console.error(e); toast('خطأ في الحفظ'); }
    finally { setSaving(false); }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.5)',zIndex:600 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:28,width:460,zIndex:601,boxShadow:'var(--shadow-lg)',maxHeight:'90vh',overflowY:'auto' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16} },
        h('div', { style:{fontWeight:800,fontSize:17} }, 'تسجيل جلسة وتحصيل'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{padding:'10px 14px',background:'var(--bg-subtle)',borderRadius:'var(--radius)',marginBottom:16,fontSize:13,display:'flex',justifyContent:'space-between',alignItems:'center'} },
        h('span', { style:{fontWeight:700} }, inv.patient),
        h('span', { style:{color:'var(--danger)',fontWeight:800} }, `متبقي: ${window.fmtEGP(remaining)}`),
      ),
      h('div', { style:{marginBottom:12,fontSize:12,color:'var(--text-tertiary)',lineHeight:1.8} }, 'أضف الجلسة وسجّل المبلغ الذي دفعه المريض فيها. لا تحتاج لإضافة دفعة منفصلة من هنا.'),
      h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12,marginBottom:12} },
        h('div', null,
          h('div', { className:'label' }, 'التاريخ'),
          h('input', { className:'input', type:'date', value:form.date, onChange:e=>set('date',e.target.value) }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'المبلغ المدفوع'),
          h('input', { className:'input', type:'number', min:0, value:form.paid_amount, onChange:e=>set('paid_amount',e.target.value) }),
        ),
      ),
      h('div', { style:{marginBottom:12} },
        h('div', { className:'label' }, 'طريقة الدفع'),
        h('select', { className:'input', value:form.payment_method, onChange:e=>set('payment_method', e.target.value) },
          h('option', { value:'cash' }, 'كاش'),
          h('option', { value:'card' }, 'كارت'),
          h('option', { value:'transfer' }, 'تحويل'),
          h('option', { value:'insurance' }, 'تأمين'),
        ),
      ),
      h('div', { style:{marginBottom:12} },
        h('div', { className:'label' }, 'الشغل المنجز في هذه الجلسة'),
        h('textarea', { className:'textarea', rows:3, placeholder:'حشو عصب، خلع، تركيب تاج...', value:form.work_done, onChange:e=>set('work_done',e.target.value) }),
      ),
      h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12,marginBottom:20} },
        h('div', null,
          h('div', { className:'label' }, 'الموعد الجاي (اختياري)'),
          h('input', { className:'input', type:'date', value:form.next_appt, onChange:e=>set('next_appt',e.target.value) }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'ملاحظات'),
          h('input', { className:'input', placeholder:'...', value:form.notes, onChange:e=>set('notes',e.target.value) }),
        ),
      ),
      h('div', { className:'flex gap-8 jc-sb' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave },
          saving ? 'جاري الحفظ...' : 'حفظ الجلسة',
        ),
      ),
    ),
  );
}

// تفاصيل الفاتورة مع كل الجلسات
function InvoiceDetailModal({ inv, onClose, onInvoiceUpdated }) {
  const { toast, setInvoices } = useContext(AppContext);
  const [sessions, setSessions] = useState([]);
  const [payments, setPayments] = useState([]);
  const [loading, setLoading] = useState(true);
  const [showAdd, setShowAdd] = useState(false);
  const noteMeta = inv.noteMeta || (window.decodeInvoiceNotes ? window.decodeInvoiceNotes(inv.notes) : {});
  const invoiceItems = Array.isArray(inv.items) ? inv.items : [];
  const invoiceSubtotal = invoiceItems.reduce((sum, item) => sum + ((Number(item.qty) || 0) * (Number(item.price) || 0)), 0);
  const invoiceDiscountAmount = Number(noteMeta.discountAmount || inv.discountAmount || 0) || 0;
  const hasDiscount = invoiceDiscountAmount > 0;

  useEffect(() => {
    Promise.all([
      DB.getInvoiceSessions(inv.id),
      DB.getInvoicePayments(inv.id),
    ])
      .then(([sessionRows, paymentRows]) => {
        setSessions(sessionRows || []);
        setPayments(paymentRows || []);
      })
      .catch(e => console.error(e))
      .finally(() => setLoading(false));
  }, [inv.id]);

  const handleSessionSaved = ({ session, payment, invoice }) => {
    setSessions(prev => [...prev, session]);
    if (payment) setPayments(prev => [payment, ...prev]);
    const updatedInv = invoice || inv;
    setInvoices(prev => (prev||[]).map(i => i.id === inv.id ? updatedInv : i));
    onInvoiceUpdated(updatedInv);
  };

  const handleDeleteSession = async (sessionId) => {
    if (!confirm('حذف هذه الجلسة؟')) return;
    try {
      const result = await DB.deleteSession(sessionId);
      setSessions(prev => prev.filter(s => s.id !== sessionId));
      setPayments(prev => prev.filter(payment => payment.sessionId !== sessionId));
      const updatedInv = result?.invoice || inv;
      setInvoices(prev => (prev||[]).map(i => i.id === inv.id ? updatedInv : i));
      onInvoiceUpdated(updatedInv);
      toast('تم حذف الجلسة');
    } catch(e) { toast('خطأ في الحذف'); }
  };

  const handleDeletePayment = async (payment) => {
    if (!payment || payment.sourceType === 'session') return;
    if (!confirm('حذف هذه الدفعة؟')) return;
    try {
      const result = await DB.deletePayment(payment.id);
      setPayments(prev => prev.filter(row => row.id !== payment.id));
      const updatedInv = result?.invoice || inv;
      setInvoices(prev => (prev||[]).map(i => i.id === inv.id ? updatedInv : i));
      onInvoiceUpdated(updatedInv);
      toast('تم حذف الدفعة');
    } catch (error) {
      console.error(error);
      toast('تعذر حذف الدفعة');
    }
  };

  const statusColor = { paid:'success', partial:'warning', unpaid:'danger' };
  const statusLabel = { paid:'مدفوعة', partial:'جزئية', unpaid:'غير مدفوعة' };

  return h(Fragment, null,
    showAdd ? h(AddSessionModal, { inv, onClose:()=>setShowAdd(false), onSaved:handleSessionSaved }) : null,
    h('div', { onClick: onClose, style:{position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:200} }),
    h('div', { style:{position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:0,width:560,zIndex:201,boxShadow:'var(--shadow-lg)',maxHeight:'85vh',display:'flex',flexDirection:'column'} },
      // Header
      h('div', { style:{padding:'20px 24px 16px',borderBottom:'1px solid var(--border)',display:'flex',justifyContent:'space-between',alignItems:'center'} },
        h('div', null,
          h('div', { style:{fontWeight:800,fontSize:16} },
            typeof inv.id==='string'&&inv.id.startsWith('INV') ? inv.id : 'INV-'+String(inv.id).slice(-6),
            h('span', { className:'chip '+statusColor[inv.status], style:{marginRight:8} }, statusLabel[inv.status]),
          ),
          h('div', { style:{fontSize:13,color:'var(--text-tertiary)',marginTop:2} },
            inv.patient
            + (inv.doctorName ? ' · ' + inv.doctorName : '')
            + (inv.date ? ' · ' + inv.date : '')
          ),
        ),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      // Summary
      h('div', { style:{padding:'12px 24px',background:'var(--bg-subtle)',display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:12} },
        [
          { label:'الإجمالي', val: inv.total, color:'var(--text-primary)' },
          { label:'مدفوع', val: inv.paid, color:'var(--success)' },
          { label:'متبقي', val: inv.total - inv.paid, color:'var(--danger)' },
        ].map((k,i) => h('div', { key:i, style:{textAlign:'center'} },
          h('div', { style:{fontSize:11,color:'var(--text-tertiary)'} }, k.label),
          h('div', { style:{fontSize:16,fontWeight:800,color:k.color} }, window.fmtEGP(k.val)),
        )),
      ),
      // Work done + discount
      h('div', { style:{padding:'16px 24px',borderBottom:'1px solid var(--border)'} },
        h('div', { style:{fontWeight:800,fontSize:14,marginBottom:10} }, 'الشغل المنجز'),
        invoiceItems.length ? h('div', { style:{display:'flex',flexWrap:'wrap',gap:8} },
          invoiceItems.map((item, index) => h('span', {
            key: item.id || index,
            style: {
              display: 'inline-flex',
              alignItems: 'center',
              gap: 6,
              padding: '4px 10px',
              borderRadius: 999,
              background: 'var(--bg-subtle)',
              border: '1px solid var(--border)',
              fontSize: 12,
              fontWeight: 700,
            },
          }, `${item.name}${Number(item.qty) > 1 ? ` × ${item.qty}` : ''}`))
        ) : h('div', { style:{fontSize:13,color:'var(--text-tertiary)'} }, 'لا توجد خدمات مسجلة'),
        h('div', { style:{fontSize:12,marginTop:10,color:hasDiscount ? 'var(--warning)' : 'var(--text-tertiary)',fontWeight:600} },
          hasDiscount
            ? `الخصم: ${window.fmtEGP(invoiceDiscountAmount)}`
            : `لا يوجد خصم مسجل${invoiceSubtotal ? ` · إجمالي الشغل قبل الخصم: ${window.fmtEGP(invoiceSubtotal)}` : ''}`,
        ),
      ),
      // Sessions list
      h('div', { style:{flex:1,overflowY:'auto',padding:'16px 24px'} },
        h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:12} },
          h('div', null,
            h('div', { style:{fontWeight:700,fontSize:14} }, `الجلسات (${sessions.length})`),
            h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:4} }, 'كل جلسة تسجل الشغل المنجز والمبلغ المدفوع فيها'),
          ),
          h('button', { className:'btn sm primary', onClick:()=>setShowAdd(true) },
            h(Icons.Plus, {size:14}), 'جلسة جديدة'
          ),
        ),
        loading ? h('div', { style:{textAlign:'center',padding:24,color:'var(--text-tertiary)'} }, 'جاري التحميل...') :
        sessions.length === 0 ? h('div', { style:{textAlign:'center',padding:24,color:'var(--text-tertiary)',border:'2px dashed var(--border)',borderRadius:'var(--radius)'} },
          h('div', null, 'لا توجد جلسات مسجلة'),
          h('button', { className:'btn sm primary mt-12', onClick:()=>setShowAdd(true) }, h(Icons.Plus, {size:14}), 'أضف أول جلسة'),
        ) :
        h('div', { style:{display:'flex',flexDirection:'column',gap:8} },
          sessions.map(s => h('div', { key:s.id, style:{padding:'12px 14px',border:'1px solid var(--border)',borderRadius:'var(--radius)',display:'grid',gridTemplateColumns:'1fr 1fr auto',gap:8,alignItems:'center'} },
            h('div', null,
              h('div', { style:{fontSize:13,fontWeight:700} }, window.fmtDate(s.date)),
              s.workDone ? h('div', { style:{fontSize:12,color:'var(--text-tertiary)',marginTop:2} }, s.workDone) : null,
            ),
            h('div', null,
              h('div', { style:{fontSize:15,fontWeight:800,color:'var(--success)'} }, window.fmtEGP(s.paidAmount)),
              s.doctorCommission > 0 ? h('div', { style:{fontSize:11,color:'var(--text-tertiary)'} }, `عمولة: ${window.fmtEGP(s.doctorCommission)}`) : null,
            ),
            h('button', { className:'icon-btn', style:{color:'var(--danger)'}, onClick:()=>handleDeleteSession(s.id) },
              h(Icons.Trash, {size:13}),
            ),
          )),
        ),
      ),
      h('div', { style:{padding:'0 24px 16px'} },
        h('div', { style:{paddingTop:16,borderTop:'1px solid var(--border)'} },
          h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10} },
            h('div', null,
              h('div', { style:{fontWeight:700,fontSize:14} }, `سجل التحصيل (${payments.length})`),
              h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:4} }, 'يُنشأ تلقائياً من الجلسات المسجلة'),
            ),
            h('span', { style:{fontSize:12,color:'var(--text-tertiary)'} }, window.fmtEGP(payments.reduce((sum, payment) => sum + (Number(payment.amount) || 0), 0))),
          ),
          payments.length ? h('div', { style:{display:'flex',flexDirection:'column',gap:8} },
            payments.map(payment => h('div', { key:payment.id, style:{padding:'12px 14px',border:'1px solid var(--border)',borderRadius:'var(--radius)',display:'grid',gridTemplateColumns:'1fr auto auto',gap:10,alignItems:'center'} },
              h('div', null,
                h('div', { style:{fontSize:13,fontWeight:700} }, `${window.fmtDate(payment.date)} · ${payment.receivedBy || 'تحصيل'}`),
                h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:2} }, [payment.method, payment.sourceType === 'session' ? 'ناتجة من جلسة' : 'تحصيل يدوي', payment.notes].filter(Boolean).join(' · ')),
              ),
              h('span', { className:`chip ${payment.sourceType === 'session' ? 'accent' : 'success'}` }, payment.sourceType === 'session' ? 'جلسة' : 'يدوي'),
              payment.sourceType === 'session'
                ? h('span', { style:{fontWeight:800,color:'var(--success)'} }, window.fmtEGP(payment.amount))
                : h('div', { className:'flex gap-4 ai-c' },
                  h('span', { style:{fontWeight:800,color:'var(--success)'} }, window.fmtEGP(payment.amount)),
                  h('button', { className:'icon-btn', style:{color:'var(--danger)'}, onClick:()=>handleDeletePayment(payment) }, h(Icons.Trash, {size:13})),
                ),
            ))
          ) : h('div', { style:{fontSize:12,color:'var(--text-tertiary)',padding:'10px 0'} }, 'لا توجد تحصيلات مسجلة بعد'),
        ),
      ),
      h('div', { style:{padding:'12px 24px',borderTop:'1px solid var(--border)'} },
        h('button', { className:'btn outline', style:{width:'100%'}, onClick:onClose }, 'إغلاق'),
      ),
    ),
  );
}

function Billing() {
  const { setScreen, screenParams, invoices, setInvoices, toast, clinicName } = useContext(AppContext);
  const [detailInv, setDetailInv] = useState(null);
  const [editInv, setEditInv] = useState(null);
  const [tabFilter, setTabFilter] = useState('all');
  const [billSearch, setBillSearch] = useState('');
  const [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const [showDateFilter, setShowDateFilter] = useState(false);
  const [activeDatePreset, setActiveDatePreset] = useState('all');
  const setBillingRange = (fromValue, toValue, presetKey = 'custom') => {
    setDateFrom(fromValue || '');
    setDateTo(toValue || '');
    setActiveDatePreset(presetKey);
  };
  const applyBillingPreset = (presetKey) => {
    const { fromValue, toValue } = window.resolveDateRangePreset
      ? window.resolveDateRangePreset(presetKey)
      : { fromValue: '', toValue: '' };
    setBillingRange(fromValue, toValue, presetKey);
    setShowDateFilter(false);
  };
  const clearBillingRange = () => {
    setBillingRange('', '', 'all');
    setShowDateFilter(false);
  };
  const selectedRangeLabel = window.getDateRangeLabel
    ? window.getDateRangeLabel(dateFrom, dateTo)
    : 'كل التواريخ';
  const allInvoices = (invoices && invoices.length) ? invoices : (window.INVOICES || []);
  useEffect(() => {
    if (!screenParams?.invoiceId) return;
    const match = allInvoices.find((invoice) => invoice.id === screenParams.invoiceId);
    if (match) setDetailInv(match);
  }, [allInvoices, screenParams]);
  const dateFilteredInvoices = allInvoices.filter(i => {
    const invDate = String(i.date || '').slice(0, 10);
    if (dateFrom && (!invDate || invDate < dateFrom)) return false;
    if (dateTo && (!invDate || invDate > dateTo)) return false;
    return true;
  });
  const filtered = dateFilteredInvoices.filter(i => {
    if (tabFilter !== 'all' && i.status !== tabFilter) return false;
    if (billSearch) {
      const q = billSearch.toLowerCase();
      const nameMatch = (i.patient || '').toLowerCase().includes(q);
      const doctorMatch = (i.doctorName || '').toLowerCase().includes(q);
      const phoneMatch = (i.phone || i.patient_phone || '').includes(q);
      const idMatch = String(i.id || '').toLowerCase().includes(q);
      if (!nameMatch && !doctorMatch && !phoneMatch && !idMatch) return false;
    }
    return true;
  });
  const total = dateFilteredInvoices.reduce((s, i) => s + i.total, 0);
  const paid  = dateFilteredInvoices.reduce((s, i) => s + i.paid,  0);
  const outstanding = total - paid;

  return h('div', { className: 'fade-in' },
    detailInv ? h(InvoiceDetailModal, { inv: detailInv, onClose:()=>setDetailInv(null), onInvoiceUpdated:(upd)=>setDetailInv(upd) }) : null,
    editInv ? h(EditInvoiceModal, { inv: editInv, onClose:()=>setEditInv(null), onSaved:(upd)=>{ setInvoices(prev=>prev.map(i=>i.id===upd.id?upd:i)); setEditInv(null); } }) : null,
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الفواتير والمدفوعات'),
        h('div', { className: 'page-subtitle' }, `${dateFilteredInvoices.length} فاتورة · ${window.fmtEGP(outstanding)} مستحقة${dateFrom || dateTo ? ' ضمن الفترة المحددة' : ''}`),
      ),
      h('div', { className: 'flex gap-8' },
        h('button', { className: 'btn outline' }, h(Icons.Download, { size: 16 }), 'تصدير'),
        h('button', { className: 'btn primary', onClick: () => setScreen('new-invoice') }, h(Icons.Plus, { size: 16 }), 'فاتورة جديدة'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'grid cols-3 mb-16' },
        [
          { label: 'إجمالي الفواتير', value: total, icon: Icons.CreditCard, color: 'var(--accent)', soft: 'var(--accent-soft)' },
          { label: 'مدفوع', value: paid, icon: Icons.Check, color: 'var(--success)', soft: 'var(--success-soft)' },
          { label: 'مستحق', value: outstanding, icon: Icons.AlertTriangle, color: 'var(--danger)', soft: 'var(--danger-soft)' },
        ].map((k, i) => h('div', { key: i, className: 'card kpi' },
          h('div', { className: 'flex jc-sb ai-c' },
            h('div', null,
              h('div', { className: 'label' }, k.label),
              h('div', { className: 'value' }, window.fmtEGP(k.value)),
            ),
            h('div', { className: 'kpi-icon', style: { background: k.soft, color: k.color } }, h(k.icon, { size: 20 })),
          ),
        )),
      ),
      h('div', { className: 'card', style: { overflow: 'visible' } },
        h('div', { style: { padding: '12px 16px', borderBottom: '1px solid var(--border)' } },
          h(Shell.DateRangeFilter, {
            title: 'فلتر التاريخ',
            subtitle: 'اختر فترة جاهزة أو حدد من يوم إلى يوم',
            dateFrom,
            dateTo,
            open: showDateFilter,
            onToggle: () => setShowDateFilter(prev => !prev),
            onClose: () => setShowDateFilter(false),
            onPresetSelect: applyBillingPreset,
            activePreset: activeDatePreset,
            onFromChange: (value) => {
              setDateFrom(value);
              setActiveDatePreset('custom');
            },
            onToChange: (value) => {
              setDateTo(value);
              setActiveDatePreset('custom');
            },
            onClear: clearBillingRange,
            onApply: () => setShowDateFilter(false),
          }),
          h('div', { style: { position: 'relative' } },
            h('input', {
              className: 'input',
              placeholder: 'ابحث باسم المريض أو رقم الهاتف...',
              value: billSearch,
              onChange: e => setBillSearch(e.target.value),
              style: { paddingInlineEnd: 38 },
            }),
            billSearch ? h('button', {
              onClick: () => setBillSearch(''),
              style: {
                position: 'absolute', insetInlineEnd: 10, top: '50%', transform: 'translateY(-50%)',
                background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-tertiary)', padding: 2,
              },
            }, h(Icons.X, { size: 14 })) :
            h('span', {
              style: { position: 'absolute', insetInlineEnd: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--text-tertiary)', pointerEvents: 'none' },
            }, h(Icons.Search, { size: 15 })),
          ),
        ),
        h('div', { className: 'tabs', style: { padding: '0 16px', marginBottom: 0 } },
          [['all','الكل'],['paid','مدفوعة'],['partial','جزئية'],['unpaid','غير مدفوعة']].map(([v,l]) => h('button', {
            key: v, className: 'tab' + (tabFilter===v?' active':''), onClick:()=>setTabFilter(v),
          }, l)),
        ),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, ['رقم الفاتورة', 'المريض', 'الطبيب', 'التاريخ', 'الإجمالي', 'المدفوع', 'المتبقي', 'الحالة', ''].map((t, i) => h('th', { key: i }, t)))),
          h('tbody', null,
            filtered.length ? filtered.map(inv => h('tr', { key: inv.id, style: { cursor: 'pointer' }, onClick:()=>setDetailInv(inv) },
              h('td', { style: { fontFamily: 'monospace', fontSize: 12, fontWeight: 700 } }, typeof inv.id === 'string' && inv.id.startsWith('INV') ? inv.id : 'INV-' + String(inv.id).slice(-6)),
              h('td', null, inv.patient),
              h('td', null, inv.doctorName || '—'),
              h('td', { style: { fontSize: 13, color: 'var(--text-secondary)' } }, inv.date),
              h('td', { style: { fontWeight: 700 } }, window.fmtEGP(inv.total)),
              h('td', { style: { color: 'var(--success)', fontWeight: 600 } }, window.fmtEGP(inv.paid)),
              h('td', { style: { color: inv.total - inv.paid > 0 ? 'var(--danger)' : 'var(--text-muted)', fontWeight: 700 } }, window.fmtEGP(inv.total - inv.paid)),
              h('td', null, h('span', { className: 'chip ' + (inv.status === 'paid' ? 'success' : inv.status === 'partial' ? 'warning' : 'danger') },
                inv.status === 'paid' ? 'مدفوعة' : inv.status === 'partial' ? 'جزئية' : 'غير مدفوعة')),
              h('td', null,
                h('div', { className: 'flex gap-4' },
                  h('button', { className:'btn sm primary', onClick:e=>{e.stopPropagation();setDetailInv(inv);} }, h(Icons.Plus,{size:12}), 'جلسة'),
                  h('button', { className: 'icon-btn', title: 'عرض وتعديل', onClick: e => { e.stopPropagation(); setEditInv(inv); } }, h(Icons.Edit, { size: 14 })),
                  h('button', { className: 'icon-btn', title: 'طباعة', onClick: e => { e.stopPropagation(); printInvoice(inv, clinicName); } }, h(Icons.Printer, { size: 14 })),
                  h('button', {
                    className: 'icon-btn',
                    title: 'حذف الفاتورة',
                    style: { color: 'var(--danger)' },
                    onClick: async (e) => {
                      e.stopPropagation();
                      if (!confirm(`حذف الفاتورة ${inv.id}؟`)) return;
                      try {
                        await SB.from('invoice_items').delete().eq('invoice_id', inv.id);
                        await SB.from('invoices').delete().eq('id', inv.id);
                        setInvoices(prev => prev.filter(i => i.id !== inv.id));
                        toast('تم حذف الفاتورة');
                      } catch(e) { console.error(e); toast('خطأ في الحذف'); }
                    },
                  }, h(Icons.Trash, { size: 14 })),
                ),
              ),
            )) : h('tr', null, h('td', { colSpan:9, style:{textAlign:'center',padding:32,color:'var(--text-tertiary)'} }, 'لا توجد فواتير')),
          ),
        ),
      ),
    ),
  );
}

function Sessions() {
  const { sessions, invoices, setScreen } = useContext(AppContext);
  const [query, setQuery] = useState('');
  const [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const [showDateFilter, setShowDateFilter] = useState(false);
  const [activeDatePreset, setActiveDatePreset] = useState('all');

  const setSessionRange = (fromValue, toValue, presetKey = 'custom') => {
    setDateFrom(fromValue || '');
    setDateTo(toValue || '');
    setActiveDatePreset(presetKey);
  };

  const applySessionPreset = (presetKey) => {
    const { fromValue, toValue } = window.resolveDateRangePreset
      ? window.resolveDateRangePreset(presetKey)
      : { fromValue: '', toValue: '' };
    setSessionRange(fromValue, toValue, presetKey);
    setShowDateFilter(false);
  };

  const clearSessionRange = () => {
    setSessionRange('', '', 'all');
    setShowDateFilter(false);
  };

  const selectedRangeLabel = window.getDateRangeLabel
    ? window.getDateRangeLabel(dateFrom, dateTo)
    : 'كل التواريخ';

  const allSessions = (sessions && sessions.length) ? sessions : (window.SESSIONS || []);
  const allInvoices = (invoices && invoices.length) ? invoices : (window.INVOICES || []);
  const invoiceMap = new Map(allInvoices.map(invoice => [String(invoice.id || ''), invoice]));
  const groupedSessions = new Map();
  const remainingBySessionId = new Map();

  allSessions.forEach(session => {
    const invoiceKey = String(session?.invoiceId || '');
    if (!invoiceKey) return;
    if (!groupedSessions.has(invoiceKey)) groupedSessions.set(invoiceKey, []);
    groupedSessions.get(invoiceKey).push(session);
  });

  const formatInvoiceCode = (invoiceId) => (
    typeof invoiceId === 'string' && invoiceId.startsWith('INV')
      ? invoiceId
      : `INV-${String(invoiceId || '').slice(-6)}`
  );

  const sessionRows = [];
  allSessions.forEach(session => {
    const invoiceKey = String(session?.invoiceId || '');
    const invoice = invoiceMap.get(invoiceKey);
    const siblings = [...(groupedSessions.get(invoiceKey) || [session])].sort((a, b) => {
      const aDate = String(a?.date || a?.created_at || '');
      const bDate = String(b?.date || b?.created_at || '');
      if (aDate !== bDate) return aDate.localeCompare(bDate);
      return String(a?.created_at || '').localeCompare(String(b?.created_at || ''));
    });
    let cumulativePaid = 0;
    siblings.forEach(item => {
      cumulativePaid += Number(item?.paidAmount) || 0;
      remainingBySessionId.set(item?.id, Math.max(0, (Number(invoice?.total) || 0) - cumulativePaid));
    });

    sessionRows.push({
      id: session.id,
      patientId: session.patientId || invoice?.patientId || invoice?.patient_id || '',
      patient: session.patient || invoice?.patient || '—',
      date: session.date || invoice?.date || '',
      invoiceCode: formatInvoiceCode(session.invoiceId),
      doctorName: session.doctor || invoice?.doctorName || '—',
      services: String(session.workDone || '').trim() || (invoice?.items || []).map(item => item.name).filter(Boolean).join('، ') || 'خدمة غير محددة',
      total: Number(invoice?.total) || Number(session.paidAmount) || 0,
      paid: Number(session.paidAmount) || 0,
      remaining: Number.isFinite(remainingBySessionId.get(session.id))
        ? remainingBySessionId.get(session.id)
        : Math.max(0, (Number(invoice?.total) || 0) - (Number(session.paidAmount) || 0)),
      notes: session.notes || '',
      nextAppt: session.nextAppt || '',
      source: 'session',
    });
  });

  const dateFilteredSessions = sessionRows.filter(session => {
    const sessionDate = String(session.date || '').slice(0, 10);
    if (dateFrom && (!sessionDate || sessionDate < dateFrom)) return false;
    if (dateTo && (!sessionDate || sessionDate > dateTo)) return false;
    return true;
  });

  const normalizedQuery = query.trim().toLowerCase();
  const filtered = dateFilteredSessions.filter(session => {
    if (!normalizedQuery) return true;
    return [
      session.patient,
      session.doctorName,
      session.services,
      session.notes,
      session.nextAppt,
      session.invoiceCode,
      session.id,
    ].some(value => String(value || '').toLowerCase().includes(normalizedQuery));
  });

  const totalCollected = filtered.reduce((sum, session) => sum + (Number(session.paid) || 0), 0);
  const uniquePatients = new Set(filtered.map(session => String(session.patientId || session.patient || '').trim()).filter(Boolean)).size;
  const uniqueDoctors = new Set(filtered.map(session => String(session.doctorName || '').trim()).filter(Boolean)).size;

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الجلسات'),
        h('div', { className: 'page-subtitle' }, `${filtered.length} جلسة فعلية${dateFrom || dateTo ? ` ضمن ${selectedRangeLabel}` : ''}`),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'grid cols-3 mb-16' },
        [
          { label: 'عدد الجلسات', value: window.fmtNum(filtered.length), icon: Icons.FileText, color: 'var(--accent)', soft: 'var(--accent-soft)' },
          { label: 'المحصل الفعلي', value: window.fmtEGP(totalCollected), icon: Icons.CreditCard, color: 'var(--success)', soft: 'var(--success-soft)' },
          { label: 'مرضى الجلسات', value: window.fmtNum(uniquePatients), icon: Icons.Users, color: 'var(--warning)', soft: 'var(--warning-soft)' },
        ].map((card) => h('div', { key: card.label, className: 'card kpi' },
          h('div', { className: 'flex jc-sb ai-c' },
            h('div', null,
              h('div', { className: 'label' }, card.label),
              h('div', { className: 'value' }, card.value),
              card.label === 'مرضى الجلسات'
                ? h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 6 } }, `${window.fmtNum(uniqueDoctors)} طبيب ضمن النتائج`)
                : null,
            ),
            h('div', { className: 'kpi-icon', style: { background: card.soft, color: card.color } }, h(card.icon, { size: 20 })),
          ),
        )),
      ),
      h('div', { className: 'card', style: { overflow: 'visible' } },
        h('div', { style: { padding: '12px 16px', borderBottom: '1px solid var(--border)' } },
          h('div', { className: 'flex gap-12 ai-c wrap' },
            h('div', { style: { flex: 1, minWidth: 240, position: 'relative' } },
              h('input', {
                className: 'input',
                placeholder: 'ابحث باسم المريض أو الطبيب أو العمل المنجز...',
                value: query,
                onChange: e => setQuery(e.target.value),
                style: { paddingInlineEnd: 38 },
              }),
              query ? h('button', {
                onClick: () => setQuery(''),
                style: {
                  position: 'absolute', insetInlineEnd: 10, top: '50%', transform: 'translateY(-50%)',
                  background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-tertiary)', padding: 2,
                },
              }, h(Icons.X, { size: 14 })) :
              h('span', {
                style: { position: 'absolute', insetInlineEnd: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--text-tertiary)', pointerEvents: 'none' },
              }, h(Icons.Search, { size: 15 })),
            ),
            h('div', { style: { flex: '1 1 320px', maxWidth: 'min(320px, 100%)' } },
              h(Shell.DateRangeFilter, {
                title: 'فلتر تاريخ الجلسات',
                subtitle: 'نفس الفلتر الموحد المستخدم في المرضى والفواتير',
                dateFrom,
                dateTo,
                open: showDateFilter,
                onToggle: () => setShowDateFilter(prev => !prev),
                onClose: () => setShowDateFilter(false),
                onPresetSelect: applySessionPreset,
                activePreset: activeDatePreset,
                onFromChange: (value) => {
                  setDateFrom(value);
                  setActiveDatePreset('custom');
                },
                onToChange: (value) => {
                  setDateTo(value);
                  setActiveDatePreset('custom');
                },
                onClear: clearSessionRange,
                onApply: () => setShowDateFilter(false),
                align: 'start',
                buttonWidth: '100%',
                menuWidth: 'min(420px, calc(100vw - 48px))',
              }),
            ),
          ),
        ),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, [
            'التاريخ',
            'المريض',
            'رقم الفاتورة',
            'الطبيب',
            'الخدمة / الشغل المنجز',
            'إجمالي الفاتورة',
            'مدفوع الجلسة',
            'المتبقي',
            'النوع',
          ].map((title, index) => h('th', { key: index }, title)))),
          h('tbody', null,
            filtered.length ? filtered.map(session => h('tr', { key: session.id },
              h('td', { style: { fontWeight: 700 } }, session.date || '—'),
              h('td', null,
                session.patientId
                  ? h('button', {
                    className: 'btn ghost sm',
                    style: { padding: 0, minHeight: 'auto', color: 'var(--accent)', fontWeight: 700 },
                    onClick: () => setScreen('patient-file', { patientId: session.patientId }),
                  }, session.patient || '—')
                  : (session.patient || '—'),
              ),
              h('td', { style: { fontFamily: 'monospace', fontSize: 12, fontWeight: 700 } }, session.invoiceCode),
              h('td', null, session.doctorName || '—'),
              h('td', null,
                h('div', { style: { fontWeight: 700 } }, session.services || 'خدمة غير محددة'),
                session.nextAppt ? h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, `الموعد القادم: ${session.nextAppt}`) : null,
                session.notes ? h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, session.notes) : null,
              ),
              h('td', { style: { fontWeight: 700 } }, window.fmtEGP(session.total)),
              h('td', { style: { color: 'var(--success)', fontWeight: 700 } }, window.fmtEGP(session.paid)),
              h('td', { style: { color: session.remaining > 0 ? 'var(--danger)' : 'var(--text-muted)', fontWeight: 700 } }, window.fmtEGP(session.remaining)),
              h('td', null, h('span', { className: 'chip accent' }, 'جلسة فعلية')),
            )) : h('tr', null, h('td', { colSpan: 9, style: { textAlign: 'center', padding: 32, color: 'var(--text-tertiary)' } }, 'لا توجد جلسات مطابقة للفلاتر الحالية')),
          ),
        ),
      ),
    ),
  );
}

// ==================== Edit Invoice Notes / Paid Amount ====================
function EditInvoiceModal({ inv, onClose, onSaved }) {
  const { toast, clinicName } = useContext(AppContext);
  const [notes, setNotes] = useState(inv.notes || '');
  const [saving, setSaving] = useState(false);

  // تعديل الملاحظات فقط (البنود تتعدل من خلال الجلسات)
  const handleSave = async () => {
    setSaving(true);
    try {
      const encodedNotes = window.encodeInvoiceNotes
        ? window.encodeInvoiceNotes({
            paymentMethod: inv.paymentMethod || '',
            doctorId: inv.doctorId || null,
            doctorName: inv.doctorName || '',
            memo: notes,
            discountPercent: inv.discountPercent || inv.noteMeta?.discountPercent || 0,
            discountAmount: inv.discountAmount || inv.noteMeta?.discountAmount || 0,
            subtotal: inv.subtotal || inv.noteMeta?.subtotal || 0,
            total: inv.total || inv.noteMeta?.total || 0,
          })
        : notes;
      const { data, error } = await SB.from('invoices')
        .update({ notes: encodedNotes })
        .eq('id', inv.id)
        .select('*, patients(name)').single();
      if (error) throw error;
      toast('تم الحفظ ✅');
      onSaved({ ...inv, notes });
      onClose();
    } catch(e) { toast('خطأ: ' + (e.message || 'غير متوقع')); }
    finally { setSaving(false); }
  };

  const invId = typeof inv.id === 'string' && inv.id.startsWith('INV') ? inv.id : 'INV-' + String(inv.id).slice(-6);

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:300 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:24,width:460,zIndex:301,boxShadow:'var(--shadow-lg)' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16} },
        h('div', null,
          h('div', { style:{fontWeight:800,fontSize:16} }, 'تفاصيل الفاتورة'),
          h('div', { style:{fontSize:13,color:'var(--text-tertiary)',marginTop:2} }, invId + ' · ' + inv.patient),
        ),
        h('div', { className:'flex gap-8' },
          h('button', { className:'btn sm outline', onClick:()=>printInvoice(inv, clinicName) }, h(Icons.Printer,{size:14}), 'طباعة'),
          h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
        ),
      ),
      // بنود الفاتورة (للعرض فقط)
      h('div', { className:'card mb-14', style:{overflow:'hidden'} },
        h('table', { className:'data-table', style:{fontSize:12} },
          h('thead', null, h('tr', null, ['الخدمة','الكمية','السعر','الإجمالي'].map((t,i)=>h('th',{key:i},t)))),
          h('tbody', null,
            (inv.items||[]).length === 0 ?
              h('tr', null, h('td', {colSpan:4,style:{textAlign:'center',color:'var(--text-tertiary)',padding:16}}, 'لا توجد بنود مسجلة')) :
            (inv.items||[]).map((it,i) => h('tr',{key:i},
              h('td',{style:{fontWeight:600}}, it.name),
              h('td',null, it.qty),
              h('td',null, window.fmtEGP(it.price)),
              h('td',{style:{fontWeight:700}}, window.fmtEGP(it.qty*it.price-(it.discount||0))),
            )),
          ),
        ),
      ),
      // ملاحظات قابلة للتعديل
      h('div', null,
        h('div', { className:'label' }, 'ملاحظات الفاتورة'),
        h('textarea', { className:'textarea', rows:3, value:notes, onChange:e=>setNotes(e.target.value) }),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-16' },
        h('button', { className:'btn outline', onClick:onClose }, 'إغلاق'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave },
          saving ? 'جاري الحفظ...' : 'حفظ الملاحظات'),
      ),
    ),
  );
}

// ==================== New Invoice ====================
function NewInvoice() {
  const { setScreen, toast, clinicId, setInvoices, invoices, patients, doctors, services } = useContext(AppContext);
  const allPts  = (patients && patients.length) ? patients : (window.PATIENTS || []);
  const allDoctors = (doctors && doctors.length) ? doctors : (window.DOCTORS || []);
  const allSvcs = (services && services.length) ? services : (window.TREATMENT_TYPES || []);
  const [items, setItems] = useState([{ id: 1, service_id: null, name: 'كشف وفحص', qty: 1, price: 150 }]);
  const [patient, setPatient] = useState(null);
  const [doctorId, setDoctorId] = useState('');
  const nextInvNum = `INV-${new Date().getFullYear()}-${String((invoices ? invoices.length : 0) + 1).padStart(4, '0')}`;
  const [payMethod, setPayMethod] = useState('نقدي');
  useEffect(() => { if (!patient && allPts.length) setPatient(allPts[0]); }, [allPts.length]);
  useEffect(() => {
    if (!doctorId && allDoctors.length) setDoctorId(String(allDoctors[0].id || ''));
  }, [allDoctors.length, doctorId]);
  const [saving, setSaving] = useState(false);
  const [discount, setDiscount] = useState(0);
  const subtotal = items.reduce((s, i) => s + i.qty * i.price, 0);
  const discountAmt = Math.min(Math.max(Number(discount) || 0, 0), subtotal);
  const discountPercentValue = subtotal > 0 ? (discountAmt / subtotal) * 100 : 0;
  const total = subtotal - discountAmt;
  const selectedDoctor = allDoctors.find(d => String(d.id || '') === String(doctorId || '')) || null;

  const addItem = () => setItems([...items, { id: Date.now(), service_id: null, name: '', qty: 1, price: 0 }]);
  const removeItem = (id) => setItems(items.filter(i => i.id !== id));
  const updateItem = (id, field, val) => setItems(items.map(i => i.id === id ? { ...i, [field]: val } : i));

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', { className: 'flex gap-12 ai-c' },
        h('button', { className: 'icon-btn', onClick: () => setScreen('billing') }, h(Icons.ChevronRight, { size: 18 })),
        h('div', null,
          h('div', { className: 'page-title' }, 'فاتورة جديدة'),
          h('div', { className: 'page-subtitle' }, nextInvNum),
        ),
      ),
      h('div', { className: 'flex gap-8' },
        h('button', { className: 'btn outline', onClick: () => setScreen('billing') }, 'إلغاء'),
        h('button', {
          className: 'btn primary',
          disabled: saving,
          onClick: async () => {
            if (!patient) { toast('اختر مريضاً أولاً'); return; }
            if (allDoctors.length && !selectedDoctor) { toast('اختر الطبيب أولاً'); return; }
            setSaving(true);
            try {
              const encodedNotes = window.encodeInvoiceNotes
                ? window.encodeInvoiceNotes({
                    paymentMethod: payMethod,
                    doctorId: selectedDoctor ? selectedDoctor.id : null,
                    doctorName: selectedDoctor ? selectedDoctor.name : '',
                    memo: '',
                    discountPercent: discountPercentValue,
                    discountAmount: discountAmt,
                    subtotal,
                    total,
                  })
                : JSON.stringify({
                    paymentMethod: payMethod,
                    doctorId: selectedDoctor ? selectedDoctor.id : null,
                    doctorName: selectedDoctor ? selectedDoctor.name : '',
                    memo: '',
                    discountPercent: discountPercentValue,
                    discountAmount: discountAmt,
                    subtotal,
                    total,
                  });
              const inv = await DB.addInvoice(clinicId,
                {
                  patient_id: patient.id,
                  date: new Date().toISOString().split('T')[0],
                  notes: encodedNotes,
                  doctor_id: selectedDoctor ? selectedDoctor.id : null,
                  doctor_name: selectedDoctor ? selectedDoctor.name : '',
                  total,
                },
                items.map(it => ({ service_id: it.service_id || null, name: it.name, qty: it.qty, price: it.price, discount: 0 }))
              );
              setInvoices([inv, ...invoices]);
              toast('تم إنشاء الفاتورة بنجاح ✅');
              setScreen('billing');
            } catch(e) {
              console.error(e);
              toast('حدث خطأ أثناء الحفظ');
            } finally { setSaving(false); }
          },
        }, h(Icons.Check, { size: 16 }), saving ? 'جاري الحفظ...' : 'حفظ الفاتورة'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { className: 'label' }, 'المريض'),
          h('select', {
            className: 'select mb-16',
            value: patient ? patient.id : '',
            onChange: (e) => setPatient(allPts.find(p => p.id === e.target.value) || null),
          },
            !patient ? h('option', { value: '' }, '— اختر مريضاً —') : null,
            allPts.map(p => h('option', { key: p.id, value: p.id }, `${p.name} — ${p.phone || p.id}`)),
          ),
          h('div', { className: 'label' }, 'الطبيب'),
          h('select', {
            className: 'select mb-16',
            value: doctorId,
            onChange: (e) => setDoctorId(e.target.value),
          },
            h('option', { value: '' }, allDoctors.length ? '— اختر الطبيب —' : 'لا يوجد أطباء مضافين'),
            allDoctors.map(d => h('option', { key: d.id || d.name, value: String(d.id || '') }, `${d.name}${d.specialty ? ' — ' + d.specialty : ''}`)),
          ),
          h('div', { className: 'label' }, 'البنود'),
          h('div', { className: 'card', style: { overflow: 'hidden', marginBottom: 8 } },
            h('table', { className: 'data-table', style: { fontSize: 13 } },
              h('thead', null, h('tr', null, ['الإجراء', 'الكمية', 'السعر', 'الإجمالي', ''].map((t, i) => h('th', { key: i }, t)))),
              h('tbody', null,
                items.map(it => h('tr', { key: it.id },
                  h('td', null,
                    h('select', {
                      className: 'select',
                      style: { padding: '5px 8px', fontSize: 12 },
                      value: it.service_id || '',
                      onChange: e => {
                        const svc = allSvcs.find(s => s.id === e.target.value);
                        if (svc) setItems(prev => prev.map(i => i.id === it.id ? { ...i, service_id: svc.id, name: svc.name, price: svc.price } : i));
                        else setItems(prev => prev.map(i => i.id === it.id ? { ...i, service_id: null } : i));
                      },
                    },
                      h('option', { value: '' }, it.name || '— اختر خدمة —'),
                      allSvcs.map(s => h('option', { key: s.id, value: s.id }, s.name + ' · ' + window.fmtEGP(s.price))),
                    ),
                  ),
                  h('td', { style: { width: 70 } }, h('input', { className: 'input', type: 'number', style: { padding: 6, fontSize: 13 }, value: it.qty, onChange: (e) => updateItem(it.id, 'qty', +e.target.value) })),
                  h('td', { style: { width: 100 } }, h('input', { className: 'input', type: 'number', style: { padding: 6, fontSize: 13 }, value: it.price, onChange: (e) => updateItem(it.id, 'price', +e.target.value) })),
                  h('td', { style: { fontWeight: 700, width: 100 } }, window.fmtEGP(it.qty * it.price)),
                  h('td', { style: { width: 40 } }, h('button', { className: 'icon-btn', onClick: () => removeItem(it.id) }, h(Icons.Trash, { size: 14 }))),
                )),
              ),
            ),
          ),
          h('button', { className: 'btn outline sm', onClick: addItem }, h(Icons.Plus, { size: 14 }), 'إضافة بند'),
          h('div', { className: 'mt-16' },
            h('div', { className: 'label' }, 'ملاحظات'),
            h('textarea', { className: 'textarea', rows: 2, placeholder: 'أي ملاحظات على الفاتورة...' }),
          ),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 16 } }, 'الملخص'),
          h('div', { style: { display: 'flex', flexDirection: 'column', gap: 10 } },
            h('div', { className: 'flex jc-sb', style: { fontSize: 13 } },
              h('span', { style: { color: 'var(--text-tertiary)' } }, 'إجمالي الخدمات'), h('span', { style: { fontWeight: 600 } }, window.fmtEGP(subtotal)),
            ),
            h('div', { className: 'flex jc-sb ai-c' },
              h('span', { style: { fontSize: 13, color: 'var(--text-tertiary)' } }, 'الخصم'),
              h('input', { type: 'number', className: 'input', style: { width: 90, padding: 6, fontSize: 13 }, value: discount, onChange: (e) => setDiscount(+e.target.value) }),
            ),
            h('div', { className: 'flex jc-sb', style: { fontSize: 13, color: 'var(--danger)' } },
              h('span', null, 'قيمة الخصم'), h('span', null, '- ' + window.fmtEGP(discountAmt)),
            ),
            h('div', { className: 'divider' }),
            h('div', { className: 'flex jc-sb', style: { fontSize: 20, fontWeight: 800 } },
              h('span', null, 'الإجمالي النهائي'), h('span', { style: { color: 'var(--accent)' } }, window.fmtEGP(total)),
            ),
          ),
          h('div', { className: 'label mt-16' }, 'طريقة الدفع'),
          h('div', { className: 'grid cols-2', style: { gap: 6 } },
            ['نقدي', 'فيزا', 'تحويل', 'تأمين'].map(m => h('button', {
              key: m,
              className: 'btn sm ' + (payMethod === m ? 'primary' : 'outline'),
              onClick: () => setPayMethod(m),
            }, m)),
          ),
        ),
      ),
    ),
  );
}

// ==================== Treatments (plans) ====================
function Treatments() {
  const { setScreen } = useContext(AppContext);
  const plans = [
    { id: 'TP1', patient: 'أحمد محمد السيد', doctor: 'د. سارة', status: 'جارية', progress: 60, procedures: 6, startDate: '2026-02-15', total: 8500, paid: 5000 },
    { id: 'TP2', patient: 'فاطمة علي حسن', doctor: 'د. منى', status: 'جارية', progress: 35, procedures: 18, startDate: '2026-01-10', total: 35000, paid: 12000 },
    { id: 'TP3', patient: 'محمد عبد الرحمن', doctor: 'د. سارة', status: 'جارية', progress: 85, procedures: 4, startDate: '2026-03-20', total: 4500, paid: 1100 },
    { id: 'TP4', patient: 'رنا أشرف', doctor: 'د. منى', status: 'مسودة', progress: 0, procedures: 8, startDate: '2026-04-18', total: 12000, paid: 0 },
    { id: 'TP5', patient: 'سلمى حسام', doctor: 'د. خالد', status: 'مكتملة', progress: 100, procedures: 3, startDate: '2025-11-15', total: 6000, paid: 6000 },
  ];

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'خطط العلاج'),
        h('div', { className: 'page-subtitle' }, `${plans.filter(p => p.status === 'جارية').length} خطة جارية · ${plans.length} خطة إجمالاً`),
      ),
      h('div', { className: 'flex gap-8' },
        h('button', { className: 'btn primary', onClick: () => setScreen('new-invoice') }, h(Icons.Plus, { size: 16 }), 'فاتورة/خطة جديدة'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'grid', style: { gap: 12 } },
        plans.map(p => h('div', { key: p.id, className: 'card p-20', style: { cursor: 'pointer' }, onClick: () => setScreen('billing') },
          h('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 1.5fr 80px', gap: 20, alignItems: 'center' } },
            h('div', null,
              h('div', { style: { fontWeight: 800, fontSize: 15 } }, p.patient),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 } }, `${p.id} · ${p.doctor} · ${p.procedures} إجراءات`),
            ),
            h('div', null,
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'التاريخ'),
              h('div', { style: { fontSize: 13, fontWeight: 600, marginTop: 2 } }, p.startDate),
            ),
            h('div', null,
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'الإجمالي'),
              h('div', { style: { fontSize: 14, fontWeight: 800, marginTop: 2 } }, window.fmtEGP(p.total)),
              h('div', { style: { fontSize: 11, color: 'var(--success)' } }, 'مدفوع: ' + window.fmtEGP(p.paid)),
            ),
            h('div', null,
              h('div', { className: 'flex jc-sb ai-c mb-4' },
                h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'التقدم'),
                h('span', { style: { fontSize: 12, fontWeight: 700 } }, p.progress + '%'),
              ),
              h('div', { className: 'progress' },
                h('div', { className: 'progress-bar', style: { width: p.progress + '%', background: p.status === 'مكتملة' ? 'var(--success)' : 'var(--accent)' } }),
              ),
            ),
            h('span', { className: 'chip ' + (p.status === 'مكتملة' ? 'success' : p.status === 'جارية' ? 'info' : '') }, p.status),
          ),
        )),
      ),
    ),
  );
}

// ==================== Print Invoice ====================
function printInvoice(inv, clinicName) {
  const statusLabel = { paid:'مدفوعة', partial:'جزئية', unpaid:'غير مدفوعة' };
  const invId = typeof inv.id === 'string' && inv.id.startsWith('INV') ? inv.id : 'INV-' + String(inv.id).slice(-6);
  const rows = (inv.items || []).map(it =>
    `<tr><td>${it.name}</td><td style="text-align:center">${it.qty}</td><td style="text-align:left">${window.fmtEGP(it.price)}</td><td style="text-align:left">${window.fmtEGP(it.qty*it.price - (it.discount||0))}</td></tr>`
  ).join('');

  const html = `<!DOCTYPE html><html dir="rtl" lang="ar">
<head><meta charset="UTF-8"><title>فاتورة ${invId}</title>
<style>
  body{font-family:Arial,sans-serif;font-size:13px;color:#222;margin:0;padding:32px;direction:rtl}
  .header{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:2px solid #0891b2;padding-bottom:16px;margin-bottom:20px}
  .clinic-name{font-size:22px;font-weight:900;color:#0891b2}
  .inv-meta{text-align:left;font-size:12px;color:#555}
  .inv-id{font-size:18px;font-weight:700;color:#333}
  table{width:100%;border-collapse:collapse;margin-bottom:20px}
  th{background:#0891b2;color:#fff;padding:8px 10px;text-align:right;font-size:12px}
  td{padding:7px 10px;border-bottom:1px solid #eee;font-size:12px}
  tr:nth-child(even) td{background:#f8fafb}
  .totals{float:left;min-width:220px}
  .totals table td{border:none;padding:4px 8px}
  .grand-total td{font-size:16px;font-weight:900;color:#0891b2;border-top:2px solid #0891b2}
  .status-chip{display:inline-block;padding:3px 12px;border-radius:999px;font-size:11px;font-weight:700;
    background:${inv.status==='paid'?'#d1fae5':inv.status==='partial'?'#fef3c7':'#fee2e2'};
    color:${inv.status==='paid'?'#065f46':inv.status==='partial'?'#92400e':'#991b1b'}}
  .footer{margin-top:40px;border-top:1px solid #eee;padding-top:12px;font-size:11px;color:#999;text-align:center}
  @media print{body{padding:16px} button{display:none}}
</style></head>
<body>
<div class="header">
  <div>
    <div class="clinic-name">${clinicName || 'سِنان كلينيك'}</div>
    <div style="font-size:12px;color:#666;margin-top:4px">عيادة أسنان متكاملة</div>
  </div>
  <div class="inv-meta">
    <div class="inv-id">${invId}</div>
    <div>التاريخ: ${inv.date || '—'}</div>
    <div>المريض: <strong>${inv.patient || '—'}</strong></div>
    <div>الطبيب: <strong>${inv.doctorName || '—'}</strong></div>
    <div style="margin-top:6px"><span class="status-chip">${statusLabel[inv.status]||'—'}</span></div>
  </div>
</div>

<table>
  <thead><tr><th>الخدمة / الإجراء</th><th style="text-align:center">الكمية</th><th style="text-align:left">سعر الوحدة</th><th style="text-align:left">الإجمالي</th></tr></thead>
  <tbody>${rows || '<tr><td colspan="4" style="text-align:center;color:#999">لا توجد بنود</td></tr>'}</tbody>
</table>

<div class="totals">
  <table>
    <tr><td>الإجمالي:</td><td><strong>${window.fmtEGP(inv.total)}</strong></td></tr>
    <tr><td>المدفوع:</td><td style="color:#059669"><strong>${window.fmtEGP(inv.paid)}</strong></td></tr>
    <tr class="grand-total"><td>المتبقي:</td><td>${window.fmtEGP(inv.total - inv.paid)}</td></tr>
  </table>
</div>
<div style="clear:both"></div>

<div class="footer">
  شكراً لثقتكم • ${clinicName || 'سِنان كلينيك'} • تم إنشاء هذه الفاتورة إلكترونياً
</div>
</body></html>`;
  const iframe = document.createElement('iframe');
  iframe.style.position = 'fixed';
  iframe.style.right = '0';
  iframe.style.bottom = '0';
  iframe.style.width = '0';
  iframe.style.height = '0';
  iframe.style.border = '0';
  iframe.style.opacity = '0';
  iframe.setAttribute('aria-hidden', 'true');
  const cleanup = () => setTimeout(() => iframe.remove(), 100);
  iframe.onload = () => {
    const win = iframe.contentWindow;
    const doc = iframe.contentDocument;
    if (!win || !doc) {
      cleanup();
      return;
    }
    try {
      doc.open();
      doc.write(html);
      doc.close();
    } catch (error) {
      console.warn('[InvoicePrint] write failed:', error);
      cleanup();
      return;
    }
    let printed = false;
    const triggerPrint = () => {
      if (printed) return;
      printed = true;
      try {
        win.focus();
        win.print();
      } catch (error) {
        console.warn('[InvoicePrint] print failed:', error);
        cleanup();
      }
    };
    win.onafterprint = cleanup;
    setTimeout(triggerPrint, 250);
    setTimeout(() => { if (!printed) cleanup(); }, 5000);
  };
  document.body.appendChild(iframe);
  iframe.src = 'about:blank';
}

// ==================== Add Service Modal ====================
function AddServiceModal({ onClose, onSaved }) {
  const { clinicId, toast } = useContext(AppContext);
  const [form, setForm] = useState({ name: '', price: '', duration: 30, category: '' });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSave = async () => {
    if (!form.name.trim()) { toast('اسم الخدمة مطلوب'); return; }
    if (!form.price || +form.price <= 0) { toast('السعر مطلوب'); return; }
    setSaving(true);
    try {
      const svc = await DB.addService(clinicId, {
        name: form.name.trim(),
        price: +form.price,
        duration: +form.duration || 30,
        category: form.category.trim() || 'عام',
      });
      toast('تم إضافة الخدمة ✅');
      onSaved(svc);
      onClose();
    } catch(e) { toast('خطأ: ' + (e.message || 'غير متوقع')); }
    finally { setSaving(false); }
  };

  const categories = ['فحص وتشخيص', 'تنظيف', 'حشو', 'علاج عصب', 'خلع', 'تركيبات', 'تقويم', 'تجميل', 'جراحة', 'أشعة', 'عام'];

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:300 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:24,width:440,zIndex:301,boxShadow:'var(--shadow-lg)' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', { style:{fontWeight:800,fontSize:17} }, 'إضافة خدمة جديدة'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gap:14} },
        h('div', null,
          h('div', { className:'label' }, 'اسم الخدمة *'),
          h('input', { className:'input', placeholder:'حشو عصب، تاج زيركون...', value:form.name, onChange:e=>set('name',e.target.value) }),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null,
            h('div', { className:'label' }, 'السعر (ج.م) *'),
            h('input', { className:'input', type:'number', min:0, placeholder:'500', value:form.price, onChange:e=>set('price',e.target.value) }),
          ),
          h('div', null,
            h('div', { className:'label' }, 'المدة (دقيقة)'),
            h('input', { className:'input', type:'number', min:5, value:form.duration, onChange:e=>set('duration',e.target.value) }),
          ),
        ),
        h('div', null,
          h('div', { className:'label' }, 'الفئة'),
          h('select', { className:'select', value:form.category, onChange:e=>set('category',e.target.value) },
            h('option', { value:'' }, '— اختر فئة —'),
            categories.map(c => h('option', { key:c, value:c }, c)),
          ),
        ),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-20' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave },
          saving ? 'جاري الحفظ...' : 'إضافة الخدمة'),
      ),
    ),
  );
}

// ==================== Add Inventory Modal ====================
function AddInventoryModal({ onClose, onSaved }) {
  const { clinicId, toast } = useContext(AppContext);
  const [form, setForm] = useState({ name: '', category: '', stock: '', minStock: '', unit: 'قطعة', price: '', usageUnitsPerPack: '', expiry: '' });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSave = async () => {
    if (!form.name.trim()) { toast('اسم الصنف مطلوب'); return; }
    setSaving(true);
    try {
      const item = await DB.addInventoryItem(clinicId, {
        name: form.name.trim(),
        category: form.category.trim() || 'عام',
        stock: +form.stock || 0,
        min_stock: +form.minStock || 0,
        unit: form.unit || 'قطعة',
        price: +form.price || 0,
        supplier: null,
        expiry: form.expiry || null,
      });
      toast('تم إضافة الصنف ✅');
      onSaved(item, Math.max(0, Number(form.usageUnitsPerPack) || 0));
      onClose();
    } catch(e) { toast('خطأ: ' + (e.message || 'غير متوقع')); }
    finally { setSaving(false); }
  };

  const invCategories = ['مواد حشو', 'مواد تنظيف', 'أدوات', 'مواد أشعة', 'تركيبات', 'مواد تخدير', 'قفازات ومستلزمات', 'أدوية', 'عام'];
  const units = ['قطعة', 'علبة', 'زجاجة', 'كيس', 'كرتون', 'أمبول', 'لفة', 'كبسولة', 'مل', 'جرام'];

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:300 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:24,width:500,zIndex:301,boxShadow:'var(--shadow-lg)',maxHeight:'90vh',overflowY:'auto' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', { style:{fontWeight:800,fontSize:17} }, 'إضافة صنف جديد'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gap:12} },
        h('div', null,
          h('div', { className:'label' }, 'اسم الصنف *'),
          h('input', { className:'input', placeholder:'مثال: كومبوزيت A2، قفازات S...', value:form.name, onChange:e=>set('name',e.target.value) }),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null,
            h('div', { className:'label' }, 'الفئة'),
            h('select', { className:'select', value:form.category, onChange:e=>set('category',e.target.value) },
              h('option', { value:'' }, '— اختر —'),
              invCategories.map(c => h('option', { key:c, value:c }, c)),
            ),
          ),
          h('div', null,
            h('div', { className:'label' }, 'وحدة القياس'),
            h('select', { className:'select', value:form.unit, onChange:e=>set('unit',e.target.value) },
              units.map(u => h('option', { key:u, value:u }, u)),
            ),
          ),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:12} },
          h('div', null, h('div', { className:'label' }, 'الكمية الحالية'), h('input', { className:'input', type:'number', min:0, value:form.stock, onChange:e=>set('stock',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'الحد الأدنى'), h('input', { className:'input', type:'number', min:0, value:form.minStock, onChange:e=>set('minStock',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'السعر (ج.م)'), h('input', { className:'input', type:'number', min:0, value:form.price, onChange:e=>set('price',e.target.value) })),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null, h('div', { className:'label' }, 'عدد وحدات الاستخدام داخل العبوة'), h('input', { className:'input', type:'number', min:0, placeholder:'مثال: 18', value:form.usageUnitsPerPack, onChange:e=>set('usageUnitsPerPack',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'تاريخ الصلاحية (اختياري)'), h('input', { className:'input', type:'date', value:form.expiry, onChange:e=>set('expiry',e.target.value) })),
        ),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-20' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave },
          saving ? 'جاري الحفظ...' : 'إضافة الصنف'),
      ),
    ),
  );
}

// ==================== Edit Inventory Modal ====================
function EditInventoryModal({ item, onClose, onSaved }) {
  const { toast } = useContext(AppContext);
  const normalizeDateValue = (value) => (/^\d{4}-\d{2}-\d{2}$/.test(String(value || '').trim()) ? String(value).trim() : '');
  const [form, setForm] = useState({
    name: item.name || '',
    category: item.category || '',
    stock: item.stock ?? '',
    minStock: item.minStock ?? '',
    unit: item.unit || 'قطعة',
    price: item.price ?? '',
    usageUnitsPerPack: item.usageUnitsPerPack ?? '',
    expiry: normalizeDateValue(item.expiry),
  });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const invCategories = ['مواد حشو', 'مواد تنظيف', 'أدوات', 'مواد أشعة', 'تركيبات', 'مواد تخدير', 'قفازات ومستلزمات', 'أدوية', 'عام'];
  const units = ['قطعة', 'علبة', 'زجاجة', 'كيس', 'كرتون', 'أمبول', 'لفة', 'كبسولة', 'مل', 'جرام'];

  const handleSave = async () => {
    if (!form.name.trim()) { toast('اسم الصنف مطلوب'); return; }
    setSaving(true);
    try {
      const updated = await DB.updateInventoryItem(item.id, {
        name: form.name.trim(),
        category: form.category.trim() || 'عام',
        stock: +form.stock || 0,
        min_stock: +form.minStock || 0,
        unit: form.unit || 'قطعة',
        price: +form.price || 0,
        expiry: normalizeDateValue(form.expiry) || null,
      });
      toast('تم تحديث الصنف ✅');
      onSaved(updated, Math.max(0, Number(form.usageUnitsPerPack) || 0));
      onClose();
    } catch (e) {
      toast('خطأ: ' + (e.message || 'غير متوقع'));
    } finally {
      setSaving(false);
    }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed', inset:0, background:'rgba(0,0,0,0.4)', zIndex:300 } }),
    h('div', { style: { position:'fixed', top:'50%', left:'50%', transform:'translate(-50%,-50%)', background:'var(--bg-elevated)', borderRadius:'var(--radius-lg)', padding:24, width:500, zIndex:301, boxShadow:'var(--shadow-lg)', maxHeight:'90vh', overflowY:'auto' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', { style:{fontWeight:800,fontSize:17} }, 'تعديل صنف'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gap:12} },
        h('div', null,
          h('div', { className:'label' }, 'اسم الصنف *'),
          h('input', { className:'input', value:form.name, onChange:e=>set('name',e.target.value) }),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null,
            h('div', { className:'label' }, 'الفئة'),
            h('select', { className:'select', value:form.category, onChange:e=>set('category',e.target.value) },
              h('option', { value:'' }, '— اختر —'),
              invCategories.map(c => h('option', { key:c, value:c }, c)),
            ),
          ),
          h('div', null,
            h('div', { className:'label' }, 'وحدة القياس'),
            h('select', { className:'select', value:form.unit, onChange:e=>set('unit',e.target.value) },
              units.map(u => h('option', { key:u, value:u }, u)),
            ),
          ),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:12} },
          h('div', null, h('div', { className:'label' }, 'الكمية الحالية'), h('input', { className:'input', type:'number', min:0, value:form.stock, onChange:e=>set('stock',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'الحد الأدنى'), h('input', { className:'input', type:'number', min:0, value:form.minStock, onChange:e=>set('minStock',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'السعر (ج.م)'), h('input', { className:'input', type:'number', min:0, value:form.price, onChange:e=>set('price',e.target.value) })),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null, h('div', { className:'label' }, 'عدد وحدات الاستخدام داخل العبوة'), h('input', { className:'input', type:'number', min:0, value:form.usageUnitsPerPack, onChange:e=>set('usageUnitsPerPack',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'تاريخ الصلاحية (اختياري)'), h('input', { className:'input', type:'date', value:form.expiry, onChange:e=>set('expiry',e.target.value) })),
        ),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-20' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave }, saving ? 'جاري الحفظ...' : 'حفظ التعديل'),
      ),
    ),
  );
}

// ==================== Bulk Edit Inventory Modal ====================
function BulkEditInventoryModal({ count, onClose, onSaved }) {
  const { toast } = useContext(AppContext);
  const [form, setForm] = useState({ category: '', minStock: '', price: '', expiry: '' });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const invCategories = ['مواد حشو', 'مواد تنظيف', 'أدوات', 'مواد أشعة', 'تركيبات', 'مواد تخدير', 'قفازات ومستلزمات', 'أدوية', 'عام'];

  const handleSave = async () => {
    const payload = {};
    if (form.category.trim()) payload.category = form.category.trim();
    if (String(form.minStock).trim() !== '') payload.min_stock = +form.minStock || 0;
    if (String(form.price).trim() !== '') payload.price = +form.price || 0;
    if (form.expiry) payload.expiry = form.expiry;
    if (!Object.keys(payload).length) {
      toast('املأ حقلًا واحدًا على الأقل للتعديل الجماعي');
      return;
    }
    setSaving(true);
    try {
      await onSaved(payload);
      onClose();
    } catch (e) {
      toast('خطأ: ' + (e.message || 'تعذر التعديل الجماعي'));
    } finally {
      setSaving(false);
    }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed', inset:0, background:'rgba(0,0,0,0.4)', zIndex:300 } }),
    h('div', { style: { position:'fixed', top:'50%', left:'50%', transform:'translate(-50%,-50%)', background:'var(--bg-elevated)', borderRadius:'var(--radius-lg)', padding:24, width:460, zIndex:301, boxShadow:'var(--shadow-lg)' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', null,
          h('div', { style:{fontWeight:800,fontSize:17} }, 'تعديل المحدد'),
          h('div', { style:{fontSize:12,color:'var(--text-tertiary)',marginTop:4} }, `سيتم تعديل ${count} صنف. الحقول المعبأة فقط هي التي ستتغير.`),
        ),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gap:12} },
        h('div', null,
          h('div', { className:'label' }, 'الفئة'),
          h('select', { className:'select', value:form.category, onChange:e=>set('category',e.target.value) },
            h('option', { value:'' }, 'اتركها كما هي'),
            invCategories.map(c => h('option', { key:c, value:c }, c)),
          ),
        ),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null, h('div', { className:'label' }, 'الحد الأدنى'), h('input', { className:'input', type:'number', min:0, placeholder:'اتركه كما هو', value:form.minStock, onChange:e=>set('minStock',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'السعر'), h('input', { className:'input', type:'number', min:0, placeholder:'اتركه كما هو', value:form.price, onChange:e=>set('price',e.target.value) })),
        ),
        h('div', null, h('div', { className:'label' }, 'الصلاحية'), h('input', { className:'input', type:'date', value:form.expiry, onChange:e=>set('expiry',e.target.value) })),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-20' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave }, saving ? 'جاري التعديل...' : 'حفظ التعديل الجماعي'),
      ),
    ),
  );
}

// ==================== BOM Modal ====================
function BomModal({ service, onClose }) {
  const { clinicId, inventory, toast } = useContext(AppContext);
  const allInv = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
  const [usageUnitsMap, setUsageUnitsMap] = useState({});
  const [bom, setBom] = useState([]);
  const [loading, setLoading] = useState(true);
  const [selInvId, setSelInvId] = useState('');
  const [qty, setQty] = useState(1);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    setUsageUnitsMap(loadInventoryUsageUnitsMap(clinicId));
  }, [clinicId]);

  useEffect(() => {
    DB.getBomForService(service.id)
      .then(setBom)
      .catch(console.error)
      .finally(() => setLoading(false));
  }, [service.id]);

  const handleAdd = async () => {
    if (!selInvId) { toast('اختر مادة أولاً'); return; }
    setSaving(true);
    try {
      const item = await DB.addBomItem(clinicId, service.id, selInvId, qty);
      setBom(prev => [...prev, item]);
      setSelInvId(''); setQty(1);
      toast('تم الإضافة ✅');
    } catch(e) { toast('خطأ: ' + (e.message || 'غير متوقع')); }
    finally { setSaving(false); }
  };

  const handleDelete = async (id) => {
    if (!confirm('حذف هذا المكوّن؟')) return;
    try {
      await DB.deleteBomItem(id);
      setBom(prev => prev.filter(b => b.id !== id));
      toast('تم الحذف');
    } catch(e) { toast('خطأ في الحذف'); }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:300 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:24,width:500,zIndex:301,boxShadow:'var(--shadow-lg)',maxHeight:'80vh',display:'flex',flexDirection:'column' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16} },
        h('div', null,
          h('div', { style:{fontWeight:800,fontSize:16} }, 'مكونات الخدمة (BOM)'),
          h('div', { style:{fontSize:13,color:'var(--text-tertiary)',marginTop:2} }, service.name + ' · ' + window.fmtEGP(service.price)),
        ),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gridTemplateColumns:'1fr 80px auto',gap:8,marginBottom:16,alignItems:'end'} },
        h('div', null,
          h('div', { className:'label' }, 'المادة من المخزون'),
          h('select', { className:'select', value:selInvId, onChange:e=>setSelInvId(e.target.value) },
            h('option', { value:'' }, '— اختر مادة —'),
            allInv.map(i => h('option', { key:i.id, value:i.id }, `${i.name} (${window.fmtNum(i.stock)} ${i.unit})`)),
          ),
        ),
        h('div', null,
          h('div', { className:'label' }, 'الكمية'),
          h('input', { className:'input', type:'number', min:0.1, step:0.1, value:qty, onChange:e=>setQty(+e.target.value) }),
        ),
        h('button', { className:'btn primary', disabled:saving||!selInvId, onClick:handleAdd, style:{marginTop:'auto'} },
          saving ? '...' : h(Icons.Plus, {size:16}),
        ),
      ),
      h('div', { style:{flex:1,overflowY:'auto'} },
        loading ? h('div', { style:{textAlign:'center',padding:24,color:'var(--text-tertiary)'} }, 'جاري التحميل...') :
        bom.length === 0 ? h('div', { style:{textAlign:'center',padding:32,color:'var(--text-tertiary)',border:'2px dashed var(--border)',borderRadius:'var(--radius)'} },
          h('div', null, '📦'),
          h('div', { style:{marginTop:8} }, 'لا توجد مكونات — أضف أول مادة من المخزون'),
        ) :
        h('div', { style:{display:'flex',flexDirection:'column',gap:6} },
          bom.map(b => {
            const invItem = allInv.find(i => i.id === b.inventoryId);
            const unitPrice = invItem ? getInventoryMeasureUnitPrice(invItem, usageUnitsMap) : 0;
            const itemCost = unitPrice * (Number(b.standardQty) || 0);
            return h('div', { key:b.id, style:{display:'flex',justifyContent:'space-between',alignItems:'center',padding:'10px 14px',border:'1px solid var(--border)',borderRadius:'var(--radius)'} },
              h('div', null,
                h('div', { style:{fontWeight:700,fontSize:13} }, b.itemName),
                h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:2} }, `الكمية المعيارية: ${b.standardQty} ${b.unit}`),
                h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:2} }, `سعر وحدة القياس: ${window.fmtEGP(unitPrice)} · التكلفة: ${window.fmtEGP(itemCost)}`),
              ),
              h('button', { className:'icon-btn', style:{color:'var(--danger)'}, onClick:()=>handleDelete(b.id) },
                h(Icons.Trash, {size:13}),
              ),
            );
          }),
        ),
      ),
    ),
  );
}

// ==================== Edit Service Modal ====================
function EditServiceModal({ service, onClose, onSaved }) {
  const { toast } = useContext(AppContext);
  const [form, setForm] = useState({ name: service.name, price: service.price, duration: service.duration, category: service.category });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSave = async () => {
    setSaving(true);
    try {
      const { data, error } = await SB.from('services')
        .update({ name: form.name, price: +form.price, duration: +form.duration, category: form.category })
        .eq('id', service.id).select().single();
      if (error) throw error;
      toast('تم حفظ الخدمة ✅');
      onSaved({ ...service, ...form, price: +form.price, duration: +form.duration });
      onClose();
    } catch(e) { toast('خطأ: ' + (e.message || 'غير متوقع')); }
    finally { setSaving(false); }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:300 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:24,width:420,zIndex:301,boxShadow:'var(--shadow-lg)' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', { style:{fontWeight:800,fontSize:16} }, 'تعديل الخدمة'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gap:12} },
        h('div', null, h('div', { className:'label' }, 'اسم الخدمة'),
          h('input', { className:'input', value:form.name, onChange:e=>set('name',e.target.value) })),
        h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:12} },
          h('div', null, h('div', { className:'label' }, 'السعر (ج.م)'),
            h('input', { className:'input', type:'number', value:form.price, onChange:e=>set('price',e.target.value) })),
          h('div', null, h('div', { className:'label' }, 'المدة (دقيقة)'),
            h('input', { className:'input', type:'number', value:form.duration, onChange:e=>set('duration',e.target.value) })),
        ),
        h('div', null, h('div', { className:'label' }, 'الفئة'),
          h('input', { className:'input', value:form.category, onChange:e=>set('category',e.target.value) })),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-20' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave },
          saving ? 'جاري الحفظ...' : 'حفظ التغييرات'),
      ),
    ),
  );
}

// ═══════════════════════════════════════════════════════
// بيانات المخزون ومكونات الخدمات من Alpha Clinic System
// ═══════════════════════════════════════════════════════
const _INV=[{name:"الفيو جيل",price:10.0,stock:10,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"باند - سادل",price:20.0,stock:20,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"باند - سيكشنال",price:35.0,stock:35,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير -فيشر",price:12.0,stock:12,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"جلاس ايونمر فيلنج - ٢٠ حالة",price:5.0,stock:5,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"صوديوم هيبو كلورايد",price:1.0,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ميتا بيست - ١٧ حالة",price:37.0,stock:37,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ميتا بيكس - ١٠ حالات",price:55.0,stock:55,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"MTA - 0.125 g",price:32.5,stock:32,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ألجينيت -18 حالة",price:27.0,stock:27,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"أمالجم",price:40.0,stock:40,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"اتش - etch - ٢٠ حالة",price:5.0,stock:5,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"اكياس تعقيم",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"اوفر جلافز",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ايدتا جيل - EDTA - ٣٠ حالة",price:3.0,stock:3,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"باند معدن",price:1.5,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بنج موضعى - 100 حالة",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بوست معدن",price:9.0,stock:9,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بوند - One Coat - 100 حالة",price:25.0,stock:25,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بوند cotelene - 100 حالة",price:7.0,stock:7,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بيبر بوينت",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير - TF",price:12.0,stock:12,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير - اندوزى -Endo z",price:40.0,stock:40,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير - جراحى",price:100.0,stock:100,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير - راوند",price:12.0,stock:12,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير - فليم -flame",price:12.0,stock:12,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بير - فوتبول",price:12.0,stock:12,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"بيزو ريمير - Peeso Reamer",price:55.0,stock:55,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"تبات شارم كور",price:15.0,stock:15,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"تبات للهواء والمياة - Air Tip",price:1.0,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"تراى",price:15.0,stock:12,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"تيفلون - ٤٠ حالة",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ثيراكال - ٥٠ حالة",price:20.0,stock:20,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"جاتابيركا تيبر ٤",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"جاتبيركا تيبر 6",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"جاتيبركا تيبر 2",price:1.0,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"جوانتى جلافز",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"حافظ مكان للاطفال - معمل",price:250.0,stock:250,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"حشو مؤقت - 100 حالة",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"خيط جراحى",price:17.0,stock:17,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"خيط فلوص - floss - ١٠٠ مريض",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ديسك فينشنج وبولشينج",price:13.0,stock:13,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"رابر بيس - مقاس - باتى - 30 حالة",price:35.0,stock:35,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"رابر بيس - مقاس - لايت ١٥ حالة",price:35.0,stock:35,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"رابر دام",price:9.0,stock:9,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ريتراكشن كورد - ٤٠ حالة",price:2.5,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"زنك اوكسايد - ٣٥ حالة",price:15.0,stock:15,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ساكشن شفاط",price:1.5,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"سالاين -saline ٢٥ حالة",price:1.0,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"سبريدر - spreader",price:25.0,stock:25,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ستريب - بوليشنج",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ستناليس كراون",price:70.0,stock:70,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ستون - فينشنج وبولشينج",price:25.0,stock:25,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"سرنجات بلاستيك",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"سن بنج",price:2.0,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"سنون ايريجشن",price:6.5,stock:6,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"سيلر - 50 حالة",price:25.0,stock:25,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"شارم كور كمبوزيت - 10 حالات",price:75.0,stock:76,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"شاش - ١٠٠ حالة",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايبر بوست",price:5.0,stock:5,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل روتارى - أوبنر",price:75.0,stock:75,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل روتارى مقاس ١٥",price:75.0,stock:75,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل روتارى مقاس ٢٠",price:75.0,stock:75,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل روتارى مقاس ٢٥",price:75.0,stock:75,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل روتارى مقاس ٣٠",price:75.0,stock:75,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل مانوال مقاس ٢٠",price:40.0,stock:40,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل مانوال مقاس ١٠",price:40.0,stock:40,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل مانوال مقاس ١٥",price:40.0,stock:40,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فايل مانوال مقاس ٨",price:40.0,stock:40,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فرش تلميع وبوليشنغ",price:5.5,stock:5,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فرشة بوند",price:1.0,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"فورماكريزول - ٤٠٠ حالة",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"قطن - ١٠٠ حالة",price:1.0,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"قطن رول",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كبموزيت - Capo - 20 حالة",price:35.0,stock:35,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كبموزيت - Ruby - 10 حالات",price:16.0,stock:16,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كراون - معمل",price:350.0,stock:350,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كربولة بنج",price:20.0,stock:20,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كلوروهيكسدين جيل - ١٥ حالةً",price:6.5,stock:6,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كمبوزيت Ruby - 20 حالات",price:16.0,stock:16,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كمبوزيت Z-Fill - ١٥ حالة",price:50.0,stock:50,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كمبوزيت فلوبال - flowable - ٢٠ حالة",price:15.0,stock:15,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"كوبايات",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"لزق - سيمنت - ٤٠ حالة",price:2.5,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ماسك للوجه",price:1.5,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"مشرط",price:10.0,stock:10,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"مضاد حساسية - desensitizer - ١٠ حالات",price:5.0,stock:5,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"معجون تلميع وبوليشنغ - ٤٠ حالة",price:2.5,stock:2,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"مفرش ألوان",price:1.0,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"مفرش شفاف",price:0.5,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"مناديل",price:1.0,stock:0,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"هيمو ستوب - hemostop - ٣٠ حالة",price:3.0,stock:3,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"واكس - شمع 50 حالة",price:4.0,stock:4,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ورق كربون",price:1.5,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5},{name:"ويدج",price:1.5,stock:1,unit:"قطعة",category:"مستلزمات طبية",minStock:5}];
const _BOM={"كشف":[["جوانتى جلافز",2],["مفرش شفاف",1],["ماسك للوجه",1],["كوبايات",1],["تبات للهواء والمياة - Air Tip",1],["اكياس تعقيم",2],["اوفر جلافز",3],["خيط فلوص - floss - ١٠٠ مريض",1],["قطن - ١٠٠ حالة",1]],"خلع عادي":[["الفيو جيل",1],["اكياس تعقيم",4],["اوفر جلافز",3],["بنج موضعى - 100 حالة",1],["تبات للهواء والمياة - Air Tip",1],["جوانتى جلافز",2],["سرنجات بلاستيك",1],["سن بنج",1],["قطن - ١٠٠ حالة",2],["قطن رول",2],["كربولة بنج",2],["مفرش ألوان",1],["ماسك للوجه",1],["كوبايات",2],["مفرش شفاف",1],["مناديل",2]],"خلع عادي اطفال":[["اكياس تعقيم",4],["اوفر جلافز",3],["بنج موضعى - 100 حالة",1],["تبات للهواء والمياة - Air Tip",1],["جوانتى جلافز",2],["سرنجات بلاستيك",1],["سن بنج",1],["قطن - ١٠٠ حالة",2],["قطن رول",2],["كربولة بنج",1],["مفرش ألوان",1],["ماسك للوجه",1],["كوبايات",1],["مفرش شفاف",1],["مناديل",2]],"خلع جراحى سيباريشن":[["مفرش ألوان",1],["مفرش شفاف",1],["جوانتى جلافز",2],["اوفر جلافز",2],["ماسك للوجه",1],["كوبايات",1],["تبات للهواء والمياة - Air Tip",1],["سن بنج",1],["كربولة بنج",2],["بنج موضعى - 100 حالة",1],["اكياس تعقيم",4],["قطن - ١٠٠ حالة",2],["الفيو جيل",1],["سرنجات بلاستيك",1],["بير - جراحى",1]],"خلع جراحى امباكشن":[["مفرش شفاف",1],["مفرش ألوان",1],["الفيو جيل",1],["اكياس تعقيم",4],["اوفر جلافز",3],["تبات للهواء والمياة - Air Tip",1],["بير - جراحى",1],["بنج موضعى - 100 حالة",1],["جوانتى جلافز",2],["خيط جراحى",1],["سرنجات بلاستيك",1],["قطن - ١٠٠ حالة",2],["شاش - ١٠٠ حالة",1],["سن بنج",1],["كربولة بنج",2],["كوبايات",2],["ماسك للوجه",1],["مناديل",2],["مشرط",1]],"حشو كمبوزيت أمامي":[["مفرش شفاف",2],["مفرش ألوان",1],["جوانتى جلافز",4],["اوفر جلافز",5],["ماسك للوجه",1],["ساكشن شفاط",3],["كوبايات",2],["تبات للهواء والمياة - Air Tip",2],["سن بنج",2],["كربولة بنج",2],["بنج موضعى - 100 حالة",2],["كمبوزيت Z-Fill - ١٥ حالة",1],["بوند - One Coat - 100 حالة",1],["فرشة بوند",2],["اتش - etch - ٢٠ حالة",1],["كمبوزيت فلوبال - flowable - ٢٠ حالة",1],["ديسك فينشنج وبولشينج",1],["حشو مؤقت - 100 حالة",1],["اكياس تعقيم",6],["ورق كربون",1],["بير - TF",1],["قطن - ١٠٠ حالة",2],["قطن رول",2],["رابر دام",1],["ويدج",1],["مناديل",2],["تيفلون - ٤٠ حالة",1],["خيط فلوص - floss - ١٠٠ مريض",1]],"حشو كومبوزيت خلفى":[["مفرش ألوان",1],["مفرش شفاف",2],["جوانتى جلافز",4],["ماسك للوجه",1],["ساكشن شفاط",2],["كوبايات",2],["تبات للهواء والمياة - Air Tip",2],["سن بنج",2],["بنج موضعى - 100 حالة",2],["كربولة بنج",2],["كمبوزيت فلوبال - flowable - ٢٠ حالة",1],["كبموزيت - Capo - 20 حالة",1],["بوند - One Coat - 100 حالة",1],["اتش - etch - ٢٠ حالة",1],["باند - سادل",1],["ستون - فينشنج وبولشينج",1],["حشو مؤقت - 100 حالة",1],["اكياس تعقيم",6],["فرشة بوند",2],["ورق كربون",1],["اوفر جلافز",5],["رابر دام",1],["ويدج",1],["مناديل",1],["قطن - ١٠٠ حالة",2],["قطن رول",2],["تيفلون - ٤٠ حالة",1],["بير - TF",1],["ثيراكال - ٥٠ حالة",1]],"حشو عادى اطفال":[["أمالجم",1],["اكياس تعقيم",3],["اوفر جلافز",3],["باند معدن",1],["بنج موضعى - 100 حالة",1],["بير - راوند",1],["تبات للهواء والمياة - Air Tip",2],["جوانتى جلافز",2],["سن بنج",1],["ساكشن شفاط",2],["كوبايات",1],["كربولة بنج",1],["قطن رول",1],["قطن - ١٠٠ حالة",1],["ماسك للوجه",1],["مفرش ألوان",1],["مفرش شفاف",1],["مناديل",1],["ويدج",1]],"حشو عصب جزئى اطفال":[["مفرش ألوان",1],["مفرش شفاف",2],["مناديل",2],["ويدج",1],["ماسك للوجه",1],["كوبايات",2],["كربولة بنج",1],["قطن رول",2],["قطن - ١٠٠ حالة",2],["فورماكريزول - ٤٠٠ حالة",1],["سن بنج",1],["ساكشن شفاط",3],["جوانتى جلافز",4],["حشو مؤقت - 100 حالة",1],["زنك اوكسايد - ٣٥ حالة",1],["تبات للهواء والمياة - Air Tip",2],["بير - TF",1],["بنج موضعى - 100 حالة",1],["باند معدن",1],["اوفر جلافز",5],["اكياس تعقيم",6],["أمالجم",1]],"حشو عصب كلى اطفال":[["مفرش شفاف",2],["مفرش ألوان",1],["جوانتى جلافز",4],["اوفر جلافز",5],["ماسك للوجه",1],["ساكشن شفاط",3],["كوبايات",3],["تبات للهواء والمياة - Air Tip",2],["باند معدن",1],["بنج موضعى - 100 حالة",2],["كربولة بنج",2],["سن بنج",2],["اكياس تعقيم",6],["حشو مؤقت - 100 حالة",1],["بير - راوند",1],["قطن - ١٠٠ حالة",2],["قطن رول",2],["أمالجم",1],["ويدج",1],["مناديل",2],["فورماكريزول - ٤٠٠ حالة",1],["ميتا بيست - ١٧ حالة",1],["فايل مانوال مقاس ١٠",1],["فايل روتارى مقاس ١٥",1],["سرنجات بلاستيك",1]],"حشو عصب كبار":[["مفرش ألوان",1],["مفرش شفاف",3],["جوانتى جلافز",6],["ماسك للوجه",1],["ساكشن شفاط",4],["كوبايات",4],["تبات للهواء والمياة - Air Tip",3],["سن بنج",3],["كربولة بنج",3],["بنج موضعى - 100 حالة",3],["بوند cotelene - 100 حالة",1],["كمبوزيت فلوبال - flowable - ٢٠ حالة",1],["اتش - etch - ٢٠ حالة",1],["باند - سادل",1],["فايل مانوال مقاس ١٥",1],["فايل روتارى مقاس ٢٥",1],["جاتيبركا تيبر 2",8],["جاتابيركا تيبر ٤",4],["بيبر بوينت",12]]};

// ==================== Inventory ====================
function Inventory() {
  const { toast, inventory, setInventory, services, setServices, clinicId } = useContext(AppContext);
  const selectAllRef = useRef(null);
  const [tab, setTab] = useState('stock');
  const [query, setQuery] = useState('');
  const [bomService, setBomService] = useState(null);
  const [editService, setEditService] = useState(null);
  const [editInventoryItem, setEditInventoryItem] = useState(null);
  const [showAddService, setShowAddService] = useState(false);
  const [showAddInv, setShowAddInv] = useState(false);
  const [showBulkEditInv, setShowBulkEditInv] = useState(false);
  const [selectionMode, setSelectionMode] = useState(false);
  const [selectedInventoryIds, setSelectedInventoryIds] = useState([]);
  const [importing, setImporting] = useState(false);
  const [importingInv, setImportingInv] = useState(false);
  const [importingBom, setImportingBom] = useState(false);
  const usageUnitsKey = `senan-inventory-usage-units:${clinicId || 'default'}`;
  const [usageUnitsMap, setUsageUnitsMap] = useState({});
  const [bomStats, setBomStats] = useState({});
  const allInv  = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
  const allSvcs = (services && services.length) ? services : (window.TREATMENT_TYPES || []);
  const filtered = allInv.filter(i => (i.name||'').includes(query) || (i.category||'').includes(query));
  const visibleInventoryIds = filtered.map(it => it.id);
  const allVisibleSelected = selectionMode && visibleInventoryIds.length > 0 && visibleInventoryIds.every(id => selectedInventoryIds.includes(id));
  const someVisibleSelected = selectionMode && visibleInventoryIds.some(id => selectedInventoryIds.includes(id));

  const handleServiceSaved = (updated) => {
    if (setServices) setServices(prev => prev.map(s => s.id === updated.id ? updated : s));
  };
  const handleNewService = (svc) => {
    if (setServices) setServices(prev => [svc, ...prev]);
  };
  const handleNewInvItem = (item) => {
    if (setInventory) setInventory(prev => [item, ...prev]);
  };
  const handleInventorySaved = (updated) => {
    if (setInventory) setInventory(prev => prev.map(it => it.id === updated.id ? updated : it));
  };
  const extractLegacyPackMeta = (item) => extractLegacyInventoryPackMeta(item);
  const getUsageUnitsPerPack = (item) => getInventoryUsageUnitsPerPack(item, usageUnitsMap);
  const getDisplayInventoryName = (item) => getInventoryDisplayName(item);
  const persistUsageUnitsValue = (itemId, value) => {
    setUsageUnitsMap(prev => {
      const next = { ...prev };
      const numericValue = Math.max(0, Number(value) || 0);
      if (numericValue > 0) next[itemId] = numericValue;
      else delete next[itemId];
      return next;
    });
  };

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(usageUnitsKey);
      setUsageUnitsMap(raw ? JSON.parse(raw) : {});
    } catch (error) {
      console.warn('[Inventory] failed to load usage units map:', error);
      setUsageUnitsMap({});
    }
  }, [usageUnitsKey]);

  useEffect(() => {
    try {
      window.localStorage.setItem(usageUnitsKey, JSON.stringify(usageUnitsMap));
    } catch (error) {
      console.warn('[Inventory] failed to save usage units map:', error);
    }
  }, [usageUnitsKey, usageUnitsMap]);

  useEffect(() => {
    let cancelled = false;
    const loadBomStats = async () => {
      if (!allSvcs.length || !allInv.length) {
        if (!cancelled) setBomStats({});
        return;
      }
      const inventoryPriceMap = {};
      allInv.forEach(item => {
        inventoryPriceMap[item.id] = getInventoryMeasureUnitPrice(item, usageUnitsMap);
      });
      const nextStats = {};
      for (const svc of allSvcs) {
        const bom = await DB.getBomForService(svc.id);
        nextStats[svc.id] = {
          cost: bom.reduce((sum, entry) => sum + ((inventoryPriceMap[entry.inventoryId] || 0) * (Number(entry.standardQty) || 0)), 0),
          itemsCount: bom.length,
        };
      }
      if (!cancelled) setBomStats(nextStats);
    };
    loadBomStats();
    return () => { cancelled = true; };
  }, [clinicId, allSvcs.length, allInv.length, JSON.stringify(usageUnitsMap)]);

  const handleNewInvItemWithMeta = (item, usageUnitsPerPack = 0) => {
    persistUsageUnitsValue(item.id, usageUnitsPerPack);
    handleNewInvItem(item);
  };

  const handleInventorySavedWithMeta = (updated, usageUnitsPerPack = 0) => {
    persistUsageUnitsValue(updated.id, usageUnitsPerPack);
    handleInventorySaved(updated);
  };

  const toggleInventorySelection = (id) => {
    setSelectedInventoryIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
  };

  const handleSelectAllVisibleInventory = () => {
    const visibleIds = filtered.map(it => it.id);
    const allVisibleSelected = visibleIds.length > 0 && visibleIds.every(id => selectedInventoryIds.includes(id));
    if (allVisibleSelected) {
      setSelectedInventoryIds(prev => prev.filter(id => !visibleIds.includes(id)));
      setSelectionMode(false);
      return;
    }
    setSelectedInventoryIds(Array.from(new Set([...selectedInventoryIds, ...visibleIds])));
  };

  const handleBulkDeleteInventory = async () => {
    if (!selectedInventoryIds.length) {
      toast('اختر أصنافًا أولًا');
      return;
    }
    if (!window.confirm(`حذف ${selectedInventoryIds.length} صنف من المخزون؟`)) return;
    try {
      for (const id of selectedInventoryIds) {
        await DB.deleteInventoryItem(id);
      }
      if (setInventory) setInventory(prev => prev.filter(it => !selectedInventoryIds.includes(it.id)));
      setSelectedInventoryIds([]);
      setSelectionMode(false);
      toast('تم حذف الأصناف المحددة');
    } catch (e) {
      toast('❌ خطأ: ' + (e.message || 'تعذر حذف بعض الأصناف'));
    }
  };

  const handleBulkEditInventory = async (payload) => {
    const updatedRows = [];
    for (const id of selectedInventoryIds) {
      const row = await DB.updateInventoryItem(id, payload);
      updatedRows.push(row);
    }
    if (setInventory) {
      setInventory(prev => prev.map(it => updatedRows.find(row => row.id === it.id) || it));
    }
    setSelectedInventoryIds([]);
    setSelectionMode(false);
    toast('تم تعديل الأصناف المحددة ✅');
  };

  useEffect(() => {
    if (tab !== 'stock') {
      setSelectionMode(false);
      setSelectedInventoryIds([]);
    }
  }, [tab]);

  useEffect(() => {
    if (selectAllRef.current) {
      selectAllRef.current.indeterminate = !!(someVisibleSelected && !allVisibleSelected);
    }
  }, [someVisibleSelected, allVisibleSelected, selectionMode]);

  const SHEET_DOC_ID = '12LKRPmpFxpd6VRa0HGTUzqQQtFSEo3pnPA0kk2UfSnU';
  const SHEET_TABS = {
    stock: ['استيراد المخزون', 'استيراد المخزون '],
    services: ['استيراد الخدمات', 'الخدمات والاسعار', 'الخدمات والأسعار'],
    bom: ['استيراد مكونات الخدمات', 'مكونات الخدمة', 'مكونات الخدمات'],
  };
  const SHEET_GIDS = {
    stock: '2031167138',
  };
  const SHEET_BASE_URL = `https://docs.google.com/spreadsheets/d/${SHEET_DOC_ID}/gviz/tq?tqx=out:json&sheet=`;

  const normalizeSheetText = (value) => String(value || '')
    .replace(/[\u200c\u200d]/g, '')
    .replace(/\s+/g, ' ')
    .trim();

  const normalizeHeader = (value) => normalizeSheetText(value)
    .toLowerCase()
    .replace(/[\/_\-–—]+/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();

  const parseGvizResponse = (rawText) => {
    const start = rawText.indexOf('{');
    const end = rawText.lastIndexOf('}');
    if (start < 0 || end < start) throw new Error('صيغة بيانات الشيت غير متوقعة');
    return JSON.parse(rawText.slice(start, end + 1));
  };

  const gvizCellValue = (cell) => {
    if (!cell) return '';
    if (typeof cell.f === 'string' && normalizeSheetText(cell.f)) return String(cell.f);
    if (cell.v == null) return '';
    return String(cell.v);
  };

  const headerIndex = (headers, candidates) => {
    const normalized = headers.map(normalizeHeader);
    for (const candidate of candidates) {
      const idx = normalized.indexOf(normalizeHeader(candidate));
      if (idx >= 0) return idx;
    }
    return -1;
  };

  const pickValue = (row, headers, candidates) => {
    const idx = headerIndex(headers, candidates);
    return idx >= 0 ? normalizeSheetText(row[idx]) : '';
  };

  const fetchSheetRows = async (kind) => {
    const sources = [];
    if (SHEET_GIDS[kind]) {
      sources.push({ gid: SHEET_GIDS[kind] });
    }
    for (const tabName of (SHEET_TABS[kind] || [])) {
      sources.push({ sheet: tabName });
    }

    for (const source of sources) {
      const url = source.gid
        ? `https://docs.google.com/spreadsheets/d/${SHEET_DOC_ID}/gviz/tq?tqx=out:json&gid=${source.gid}`
        : `${SHEET_BASE_URL}${encodeURIComponent(source.sheet)}`;
      const res = await fetch(url);
      if (!res.ok) continue;
      const rawText = await res.text();
      const payload = parseGvizResponse(rawText);
      const table = payload?.table;
      const rows = (table?.rows || [])
        .map(row => (row.c || []).map(gvizCellValue))
        .filter(row => row.some(v => normalizeSheetText(v)));
      if (!rows.length) continue;

      const columnHeaders = (table?.cols || []).map(col => normalizeSheetText(col?.label || ''));
      const firstRow = rows[0] || [];
      const firstRowLooksLikeHeaders = firstRow.some(value => /الخدمة|الخدمات|service|name|اسم|المكون|component|quantity|الكمية|السعر|price|الفئة|category|المخزون|stock|supplier|المورد|expiry|الصلاحية/i.test(String(value || '')));
      const hasColumnHeaders = columnHeaders.some(Boolean);
      const headers = (!hasColumnHeaders || firstRowLooksLikeHeaders) ? firstRow : columnHeaders;
      const dataRows = (!hasColumnHeaders || firstRowLooksLikeHeaders) ? rows.slice(1) : rows;

      if (headers.length && dataRows.length) {
        return { tabName: source.sheet || source.gid, headers, rows: dataRows };
      }
    }
    throw new Error('لم نتمكن من قراءة تبويب الشيت المطلوب');
  };

  const upsertLocalService = async (data) => {
    const inserted = await DB.addService(clinicId, data);
    if (inserted && setServices) setServices(prev => [inserted, ...prev]);
    return inserted;
  };

  const upsertLocalInventory = async (data) => {
    const inserted = await DB.addInventoryItem(clinicId, data);
    if (inserted && setInventory) setInventory(prev => [inserted, ...prev]);
    return inserted;
  };

  // ─── استيراد الخدمات من Google Sheets ───
  const importServicesFromSheets = async () => {
    setImporting(true);
    try {
      const { headers, rows } = await fetchSheetRows('services');
      const sheetSvcs = rows.map(row => {
        const name = pickValue(row, headers, ['الخدمة', 'service', 'name', 'اسم الخدمة', 'اسم الإجراء']);
        const category = pickValue(row, headers, ['الفئة', 'category', 'التصنيف', 'نوع الخدمة']) || 'عام';
        const durationRaw = pickValue(row, headers, ['المدة', 'duration', 'الزمن', 'الوقت']);
        const priceRaw = pickValue(row, headers, ['السعر', 'price', 'تكلفة', 'القيمة']);
        const duration = Math.max(5, parseInt(durationRaw.replace(/[^\d]/g, ''), 10) || 30);
        const price = parseFloat(priceRaw.replace(/[^\d.]/g, '')) || 0;
        return { name, category, duration, price };
      }).filter(s => s.name);

      if (!sheetSvcs.length) {
        throw new Error('تبويب استيراد الخدمات يحتاج عمود "اسم الخدمة" ويفضل معه "المدة" و"السعر"');
      }

      const existingNames = new Set(allSvcs.map(s => normalizeSheetText(s.name)));
      const toAdd = sheetSvcs.filter(s => !existingNames.has(normalizeSheetText(s.name)));

      if (toAdd.length === 0) {
        toast('✅ كل الخدمات موجودة بالفعل من الشيت الإرشادي');
        return;
      }

      let added = 0;
      for (const s of toAdd) {
        try {
          const inserted = await upsertLocalService({
            name: s.name,
            price: s.price,
            duration: s.duration,
            category: s.category,
          });
          if (inserted) added++;
        } catch(e) { console.error('خطأ في إضافة:', s.name, e); }
      }
      toast(`✅ تم استيراد ${added} خدمة جديدة من الشيت الإرشادي`);
    } catch(e) {
      console.error(e);
      toast('❌ خطأ: ' + (e.message || 'فشل الاستيراد'));
    } finally {
      setImporting(false);
    }
  };

  // ─── استيراد المخزون من البيانات المحلية (_INV) ───
  const importInventoryFromSheets = async () => {
    setImportingInv(true);
    try {
      const { headers, rows } = await fetchSheetRows('stock');
      const sheetItems = rows.map(row => {
        const name = pickValue(row, headers, ['الصنف', 'الاسم', 'name', 'item', 'اسم الصنف']);
        const category = pickValue(row, headers, ['الفئة', 'category', 'التصنيف', 'نوع الصنف']) || 'مستلزمات طبية';
        const stockRaw = pickValue(row, headers, ['المخزون', 'stock', 'qty', 'quantity', 'الكمية']);
        const minRaw = pickValue(row, headers, ['الحد الأدنى', 'min stock', 'minimum', 'min', 'الحد الأدني']);
        const unit = pickValue(row, headers, ['الوحدة', 'unit', 'units']) || 'قطعة';
        const priceRaw = pickValue(row, headers, ['السعر', 'price', 'cost', 'التكلفة']);
        const supplier = pickValue(row, headers, ['المورد', 'supplier', 'source']) || '';
        const expiry = pickValue(row, headers, ['الصلاحية', 'expiry', 'expires', 'expiry date']) || '';
        const usageUnitsRaw = pickValue(row, headers, [
          'عدد وحدات الاستخدام داخل العبوة',
          'عدد الحالات داخل العبوة',
          'عدد الوحدات داخل العبوة',
          'تكفي كام حالة',
          'الحالات داخل العبوة',
          'usage units per pack',
          'cases per pack',
        ]);
        const stock = Math.max(0, parseFloat(stockRaw.replace(/[^\d.]/g, '')) || 0);
        const minStock = Math.max(0, parseFloat(minRaw.replace(/[^\d.]/g, '')) || 0);
        const price = Math.max(0, parseFloat(priceRaw.replace(/[^\d.]/g, '')) || 0);
        const usageUnitsPerPack = Math.max(0, parseFloat(String(usageUnitsRaw || '').replace(/[^\d.]/g, '')) || 0);
        return { name, category, stock, minStock, unit, price, supplier, expiry, usageUnitsPerPack };
      }).filter(i => i.name);

      if (!sheetItems.length) {
        const hasServiceHeader = headerIndex(headers, ['اسم الخدمة', 'الخدمة', 'service', 'service name']) >= 0;
        if (hasServiceHeader) {
          throw new Error('تبويب استيراد المخزون يحتوي بيانات خدمات الآن، وليس أصناف مخزون');
        }
        throw new Error('تبويب استيراد المخزون يحتاج عمود "اسم الصنف" على الأقل');
      }

      const existingNames = new Set(allInv.map(i => normalizeSheetText(i.name)));
      const toAdd = sheetItems.filter(i => !existingNames.has(normalizeSheetText(i.name)));
      if (toAdd.length === 0) {
        toast('✅ كل أصناف المخزون موجودة بالفعل من الشيت الإرشادي');
        return;
      }
      let added = 0;
      let failed = 0;
      let firstError = '';
      for (const item of toAdd) {
        try {
          const inserted = await upsertLocalInventory({
            name: item.name,
            price: item.price,
            stock: item.stock,
            min_stock: item.minStock,
            unit: item.unit,
            category: item.category,
            supplier: item.supplier || null,
            expiry: item.expiry || null,
          });
          if (inserted) {
            persistUsageUnitsValue(inserted.id, item.usageUnitsPerPack || 0);
            added++;
          }
        } catch(e) {
          failed++;
          if (!firstError) firstError = e?.message || '';
          console.error('خطأ في إضافة صنف:', item.name, e);
        }
      }
      if (added === 0 && failed > 0) {
        throw new Error(firstError || 'تعذر إضافة أصناف المخزون من الشيت');
      }
      toast(`✅ تم استيراد ${added} صنف جديد من الشيت الإرشادي${failed ? ` · تعذر ${failed}` : ''}`);
    } catch(e) {
      console.error(e);
      toast('❌ خطأ: ' + (e.message || 'فشل الاستيراد'));
    } finally {
      setImportingInv(false);
    }
  };

  // ─── استيراد مكونات الخدمات (BOM) من البيانات المحلية (_BOM) ───
  const importBomFromSheets = async () => {
    setImportingBom(true);
    try {
      // نحتاج قائمة محدّثة من Supabase للخدمات والمخزون
      const currentInv  = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
      const currentSvcs = (services  && services.length)  ? services  : (window.TREATMENT_TYPES || []);

      let totalAdded = 0, skipped = 0;

      for (const [svcName, components] of Object.entries(_BOM)) {
        // إيجاد الخدمة بالاسم (مطابقة جزئية أو كاملة)
        const svc = currentSvcs.find(s => (s.name || '').trim() === svcName.trim());
        if (!svc) { console.warn('لم يُعثر على خدمة:', svcName); skipped++; continue; }

        for (const [itemName, qty] of components) {
          const invItem = currentInv.find(i => (i.name || '').trim() === itemName.trim());
          if (!invItem) { console.warn('لم يُعثر على صنف مخزون:', itemName, '← الخدمة:', svcName); skipped++; continue; }
          try {
            await DB.addBomItem(clinicId, svc.id, invItem.id, qty);
            totalAdded++;
          } catch(e) {
            // تجاهل خطأ upsert conflict (مكوّن موجود مسبقاً)
            if (e && e.code === '23505') { totalAdded++; }
            else { console.error('خطأ BOM:', svcName, itemName, e); skipped++; }
          }
        }
      }
      toast(`✅ تم استيراد ${totalAdded} مكوّن${skipped ? ' · تخطّى ' + skipped : ''}`);
    } catch(e) {
      console.error(e);
      toast('❌ خطأ: ' + (e.message || 'فشل الاستيراد'));
    } finally {
      setImportingBom(false);
    }
  };

  const importBomFromGuidedSheet = async () => {
    setImportingBom(true);
    try {
      const currentInv  = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
      const currentSvcs = (services  && services.length)  ? services  : (window.TREATMENT_TYPES || []);
      if (!currentSvcs.length) throw new Error('استورد الخدمات أولاً قبل مكونات الخدمة');
      if (!currentInv.length) throw new Error('استورد المخزون أو أضف أصنافاً أولاً قبل مكونات الخدمة');
      const { headers, rows } = await fetchSheetRows('bom');
      const sheetRows = rows.map(row => ({
        service: pickValue(row, headers, ['الخدمة', 'service', 'اسم الخدمة', 'الإجراء', 'procedure']),
        item: pickValue(row, headers, ['اسم الصنف', 'المكون', 'item', 'الصنف', 'المادة', 'component']),
        qty: parseFloat(pickValue(row, headers, ['الكمية المعيارية', 'الكمية', 'qty', 'quantity', 'amount']).replace(/[^\d.]/g, '')) || 1,
      })).filter(r => r.service && r.item);

      if (!sheetRows.length) {
        throw new Error('تبويب استيراد مكونات الخدمة يحتاج: اسم الخدمة + اسم الصنف + الكمية المعيارية');
      }

      let totalAdded = 0, skipped = 0;
      for (const row of sheetRows) {
        const svc = currentSvcs.find(s => normalizeSheetText(s.name) === normalizeSheetText(row.service));
        const invItem = currentInv.find(i => normalizeSheetText(i.name) === normalizeSheetText(row.item));
        if (!svc || !invItem) { skipped++; continue; }
        try {
          await DB.addBomItem(clinicId, svc.id, invItem.id, row.qty);
          totalAdded++;
        } catch (e) {
          if (e && e.code === '23505') totalAdded++;
          else { console.error('خطأ BOM:', row.service, row.item, e); skipped++; }
        }
      }
      toast(`✅ تم استيراد ${totalAdded} مكوّن${skipped ? ' · تخطّي ' + skipped : ''}`);
    } catch (e) {
      console.error(e);
      toast('❌ خطأ: ' + (e.message || 'فشل الاستيراد'));
    } finally {
      setImportingBom(false);
    }
  };

  return h('div', { className: 'fade-in' },
    bomService ? h(BomModal, { service: bomService, onClose: () => setBomService(null) }) : null,
    editService ? h(EditServiceModal, { service: editService, onClose: () => setEditService(null), onSaved: handleServiceSaved }) : null,
    editInventoryItem ? h(EditInventoryModal, { item: editInventoryItem, onClose: () => setEditInventoryItem(null), onSaved: handleInventorySavedWithMeta }) : null,
    showBulkEditInv ? h(BulkEditInventoryModal, { count: selectedInventoryIds.length, onClose: () => setShowBulkEditInv(false), onSaved: handleBulkEditInventory }) : null,
    showAddService ? h(AddServiceModal, { onClose: () => setShowAddService(false), onSaved: handleNewService }) : null,
    showAddInv ? h(AddInventoryModal, { onClose: () => setShowAddInv(false), onSaved: handleNewInvItemWithMeta }) : null,

    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'المخزون والخدمات'),
        h('div', { className: 'page-subtitle' }, `${allInv.length} صنف · ${allSvcs.length} خدمة`),
      ),
      h('div', { className: 'flex gap-8' },
        h('button', { className: 'btn outline' }, h(Icons.Download, { size: 16 }), 'تصدير'),
        tab === 'stock' ? h(Fragment, null,
          h('button', {
            className: 'btn outline',
            onClick: importInventoryFromSheets,
            disabled: importingInv,
            title: 'استيراد المخزون من الشيت الإرشادي — قابل للتعديل بعد الاستيراد',
          }, h(Icons.Download, { size: 16 }), importingInv ? 'جاري الاستيراد...' : 'استيراد المخزون'),
          h('button', {
            className: 'btn outline',
            onClick: () => setSelectionMode(true),
          }, 'تحديد'),
          selectionMode && selectedInventoryIds.length > 0 ? h('button', {
            className: 'btn outline',
            onClick: () => setShowBulkEditInv(true),
          }, `تعديل المحدد${selectedInventoryIds.length ? ` (${selectedInventoryIds.length})` : ''}`) : null,
          selectionMode && selectedInventoryIds.length > 0 ? h('button', {
            className: 'btn danger outline',
            onClick: handleBulkDeleteInventory,
          }, `حذف المحدد${selectedInventoryIds.length ? ` (${selectedInventoryIds.length})` : ''}`) : null,
          h('button', { className: 'btn primary', onClick: () => setShowAddInv(true) }, h(Icons.Plus, { size: 16 }), 'صنف جديد'),
        ) : null,
        tab === 'services' ? h(Fragment, null,
          h('button', {
            className: 'btn outline',
            onClick: importServicesFromSheets,
            disabled: importing,
            title: 'استيراد الخدمات من الشيت الإرشادي — قابل للتعديل بعد الاستيراد',
          }, h(Icons.Download, { size: 16 }), importing ? 'جاري الاستيراد...' : 'استيراد الخدمات'),
          h('button', { className: 'btn primary', onClick: () => setShowAddService(true) }, h(Icons.Plus, { size: 16 }), 'خدمة جديدة'),
        ) : null,
        tab === 'bom' ? h('button', {
          className: 'btn outline',
          onClick: importBomFromGuidedSheet,
          disabled: importingBom,
          title: 'استيراد مكونات الخدمة من الشيت الإرشادي — قابل للتعديل بعد الاستيراد',
        }, h(Icons.Download, { size: 16 }), importingBom ? 'جاري الاستيراد...' : 'استيراد مكونات الخدمة') : null,
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'card p-12 mb-12', style: { background: 'var(--accent-soft)', border: '1px solid var(--border)', color: 'var(--text-secondary)' } },
        'الاستيراد هنا إرشادي فقط. بعد نزول البيانات تقدر تعدل، تحذف، وتضيف بحرية من نفس الشاشة.'
      ),
      h('div', { className: 'tabs mb-16' },
        [['stock','📦 المخزون'], ['services','⚕️ الخدمات والأسعار'], ['bom','🔬 مكونات الخدمات']].map(([v,l]) =>
          h('button', { key:v, className:'tab'+(tab===v?' active':''), onClick:()=>setTab(v) }, l)
        ),
      ),

      /* ======= TAB: المخزون ======= */
      tab === 'stock' && h(Fragment, null,
        h('div', { className: 'card p-16 mb-16 flex gap-8 ai-c' },
          h('div', { style: { flex: 1, position: 'relative' } },
            h('input', { className: 'input', placeholder: 'بحث...', value: query, onChange: (e) => setQuery(e.target.value), style: { paddingInlineEnd: 40 } }),
            h('span', { style: { position: 'absolute', insetInlineEnd: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--text-tertiary)' } }, h(Icons.Search, { size: 16 })),
          ),
          h('button', { className: 'btn outline' }, h(Icons.Filter, { size: 16 }), 'الفئة'),
        ),
        h('div', { className: 'card', style: { overflow: 'hidden' } },
          h('table', { className: 'data-table' },
            h('thead', null, h('tr', null,
              h('th', { style: { minWidth: 220, whiteSpace: 'nowrap' } },
                h('div', { style: { display:'flex', alignItems:'center', justifyContent:'flex-end', gap:10 } },
                  h('span', null, 'الصنف'),
                  selectionMode ? h('input', {
                    ref: selectAllRef,
                    type: 'checkbox',
                    checked: !!allVisibleSelected,
                    onChange: handleSelectAllVisibleInventory,
                    title: allVisibleSelected ? 'إلغاء تحديد الكل' : 'تحديد الكل',
                  }) : null,
                ),
              ),
              ['الفئة', 'المخزون', 'وحدات القياس الفعلية', 'الحد الأدنى', 'السعر', 'سعر وحدة القياس', 'الصلاحية', 'الحالة', '', '', ''].map((t, i) => h('th', { key: i }, t))
            )),
            h('tbody', null,
              filtered.map(it => {
                const stockQty = Number(it.stock) || 0;
                const minQty = Number(it.minStock) || 0;
                const critical = stockQty <= 0;
                const low = !critical && minQty > 0 && stockQty <= minQty;
                const selected = selectedInventoryIds.includes(it.id);
                const usageUnitsPerPack = getUsageUnitsPerPack(it);
                const actualUsageUnits = getInventoryActualUsageUnits(it, usageUnitsMap);
                const measureUnitPrice = getInventoryMeasureUnitPrice(it, usageUnitsMap);
                return h('tr', { key: it.id },
                  h('td', { style: { fontWeight: 600, minWidth: 220 } },
                    h('div', { style: { display:'flex', alignItems:'center', justifyContent:'flex-end', gap:10 } },
                      h('div', { style: { display:'grid', gap:4, justifyItems:'end', textAlign:'right' } },
                        h('span', null, getDisplayInventoryName(it)),
                        usageUnitsPerPack > 0 ? h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)', fontWeight: 500 } }, `العبوة تكفي ${window.fmtNum(usageUnitsPerPack)} حالة`) : null,
                      ),
                      selectionMode ? h('input', {
                        type: 'checkbox',
                        checked: selected,
                        onChange: () => toggleInventorySelection(it.id),
                      }) : null,
                    ),
                  ),
                  h('td', null, h('span', { className: 'chip' }, it.category)),
                  h('td', null,
                    h('div', { className: 'flex ai-c gap-8' },
                      h('span', { style: { fontWeight: 800, color: critical ? 'var(--danger)' : low ? 'var(--warning)' : 'var(--text-primary)' } }, window.fmtNum(stockQty)),
                      h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, it.unit),
                    ),
                  ),
                  h('td', { style: { fontWeight: 700 } }, usageUnitsPerPack > 0 ? window.fmtNum(actualUsageUnits) : '—'),
                  h('td', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, window.fmtNum(minQty) + ' ' + it.unit),
                  h('td', { style: { fontWeight: 600 } }, window.fmtEGP(it.price)),
                  h('td', { style: { fontWeight: 600 } }, usageUnitsPerPack > 0 ? window.fmtEGP(measureUnitPrice) : '—'),
                  h('td', { style: { fontSize: 12, color: 'var(--text-secondary)' } }, it.expiry || '—'),
                  h('td', null, h('span', { className: 'chip ' + (critical ? 'danger' : low ? 'warning' : 'success') },
                    critical ? 'نافد' : low ? 'منخفض' : 'متاح')),
                  h('td', null, h('button', { className: 'btn sm outline', onClick: () => toast('تم طلب الصنف') }, 'طلب')),
                  h('td', null, h('button', {
                    className: 'btn sm outline',
                    onClick: () => setEditInventoryItem({ ...it, usageUnitsPerPack }),
                  }, h(Icons.Edit, { size: 13 }), 'تعديل')),
                  h('td', null, h('button', {
                    className: 'btn sm danger outline',
                    onClick: async () => {
                      if (!window.confirm('حذف الصنف من المخزون؟')) return;
                      try {
                        await DB.deleteInventoryItem(it.id);
                        if (setInventory) setInventory(prev => prev.filter(x => x.id !== it.id));
                        toast('تم حذف الصنف');
                      } catch (e) {
                        toast('❌ خطأ: ' + (e.message || 'تعذر الحذف'));
                      }
                    },
                  }, h(Icons.Trash, { size: 13 }), 'حذف')),
                );
              }),
            ),
          ),
        ),
      ),

      /* ======= TAB: الخدمات والأسعار ======= */
      tab === 'services' && h('div', { className: 'card', style: { overflow: 'hidden' } },
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, ['الخدمة', 'الفئة', 'المدة', 'السعر', '', ''].map((t, i) => h('th', { key: i }, t)))),
          h('tbody', null,
            allSvcs.length === 0 ?
              h('tr', null, h('td', { colSpan: 6, style: { textAlign: 'center', padding: 32, color: 'var(--text-tertiary)' } }, 'لا توجد خدمات — أضف خدمات من Supabase')) :
            allSvcs.map(svc => h('tr', { key: svc.id },
              h('td', { style: { fontWeight: 700 } }, svc.name),
              h('td', null, h('span', { className: 'chip' }, svc.category || '—')),
              h('td', { style: { fontSize: 13, color: 'var(--text-secondary)' } }, (svc.duration || 30) + ' د'),
              h('td', { style: { fontWeight: 800, color: 'var(--accent)' } }, window.fmtEGP(svc.price)),
              h('td', null, h('button', { className: 'btn sm outline', onClick: () => setEditService(svc) },
                h(Icons.Edit, { size: 13 }), 'تعديل السعر')),
              h('td', null, h('button', {
                className: 'btn sm danger outline',
                onClick: async () => {
                  if (!window.confirm('حذف الخدمة ومكوناتها؟')) return;
                  try {
                    await DB.deleteService(svc.id);
                    if (setServices) setServices(prev => prev.filter(x => x.id !== svc.id));
                    toast('تم حذف الخدمة');
                  } catch (e) {
                    toast('❌ خطأ: ' + (e.message || 'تعذر الحذف'));
                  }
                },
              }, h(Icons.Trash, { size: 13 }), 'حذف')),
            )),
          ),
        ),
      ),

      /* ======= TAB: BOM ======= */
      tab === 'bom' && h('div', null,
        h('div', { className: 'grid', style: { gap: 10 } },
          allSvcs.map(svc => h('div', { key: svc.id, className: 'card p-16', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
            h('div', null,
              h('div', { style: { fontWeight: 700, fontSize: 14 } }, svc.name),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 } }, 'إجمالي تكلفة المكونات: ' + window.fmtEGP((bomStats[svc.id] && bomStats[svc.id].cost) || 0) + ' · ' + (svc.duration || 30) + ' دقيقة'),
            ),
            h('div', { className: 'flex gap-8' },
              h('button', { className: 'btn outline', onClick: () => setBomService(svc) },
                h(Icons.Package, { size: 15 }), 'إدارة المكونات'),
              h('button', {
                className: 'btn danger outline',
                onClick: async () => {
                  if (!window.confirm('حذف الخدمة وكل مكوناتها؟')) return;
                  try {
                    await DB.deleteService(svc.id);
                    if (setServices) setServices(prev => prev.filter(x => x.id !== svc.id));
                    toast('تم حذف الخدمة');
                  } catch (e) {
                    toast('❌ خطأ: ' + (e.message || 'تعذر الحذف'));
                  }
                },
              }, h(Icons.Trash, { size: 14 }), 'حذف'),
            ),
          )),
          allSvcs.length === 0 && h('div', { style: { textAlign: 'center', padding: 32, color: 'var(--text-tertiary)', border: '2px dashed var(--border)', borderRadius: 'var(--radius)' } },
            'أضف خدمات أولاً من تبويب "الخدمات والأسعار"'),
        ),
      ),
    ),
  );
}

// ==================== Edit Doctor Modal ====================
function EditDoctorModal({ doctor, onClose, onSaved }) {
  const { toast } = useContext(AppContext);
  const [form, setForm] = useState({
    name: doctor.name,
    specialty: doctor.specialty || '',
    commission_rate: Math.round((doctor.commissionRate || 0.30) * 100),
  });
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSave = async () => {
    const rate = Math.min(Math.max(+form.commission_rate, 0), 100) / 100;
    setSaving(true);
    try {
      const updated = await DB.updateDoctor(doctor.id, {
        name: form.name,
        specialty: form.specialty,
        commission_rate: rate,
      });
      toast('تم حفظ بيانات الطبيب ✅');
      onSaved({ ...doctor, ...updated, commissionRate: rate });
      onClose();
    } catch(e) { toast('خطأ: ' + (e.message || 'غير متوقع')); }
    finally { setSaving(false); }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:300 } }),
    h('div', { style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:24,width:380,zIndex:301,boxShadow:'var(--shadow-lg)' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', { style:{fontWeight:800,fontSize:16} }, 'تعديل بيانات الطبيب'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{display:'grid',gap:12} },
        h('div', null,
          h('div', { className:'label' }, 'الاسم'),
          h('input', { className:'input', value:form.name, onChange:e=>set('name',e.target.value) }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'التخصص'),
          h('input', { className:'input', value:form.specialty, onChange:e=>set('specialty',e.target.value) }),
        ),
        h('div', null,
          h('div', { className:'label' }, 'نسبة العمولة (%)'),
          h('input', { className:'input', type:'number', min:0, max:100, value:form.commission_rate, onChange:e=>set('commission_rate',e.target.value) }),
          h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:4} },
            `كل 1000 ج.م مدفوعة → عمولة: ${window.fmtEGP(1000 * form.commission_rate / 100)}`),
        ),
      ),
      h('div', { className:'flex gap-8 jc-sb mt-20' },
        h('button', { className:'btn outline', onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn primary', disabled:saving, onClick:handleSave },
          saving ? 'جاري الحفظ...' : 'حفظ'),
      ),
    ),
  );
}

// ==================== Staff ====================
function Staff() {
  const { doctors, setDoctors, toast, clinicId } = useContext(AppContext);
  const [editDoc, setEditDoc] = useState(null);
  const [importingDocs, setImportingDocs] = useState(false);
  const allDoctors = (doctors && doctors.length) ? doctors : (window.DOCTORS || []);

  const handleDoctorSaved = (updated) => {
    if (setDoctors) setDoctors(prev => prev.map(d => d.id === updated.id ? updated : d));
  };

  // بيانات الأطباء من Google Sheets (Alpha Clinic System)
  const SHEET_DOCTORS = [
    { name: 'د/ احمد دراج', specialty: 'أسنان عامة', commission_rate: 0.30, color: '#0891b2' },
    { name: 'د/ محمد عمر',  specialty: 'أسنان عامة', commission_rate: 0.30, color: '#7c3aed' },
  ];
  const importDoctorsFromSheets = async () => {
    setImportingDocs(true);
    try {
      const existingNames = new Set(allDoctors.map(d => (d.name || '').trim()));
      const toAdd = SHEET_DOCTORS.filter(d => !existingNames.has(d.name));
      if (toAdd.length === 0) { toast('✅ الأطباء موجودون بالفعل'); setImportingDocs(false); return; }
      let added = 0;
      for (const d of toAdd) {
        const { data, error } = await SB.from('doctors')
          .insert({ clinic_id: clinicId, name: d.name, specialty: d.specialty, commission_rate: d.commission_rate, color: d.color, status: 'متاح' })
          .select().single();
        if (!error && data) {
          if (setDoctors) setDoctors(prev => [...prev, {
            ...data,
            commissionRate: data.commission_rate,
            avatar: (data.name || '').slice(0, 2),
          }]);
          added++;
        }
      }
      toast('✅ تم استيراد ' + added + ' طبيب من Google Sheets');
    } catch(e) { toast('❌ خطأ: ' + (e.message || 'فشل')); }
    finally { setImportingDocs(false); }
  };

  return h('div', { className: 'fade-in' },
    editDoc ? h(EditDoctorModal, { doctor: editDoc, onClose: () => setEditDoc(null), onSaved: handleDoctorSaved }) : null,
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الموظفين'),
        h('div', { className: 'page-subtitle' }, `${allDoctors.length} أطباء · ${(window.STAFF||[]).length} موظفين مساعدين`),
      ),
      h('div', { className: 'flex gap-8' },
        allDoctors.length === 0 ? h('button', {
          className: 'btn outline',
          onClick: importDoctorsFromSheets,
          disabled: importingDocs,
        }, h(Icons.Download, { size: 16 }), importingDocs ? 'جاري الاستيراد...' : 'استيراد الأطباء من Sheets') : null,
        h('button', { className: 'btn primary' }, h(Icons.UserPlus, { size: 16 }), 'موظف جديد'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'mb-16', style: { fontWeight: 800, fontSize: 15 } }, 'الأطباء'),
      h('div', { className: 'grid cols-4 mb-24' },
        allDoctors.map(d => h('div', { key: d.id, className: 'card p-20', style: { textAlign: 'center' } },
          h('div', { className: 'avatar lg', style: { background: d.color, margin: '0 auto 12px' } }, d.avatar),
          h('div', { style: { fontWeight: 800, fontSize: 15 } }, d.name),
          h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 } }, d.specialty),
          h('div', { style: { fontSize: 12, color: 'var(--success)', fontWeight: 700, marginTop: 4 } },
            `عمولة: ${Math.round((d.commissionRate || 0.30) * 100)}%`),
          h('div', { className: 'flex jc-sb ai-c mt-16' },
            h('div', null,
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'المرضى'),
              h('div', { style: { fontWeight: 800, fontSize: 18 } }, window.fmtNum(d.patients || 0)),
            ),
            h('div', null,
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'التقييم'),
              h('div', { style: { fontWeight: 800, fontSize: 18 } },
                h(Icons.Star, { size: 14, style: { display: 'inline-block', verticalAlign: 'text-bottom', color: '#f59e0b', marginLeft: 4 } }),
                d.rating || 4.8,
              ),
            ),
          ),
          h('span', { className: 'chip ' + (d.status === 'متاحة' ? 'success' : d.status === 'مع مريض' ? 'warning' : ''), style: { marginTop: 12 } }, d.status || 'متاح'),
          h('button', { className: 'btn sm outline mt-12', style: { width: '100%' }, onClick: () => setEditDoc(d) },
            h(Icons.Edit, { size: 13 }), 'تعديل البيانات'),
        )),
      ),
      h('div', { className: 'mb-16', style: { fontWeight: 800, fontSize: 15 } }, 'الموظفون المساعدون'),
      h('div', { className: 'card', style: { overflow: 'hidden' } },
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, ['الاسم', 'الدور', 'الهاتف', 'الوردية', ''].map((t, i) => h('th', { key: i }, t)))),
          h('tbody', null,
            window.STAFF.map(s => h('tr', { key: s.id },
              h('td', null, h('div', { className: 'flex ai-c gap-12' },
                h('div', { className: 'avatar sm' }, s.avatar),
                h('div', { style: { fontWeight: 700 } }, s.name),
              )),
              h('td', null, s.role),
              h('td', { style: { direction: 'ltr', textAlign: 'right' } }, s.phone),
              h('td', null, h('span', { className: 'chip' }, s.shift)),
              h('td', null, h('button', { className: 'btn ghost sm' }, 'عرض')),
            )),
          ),
        ),
      ),
    ),
  );
}

// ==================== Reports ====================
function Reports() {
  const { doctors, invoices, appointments, inventory, clinicName } = useContext(AppContext);
  const [repTab, setRepTab] = useState('overview');
  const [commMonth, setCommMonth] = useState(new Date().toISOString().slice(0, 7)); // YYYY-MM

  const allDoctors = (doctors && doctors.length) ? doctors : (window.DOCTORS || []);
  const allInvoices = (invoices && invoices.length) ? invoices : (window.INVOICES || []);
  const allAppts = (appointments && appointments.length) ? appointments : (window.APPOINTMENTS || []);
  const allInv = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
  const today = new Date().toISOString().split('T')[0];

  // ── Commission calc ──
  // commData loaded lazily via loadCommissions()
  const [commData, setCommData] = useState([]);
  const [commLoading, setCommLoading] = useState(false);

  const loadCommissions = async () => {
    setCommLoading(true);
    try {
      const { data, error } = await SB.from('sessions')
        .select('doctor_id, paid_amount, doctor_commission, date, doctors(name, commission_rate)')
        .gte('date', commMonth + '-01')
        .lte('date', commMonth + '-31');
      if (error) throw error;
      // Group by doctor
      const map = {};
      (data || []).forEach(s => {
        const id = s.doctor_id || 'unknown';
        if (!map[id]) map[id] = { name: s.doctors?.name || 'غير محدد', totalPaid: 0, totalComm: 0, sessions: 0, rate: s.doctors?.commission_rate || 0.30 };
        map[id].totalPaid += parseFloat(s.paid_amount) || 0;
        map[id].totalComm += parseFloat(s.doctor_commission) || 0;
        map[id].sessions++;
      });
      setCommData(Object.values(map).sort((a,b) => b.totalComm - a.totalComm));
    } catch(e) { console.error(e); }
    finally { setCommLoading(false); }
  };

  useEffect(() => { if (repTab === 'commissions') loadCommissions(); }, [repTab, commMonth]);

  // ── Daily Summary ──
  const todayInvoices = allInvoices.filter(i => i.date === today);
  const todayRevenue = todayInvoices.reduce((s,i) => s + i.paid, 0);
  const todayAppts = allAppts.filter(a => a.date === today);
  const tomorrowAppts = allAppts.filter(a => {
    const t = new Date(); t.setDate(t.getDate()+1);
    return a.date === t.toISOString().split('T')[0];
  });
  const lowStock = allInv.filter(i => i.stock < i.minStock);

  const dailySummaryText = () => {
    const lines = [
      `📊 ملخص يوم ${today} — ${clinicName || 'سِنان كلينيك'}`,
      `💰 إيراد اليوم: ${window.fmtEGP(todayRevenue)} (${todayInvoices.length} فاتورة)`,
      `📅 مواعيد اليوم: ${todayAppts.length} موعد`,
      `📅 مواعيد الغد: ${tomorrowAppts.length} موعد`,
      lowStock.length > 0 ? `⚠️ مخزون منخفض: ${lowStock.map(i=>i.name).join('، ')}` : '✅ المخزون طبيعي',
    ];
    return lines.join('\n');
  };

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'التقارير والإحصائيات'),
        h('div', { className: 'page-subtitle' }, 'نظرة شاملة على أداء العيادة'),
      ),
      h('div', { className: 'flex gap-8' },
        h('button', { className: 'btn outline' }, h(Icons.Download, { size: 16 }), 'تصدير PDF'),
      ),
    ),
    h('div', { className: 'page-content' },
      // Tabs
      h('div', { className: 'tabs mb-16' },
        [['overview','📊 نظرة عامة'],['commissions','💵 عمولات الأطباء'],['daily','📋 الملخص اليومي']].map(([v,l]) =>
          h('button', { key:v, className:'tab'+(repTab===v?' active':''), onClick:()=>setRepTab(v) }, l)
        ),
      ),

      /* ===== عمولات الأطباء ===== */
      repTab === 'commissions' && h('div', null,
        h('div', { className:'card p-16 mb-16 flex gap-12 ai-c' },
          h('div', { className:'label', style:{whiteSpace:'nowrap'} }, 'شهر:'),
          h('input', { className:'input', type:'month', value:commMonth, onChange:e=>setCommMonth(e.target.value), style:{width:160} }),
          h('button', { className:'btn primary', onClick:loadCommissions, disabled:commLoading },
            commLoading ? 'جاري التحميل...' : '🔄 تحديث'),
        ),
        h('div', { className:'card', style:{overflow:'hidden'} },
          h('table', { className:'data-table' },
            h('thead', null, h('tr', null,
              ['الطبيب','عدد الجلسات','إجمالي المدفوع','نسبة العمولة','العمولة المستحقة'].map((t,i)=>h('th',{key:i},t))
            )),
            h('tbody', null,
              commLoading ? h('tr', null, h('td',{colSpan:5,style:{textAlign:'center',padding:32,color:'var(--text-tertiary)'}},'جاري التحميل...')) :
              commData.length === 0 ? h('tr', null, h('td',{colSpan:5,style:{textAlign:'center',padding:32,color:'var(--text-tertiary)'}},'لا توجد جلسات في هذا الشهر')) :
              commData.map((d,i) => h('tr',{key:i},
                h('td',{style:{fontWeight:700}}, d.name),
                h('td',null, d.sessions + ' جلسة'),
                h('td',{style:{fontWeight:700}}, window.fmtEGP(d.totalPaid)),
                h('td',null, Math.round(d.rate*100) + '%'),
                h('td',{style:{fontWeight:800,color:'var(--success)',fontSize:16}}, window.fmtEGP(Math.round(d.totalComm))),
              )),
            ),
          ),
          commData.length > 0 && h('div', {style:{padding:'12px 20px',background:'var(--bg-subtle)',display:'flex',justifyContent:'space-between',borderTop:'1px solid var(--border)'}},
            h('span',{style:{fontWeight:700}},'إجمالي العمولات المستحقة للشهر:'),
            h('span',{style:{fontWeight:900,fontSize:18,color:'var(--accent)'}},
              window.fmtEGP(commData.reduce((s,d)=>s+d.totalComm,0))),
          ),
        ),
      ),

      /* ===== الملخص اليومي ===== */
      repTab === 'daily' && h('div', null,
        h('div', { className:'grid cols-4 mb-16' },
          [
            { label:'إيراد اليوم', val:window.fmtEGP(todayRevenue), icon:Icons.DollarSign, color:'var(--success)' },
            { label:'فواتير اليوم', val:todayInvoices.length, icon:Icons.FileText, color:'var(--accent)' },
            { label:'مواعيد اليوم', val:todayAppts.length, icon:Icons.Calendar, color:'var(--info)' },
            { label:'مخزون منخفض', val:lowStock.length, icon:Icons.AlertTriangle, color: lowStock.length>0?'var(--danger)':'var(--success)' },
          ].map((k,i) => h('div',{key:i,className:'card kpi'},
            h('div',{className:'flex jc-sb ai-c'},
              h('div',null,
                h('div',{className:'label'},k.label),
                h('div',{className:'value'},k.val),
              ),
              h('div',{className:'kpi-icon',style:{background:'var(--bg-subtle)',color:k.color}}, h(k.icon,{size:20})),
            ),
          )),
        ),
        h('div',{className:'grid cols-2',style:{gap:16}},
          h('div',{className:'card p-20'},
            h('div',{style:{fontWeight:800,fontSize:14,marginBottom:12}}, '📅 مواعيد الغد ('+tomorrowAppts.length+')'),
            tomorrowAppts.length === 0 ? h('div',{style:{color:'var(--text-tertiary)',fontSize:13}},'لا توجد مواعيد') :
            h('div',{style:{display:'flex',flexDirection:'column',gap:6}},
              tomorrowAppts.slice(0,6).map((a,i)=>h('div',{key:i,style:{display:'flex',justifyContent:'space-between',padding:'8px 10px',background:'var(--bg-subtle)',borderRadius:'var(--radius)',fontSize:13}},
                h('span',{style:{fontWeight:600}}, a.patient),
                h('span',{style:{color:'var(--text-tertiary)'}}, a.time + ' · ' + a.doctor),
              )),
            ),
          ),
          h('div',{className:'card p-20'},
            h('div',{style:{fontWeight:800,fontSize:14,marginBottom:12}}, '⚠️ مخزون منخفض ('+lowStock.length+')'),
            lowStock.length === 0 ? h('div',{style:{color:'var(--success)',fontSize:13}},'✅ كل الأصناف بمستوى كافٍ') :
            h('div',{style:{display:'flex',flexDirection:'column',gap:6}},
              lowStock.slice(0,6).map((it,i)=>h('div',{key:i,style:{display:'flex',justifyContent:'space-between',padding:'8px 10px',background:'var(--danger-soft)',borderRadius:'var(--radius)',fontSize:13}},
                h('span',{style:{fontWeight:600,color:'var(--danger)'}},it.name),
                h('span',{style:{color:'var(--danger)'}}, window.fmtNum(it.stock)+'/'+window.fmtNum(it.minStock)+' '+it.unit),
              )),
            ),
          ),
        ),
        h('div',{className:'card p-20 mt-16'},
          h('div',{style:{fontWeight:800,fontSize:14,marginBottom:12}},'📤 نسخ للواتساب'),
          h('pre',{style:{background:'var(--bg-subtle)',padding:16,borderRadius:'var(--radius)',fontSize:13,fontFamily:'inherit',whiteSpace:'pre-wrap',lineHeight:1.8}},
            dailySummaryText()),
          h('button',{className:'btn primary mt-12',onClick:()=>{navigator.clipboard?.writeText(dailySummaryText());window.toast&&window.toast('تم النسخ ✅');}},
            h(Icons.Copy,{size:14}), 'نسخ للواتساب'),
        ),
      ),

      /* ===== نظرة عامة (الأصلية) ===== */
      repTab === 'overview' && h(Fragment, null,
      h('div', { className: 'grid cols-4 mb-16' },
        [
          { label: 'إيرادات الشهر', value: '342,500 ج.م', trend: '+18.4%', up: true, icon: Icons.DollarSign, color: 'var(--success)' },
          { label: 'مرضى جدد', value: '47', trend: '+12', up: true, icon: Icons.UserPlus, color: 'var(--accent)' },
          { label: 'مواعيد مكتملة', value: '284', trend: '+8%', up: true, icon: Icons.Check, color: 'var(--info)' },
          { label: 'معدل الإلغاء', value: '4.2%', trend: '-1.1%', up: false, icon: Icons.X, color: 'var(--warning)' },
        ].map((k, i) => h('div', { key: i, className: 'card kpi' },
          h('div', { className: 'flex jc-sb ai-c' },
            h('div', null,
              h('div', { className: 'label' }, k.label),
              h('div', { className: 'value' }, k.value),
              h('div', { className: 'trend ' + (k.up ? 'up' : 'down') },
                h(k.up ? Icons.TrendingUp : Icons.TrendingDown, { size: 14 }), k.trend,
              ),
            ),
            h('div', { className: 'kpi-icon', style: { background: 'var(--bg-subtle)', color: k.color } }, h(k.icon, { size: 20 })),
          ),
        )),
      ),
      h('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { className: 'flex jc-sb ai-c mb-16' },
            h('div', { style: { fontWeight: 800, fontSize: 15 } }, 'الإيرادات الشهرية'),
            h('div', { className: 'flex gap-8' },
              h('span', { className: 'chip', style: { background: 'var(--accent-soft)', color: 'var(--accent)' } }, '● إيرادات'),
              h('span', { className: 'chip' }, '● مصروفات'),
            ),
          ),
          h(LineChart, { data: [120, 145, 180, 165, 210, 195, 240, 260, 285, 305, 325, 342], expenses: [80, 95, 110, 100, 130, 120, 150, 160, 175, 185, 195, 210] }),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 16 } }, 'أكثر الإجراءات طلباً'),
          [
            { name: 'كشف وفحص', count: 142, color: 'var(--accent)' },
            { name: 'تنظيف وتلميع', count: 98, color: 'var(--info)' },
            { name: 'حشو كومبوزيت', count: 76, color: 'var(--success)' },
            { name: 'حشو عصب', count: 45, color: 'var(--warning)' },
            { name: 'تبييض', count: 28, color: 'var(--purple)' },
          ].map((p, i) => h('div', { key: i, style: { marginBottom: 12 } },
            h('div', { className: 'flex jc-sb ai-c mb-4' },
              h('span', { style: { fontSize: 13, fontWeight: 600 } }, p.name),
              h('span', { style: { fontSize: 13, fontWeight: 800 } }, p.count),
            ),
            h('div', { className: 'progress' }, h('div', { className: 'progress-bar', style: { width: (p.count / 142 * 100) + '%', background: p.color } })),
          )),
        ),
      ),
      h('div', { className: 'grid cols-3 mt-16' },
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 14, marginBottom: 12 } }, 'توزيع المرضى حسب العمر'),
          h(DonutChart, {
            data: [
              { label: 'أطفال', value: 18, color: 'var(--accent)' },
              { label: 'شباب', value: 42, color: 'var(--info)' },
              { label: 'كبار', value: 30, color: 'var(--success)' },
              { label: 'مسنون', value: 10, color: 'var(--warning)' },
            ],
          }),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 14, marginBottom: 12 } }, 'أفضل الأطباء'),
          window.DOCTORS.map((d, i) => h('div', { key: d.id, className: 'flex ai-c gap-10', style: { padding: '8px 0', borderBottom: i < 3 ? '1px solid var(--border)' : 'none' } },
            h('div', { style: { width: 20, fontSize: 14, fontWeight: 800, color: 'var(--text-tertiary)' } }, '#' + (i + 1)),
            h('div', { className: 'avatar sm', style: { background: d.color } }, d.avatar),
            h('div', { style: { flex: 1 } },
              h('div', { style: { fontSize: 13, fontWeight: 700 } }, d.name),
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, d.patients + ' مريض'),
            ),
            h('div', { style: { fontSize: 13, fontWeight: 800 } }, '★ ' + d.rating),
          )),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 14, marginBottom: 12 } }, 'مقارنة التأمين'),
          [
            { name: 'مصر للتأمين', amount: 125000, pct: 42 },
            { name: 'بوبا العربية', amount: 98000, pct: 33 },
            { name: 'أكسا', amount: 48000, pct: 16 },
            { name: 'الأهلي', amount: 27000, pct: 9 },
          ].map((t, i) => h('div', { key: i, style: { marginBottom: 12 } },
            h('div', { className: 'flex jc-sb ai-c', style: { fontSize: 12 } },
              h('span', { style: { fontWeight: 600 } }, t.name),
              h('span', { style: { color: 'var(--text-tertiary)' } }, t.pct + '%'),
            ),
            h('div', { className: 'progress', style: { marginTop: 4 } }, h('div', { className: 'progress-bar', style: { width: t.pct + '%' } })),
          )),
        ),
      ),
    ),
    ),
  );
}

function LineChart({ data, expenses }) {
  const max = Math.max(...data, ...expenses);
  const w = 100, h2 = 60;
  const path = (arr) => arr.map((v, i) => `${i === 0 ? 'M' : 'L'} ${(i / (arr.length - 1)) * w} ${h2 - (v / max) * h2}`).join(' ');
  const area = (arr) => `${path(arr)} L ${w} ${h2} L 0 ${h2} Z`;
  return h('div', null,
    h('svg', { viewBox: `0 0 ${w} ${h2}`, preserveAspectRatio: 'none', style: { width: '100%', height: 200 } },
      h('path', { d: area(data), fill: 'var(--accent)', fillOpacity: 0.15 }),
      h('path', { d: path(data), fill: 'none', stroke: 'var(--accent)', strokeWidth: 0.6, strokeLinecap: 'round' }),
      h('path', { d: path(expenses), fill: 'none', stroke: 'var(--text-tertiary)', strokeWidth: 0.5, strokeDasharray: '2 1' }),
    ),
    h('div', { className: 'flex jc-sb', style: { fontSize: 10, color: 'var(--text-tertiary)', marginTop: 8 } },
      ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'].map((m, i) => h('span', { key: i }, m.slice(0, 3))),
    ),
  );
}

function DonutChart({ data }) {
  const total = data.reduce((s, d) => s + d.value, 0);
  let offset = 0;
  const C = 2 * Math.PI * 40;
  return h('div', { style: { display: 'flex', alignItems: 'center', gap: 16 } },
    h('svg', { width: 120, height: 120, viewBox: '0 0 120 120' },
      data.map((d, i) => {
        const pct = d.value / total;
        const dash = pct * C;
        const seg = h('circle', {
          key: i, cx: 60, cy: 60, r: 40, fill: 'none', stroke: d.color, strokeWidth: 20,
          strokeDasharray: `${dash} ${C - dash}`, strokeDashoffset: -offset,
          transform: 'rotate(-90 60 60)',
        });
        offset += dash;
        return seg;
      }),
    ),
    h('div', { style: { flex: 1 } },
      data.map((d, i) => h('div', { key: i, className: 'flex ai-c gap-8', style: { padding: '4px 0', fontSize: 12 } },
        h('div', { style: { width: 10, height: 10, borderRadius: 2, background: d.color } }),
        h('span', { style: { flex: 1 } }, d.label),
        h('span', { style: { fontWeight: 700 } }, d.value + '%'),
      )),
    ),
  );
}

// ==================== Messages ====================
function Messages() {
  const [active, setActive] = useState('M1');
  const [text, setText] = useState('');
  const [thread, setThread] = useState([
    { id: 1, from: 'them', text: 'صباح الخير، هل أشعة المريض أحمد جاهزة؟', time: '10:22' },
    { id: 2, from: 'me', text: 'صباح النور، نعم تم رفعها منذ قليل على ملفه', time: '10:23' },
    { id: 3, from: 'them', text: 'ممتاز، سأراجعها الآن. شكراً!', time: '10:24' },
  ]);

  const activeThread = (window.MESSAGES || []).find(m => m.id === active) || (window.MESSAGES || [])[0] || {};

  return h('div', { className: 'fade-in', style: { height: '100%' } },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الدردشة الداخلية'),
        h('div', { className: 'page-subtitle' }, 'تواصل سريع بين أعضاء الفريق'),
      ),
    ),
    h('div', { className: 'page-content', style: { height: 'calc(100% - 100px)' } },
      h('div', { className: 'card', style: { display: 'grid', gridTemplateColumns: '300px 1fr', height: 'calc(100vh - 180px)', overflow: 'hidden' } },
        h('div', { style: { borderInlineEnd: '1px solid var(--border)', overflow: 'auto' } },
          h('div', { style: { padding: 12, borderBottom: '1px solid var(--border)' } },
            h('input', { className: 'input', placeholder: 'بحث في المحادثات...', style: { padding: 8, fontSize: 13 } }),
          ),
          window.MESSAGES.map(m => h('div', {
            key: m.id,
            onClick: () => setActive(m.id),
            style: {
              padding: '12px 14px', borderBottom: '1px solid var(--border)', cursor: 'pointer',
              background: active === m.id ? 'var(--accent-soft)' : 'transparent',
              display: 'flex', gap: 10, alignItems: 'center',
            },
          },
            h('div', { style: { position: 'relative' } },
              h('div', { className: 'avatar sm' }, m.avatar),
              m.online ? h('div', { style: { position: 'absolute', bottom: -2, insetInlineEnd: -2, width: 10, height: 10, borderRadius: '50%', background: 'var(--success)', border: '2px solid var(--bg-elevated)' } }) : null,
            ),
            h('div', { style: { flex: 1, minWidth: 0 } },
              h('div', { className: 'flex jc-sb ai-c' },
                h('div', { style: { fontSize: 13, fontWeight: 700, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, m.from),
                h('div', { style: { fontSize: 10, color: 'var(--text-tertiary)' } }, m.time),
              ),
              h('div', { className: 'flex jc-sb ai-c' },
                h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 } }, m.preview),
                m.unread ? h('span', { style: { background: 'var(--accent)', color: '#fff', fontSize: 10, fontWeight: 700, padding: '1px 6px', borderRadius: 999 } }, m.unread) : null,
              ),
            ),
          )),
        ),
        h('div', { style: { display: 'flex', flexDirection: 'column', overflow: 'hidden' } },
          h('div', { style: { padding: 14, borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12 } },
            h('div', { className: 'avatar sm' }, activeThread.avatar),
            h('div', { style: { flex: 1 } },
              h('div', { style: { fontWeight: 700 } }, activeThread.from),
              h('div', { style: { fontSize: 11, color: activeThread.online ? 'var(--success)' : 'var(--text-tertiary)' } }, activeThread.online ? 'متصل الآن' : 'غير متصل'),
            ),
            h('button', { className: 'icon-btn' }, h(Icons.Phone, { size: 16 })),
            h('button', { className: 'icon-btn' }, h(Icons.MoreHorizontal, { size: 16 })),
          ),
          h('div', { style: { flex: 1, overflowY: 'auto', padding: 20, display: 'flex', flexDirection: 'column', gap: 10 } },
            thread.map(m => h('div', {
              key: m.id,
              style: { display: 'flex', justifyContent: m.from === 'me' ? 'flex-start' : 'flex-end' },
            },
              h('div', {
                style: {
                  maxWidth: '70%', padding: '10px 14px',
                  background: m.from === 'me' ? 'var(--accent)' : 'var(--bg-subtle)',
                  color: m.from === 'me' ? '#fff' : 'var(--text-primary)',
                  borderRadius: m.from === 'me' ? '14px 14px 4px 14px' : '14px 14px 14px 4px',
                  fontSize: 13,
                },
              },
                h('div', null, m.text),
                h('div', { style: { fontSize: 10, opacity: 0.7, marginTop: 4, textAlign: 'end' } }, m.time),
              ),
            )),
          ),
          h('div', { style: { padding: 14, borderTop: '1px solid var(--border)', display: 'flex', gap: 8, alignItems: 'center' } },
            h('button', { className: 'icon-btn' }, h(Icons.Paperclip, { size: 18 })),
            h('input', {
              className: 'input', placeholder: 'اكتب رسالة...', value: text,
              onChange: (e) => setText(e.target.value),
              onKeyDown: (e) => {
                if (e.key === 'Enter' && text.trim()) {
                  setThread([...thread, { id: Date.now(), from: 'me', text, time: 'الآن' }]);
                  setText('');
                }
              },
            }),
            h('button', {
              className: 'btn primary',
              onClick: () => {
                if (!text.trim()) return;
                setThread([...thread, { id: Date.now(), from: 'me', text, time: 'الآن' }]);
                setText('');
              },
            }, h(Icons.Send, { size: 16 })),
          ),
        ),
      ),
    ),
  );
}

// ==================== Settings ====================
function Settings() {
  const { theme, setTheme, density, setDensity, clinicName, setClinicName } = useContext(AppContext);
  const [tab, setTab] = useState('general');
  const [roomCount, setRoomCount] = useState(() => parseInt(localStorage.getItem('senan-rooms') || '1', 10));
  const saveRooms = (n) => { const v = Math.max(1, Math.min(10, n)); setRoomCount(v); localStorage.setItem('senan-rooms', String(v)); };
  const [startHour, setStartHour] = useState(() => parseInt(localStorage.getItem('senan-start-hour') || '9', 10));
  const [endHour,   setEndHour]   = useState(() => parseInt(localStorage.getItem('senan-end-hour')   || '17', 10));
  const saveStartHour = (h) => { setStartHour(h); localStorage.setItem('senan-start-hour', String(h)); };
  const saveEndHour   = (h) => { setEndHour(h);   localStorage.setItem('senan-end-hour',   String(h)); };
  const hourLabel = (h) => {
    if (h === 0) return '12:00 ص';
    if (h < 12)  return h + ':00 ص';
    if (h === 12) return '12:00 م';
    return (h - 12) + ':00 م';
  };

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الإعدادات'),
        h('div', { className: 'page-subtitle' }, 'إدارة إعدادات العيادة والنظام'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { style: { display: 'grid', gridTemplateColumns: '240px 1fr', gap: 20 } },
        h('div', { className: 'card', style: { padding: 10, height: 'fit-content' } },
          [
            { id: 'general', label: 'عام', icon: Icons.Settings },
            { id: 'clinic', label: 'بيانات العيادة', icon: Icons.Building },
            { id: 'appearance', label: 'المظهر', icon: Icons.Sliders },
            { id: 'notifications', label: 'الإشعارات', icon: Icons.Bell },
            { id: 'billing-s', label: 'الفوترة والضرائب', icon: Icons.CreditCard },
            { id: 'integrations', label: 'التكاملات', icon: Icons.Zap },
            { id: 'security', label: 'الأمان', icon: Icons.Shield },
            { id: 'backup', label: 'النسخ الاحتياطي', icon: Icons.Database },
          ].map(s => h('button', {
            key: s.id,
            className: 'nav-item' + (tab === s.id ? ' active' : ''),
            onClick: () => setTab(s.id),
          },
            h('span', { className: 'icon-box' }, h(s.icon, { size: 16 })),
            h('span', null, s.label),
          )),
        ),
        h('div', { className: 'card p-24' },
          tab === 'general' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'الإعدادات العامة'),
            h('div', { className: 'grid', style: { gap: 16 } },
              h('div', null, h('div', { className: 'label' }, 'اللغة'), h('select', { className: 'select' }, h('option', null, 'العربية'), h('option', null, 'English'))),
              h('div', null, h('div', { className: 'label' }, 'المنطقة الزمنية'), h('select', { className: 'select' }, h('option', null, 'GMT+2 (القاهرة)'))),
              h('div', null, h('div', { className: 'label' }, 'العملة'), h('select', { className: 'select' }, h('option', null, 'الجنيه المصري (ج.م)'), h('option', null, 'الريال السعودي'))),
              h('div', null, h('div', { className: 'label' }, 'تنسيق التاريخ'), h('select', { className: 'select' }, h('option', null, 'DD-MM-YYYY'), h('option', null, 'YYYY-MM-DD'))),
            ),
          ),
          tab === 'clinic' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'بيانات العيادة'),
            h('div', { className: 'grid', style: { gap: 16 } },
              h('div', null, h('div', { className: 'label' }, 'اسم العيادة'), h('input', { className: 'input', value: clinicName, onChange: (e) => setClinicName(e.target.value) })),
              h('div', { className: 'grid cols-2', style: { gap: 12 } },
                h('div', null, h('div', { className: 'label' }, 'رقم الهاتف'), h('input', { className: 'input', defaultValue: '+20 2 2345 6789' })),
                h('div', null, h('div', { className: 'label' }, 'البريد الإلكتروني'), h('input', { className: 'input', defaultValue: 'info@senan.clinic' })),
              ),
              h('div', null, h('div', { className: 'label' }, 'العنوان'), h('input', { className: 'input', defaultValue: 'شارع التحرير، وسط البلد، القاهرة' })),
              h('div', null, h('div', { className: 'label' }, 'الرقم الضريبي'), h('input', { className: 'input', defaultValue: '123-456-789' })),
              h('div', null, h('div', { className: 'label' }, 'ساعات العمل'), h('input', { className: 'input', defaultValue: 'السبت - الخميس · 9 صباحاً - 9 مساءً' })),
              h('div', null,
                h('div', { className: 'label' }, 'عدد غرف العيادة'),
                h('div', { className: 'flex ai-c gap-12' },
                  h('button', { className: 'btn outline sm', onClick: () => saveRooms(roomCount - 1) }, '−'),
                  h('span', { style: { fontWeight: 800, fontSize: 20, minWidth: 32, textAlign: 'center' } }, roomCount),
                  h('button', { className: 'btn outline sm', onClick: () => saveRooms(roomCount + 1) }, '+'),
                  h('span', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, 'تنعكس فوراً على جدول المواعيد'),
                ),
              ),
              h('div', null,
                h('div', { className: 'label' }, 'ساعات جدول المواعيد'),
                h('div', { className: 'flex ai-c gap-12', style: { flexWrap: 'wrap' } },
                  h('div', { className: 'flex ai-c gap-8' },
                    h('span', { style: { fontSize: 13, color: 'var(--text-secondary)', minWidth: 40 } }, 'من'),
                    h('select', {
                      className: 'select',
                      style: { width: 120 },
                      value: startHour,
                      onChange: e => saveStartHour(parseInt(e.target.value)),
                    },
                      Array.from({ length: 18 }, (_, i) => i + 6).map(h_ =>
                        h('option', { key: h_, value: h_ }, hourLabel(h_))
                      ),
                    ),
                  ),
                  h('div', { className: 'flex ai-c gap-8' },
                    h('span', { style: { fontSize: 13, color: 'var(--text-secondary)', minWidth: 40 } }, 'إلى'),
                    h('select', {
                      className: 'select',
                      style: { width: 120 },
                      value: endHour,
                      onChange: e => saveEndHour(parseInt(e.target.value)),
                    },
                      Array.from({ length: 18 }, (_, i) => i + 7).map(h_ =>
                        h('option', { key: h_, value: h_, disabled: h_ <= startHour }, hourLabel(h_))
                      ),
                    ),
                  ),
                  h('span', { style: { fontSize: 12, color: 'var(--text-tertiary)' } },
                    `${endHour - startHour} ساعة · تنعكس فوراً على جدول المواعيد`),
                ),
              ),
            ),
            h('button', { className: 'btn primary mt-24' }, 'حفظ التغييرات'),
          ),
          tab === 'appearance' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'المظهر'),
            h('div', { className: 'label' }, 'الثيم'),
            h('div', { className: 'grid cols-3', style: { gap: 10, marginBottom: 20 } },
              [{ id: 'clean', name: 'طبي نظيف', desc: 'أبيض + تركواز هادئ' }, { id: 'luxe', name: 'فاخر داكن', desc: 'أسود + ذهبي' }, { id: 'warm', name: 'دافئ', desc: 'باستيل وأرضي' }].map(t => h('div', {
                key: t.id,
                onClick: () => setTheme(t.id),
                style: {
                  padding: 16, cursor: 'pointer', borderRadius: 'var(--radius)',
                  border: '2px solid ' + (theme === t.id ? 'var(--accent)' : 'var(--border)'),
                  background: theme === t.id ? 'var(--accent-soft)' : 'transparent',
                },
              },
                h('div', { className: 'theme-swatch', 'data-preview': t.id, style: { width: '100%', height: 50, marginBottom: 10, transform: 'none' } }),
                h('div', { style: { fontWeight: 700, fontSize: 14 } }, t.name),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2 } }, t.desc),
              )),
            ),
            h('div', { className: 'label' }, 'الكثافة'),
            h('div', { className: 'flex gap-8' },
              ['compact', 'comfortable'].map((d, i) => h('button', {
                key: d,
                className: 'btn ' + (density === d ? 'primary' : 'outline'),
                onClick: () => setDensity(d),
              }, i === 0 ? 'مدمجة' : 'مريحة')),
            ),
          ),
          tab === 'notifications' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'إعدادات الإشعارات'),
            h('div', { className: 'grid', style: { gap: 4 } },
              ['تذكيرات المواعيد (WhatsApp)', 'تذكيرات المواعيد (SMS)', 'تأكيد استلام المدفوعات', 'تنبيهات انخفاض المخزون', 'تنبيهات انتهاء الصلاحية', 'التقرير اليومي للمدير'].map((l, i) => h('label', {
                key: i,
                style: { padding: '14px 0', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', cursor: 'pointer' },
              },
                h('span', { style: { fontSize: 14 } }, l),
                h(Toggle, { defaultChecked: i < 4 }),
              )),
            ),
          ),
          tab === 'billing-s' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'الفوترة والضرائب'),
            h('div', { className: 'grid cols-2', style: { gap: 16 } },
              h('div', null, h('div', { className: 'label' }, 'نسبة الضريبة (%)'), h('input', { className: 'input', defaultValue: '14' })),
              h('div', null, h('div', { className: 'label' }, 'بادئة الفواتير'), h('input', { className: 'input', defaultValue: 'INV-2026-' })),
              h('div', null, h('div', { className: 'label' }, 'شروط الدفع'), h('input', { className: 'input', defaultValue: 'صافي 30 يوم' })),
              h('div', null, h('div', { className: 'label' }, 'العملة الافتراضية'), h('input', { className: 'input', defaultValue: 'ج.م' })),
            ),
          ),
          tab === 'integrations' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'التكاملات'),
            [
              { name: 'WhatsApp Business', desc: 'إرسال التذكيرات والتأكيدات تلقائياً', on: true },
              { name: 'بوابة الدفع Fawry', desc: 'تحصيل المدفوعات أونلاين', on: true },
              { name: 'Google Calendar', desc: 'مزامنة المواعيد مع جوجل', on: false },
              { name: 'نظام التأمين الموحد', desc: 'الربط مع شركات التأمين', on: true },
              { name: 'SMS Gateway', desc: 'إرسال رسائل نصية', on: false },
            ].map((it, i) => h('div', { key: i, style: { padding: 16, border: '1px solid var(--border)', borderRadius: 'var(--radius)', marginBottom: 10, display: 'flex', alignItems: 'center', gap: 12 } },
              h('div', { style: { width: 40, height: 40, borderRadius: 10, background: 'var(--bg-subtle)', display: 'grid', placeItems: 'center' } }, h(Icons.Zap, { size: 18 })),
              h('div', { style: { flex: 1 } },
                h('div', { style: { fontWeight: 700 } }, it.name),
                h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, it.desc),
              ),
              h(Toggle, { defaultChecked: it.on }),
            )),
          ),
          tab === 'security' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'الأمان'),
            h('div', { className: 'grid', style: { gap: 16 } },
              h('div', null, h('div', { className: 'label' }, 'كلمة المرور الحالية'), h('input', { className: 'input', type: 'password', defaultValue: '••••••••' })),
              h('div', null, h('div', { className: 'label' }, 'كلمة المرور الجديدة'), h('input', { className: 'input', type: 'password' })),
              h('label', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: 12, background: 'var(--bg-subtle)', borderRadius: 'var(--radius)' } },
                h('div', null,
                  h('div', { style: { fontWeight: 700 } }, 'التحقق بخطوتين'),
                  h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 } }, 'أمان إضافي لحسابك'),
                ),
                h(Toggle, { defaultChecked: true }),
              ),
            ),
          ),
          tab === 'backup' && h('div', null,
            h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'النسخ الاحتياطي'),
            h('div', { style: { padding: 16, background: 'var(--success-soft)', borderRadius: 'var(--radius)', color: 'var(--success)', fontWeight: 600, marginBottom: 16 } },
              h(Icons.Check, { size: 16, style: { display: 'inline-block', verticalAlign: 'text-bottom', marginLeft: 6 } }),
              'آخر نسخة احتياطية: اليوم 03:00 صباحاً',
            ),
            h('div', { className: 'grid cols-2', style: { gap: 12 } },
              h('button', { className: 'btn outline' }, h(Icons.Download, { size: 16 }), 'تصدير جميع البيانات'),
              h('button', { className: 'btn outline' }, h(Icons.Upload, { size: 16 }), 'استعادة من نسخة'),
            ),
          ),
        ),
      ),
    ),
  );
}

function Toggle({ defaultChecked }) {
  const [on, setOn] = useState(!!defaultChecked);
  return h('button', {
    onClick: () => setOn(!on),
    style: {
      width: 42, height: 24, borderRadius: 999, border: 'none',
      background: on ? 'var(--accent)' : 'var(--border-strong)',
      position: 'relative', cursor: 'pointer', transition: 'background 0.2s',
    },
  },
    h('div', {
      style: {
        width: 18, height: 18, borderRadius: '50%', background: '#fff',
        position: 'absolute', top: 3, insetInlineStart: on ? 21 : 3,
        transition: 'all 0.2s', boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
      },
    }),
  );
}

// ==================== Insurance ====================
function Insurance() {
  const providers = [
    { name: 'مصر للتأمين الصحي', patients: 42, claims: 18, approved: 15, pending: 3, amount: 125000, color: 'var(--accent)' },
    { name: 'بوبا العربية', patients: 28, claims: 12, approved: 11, pending: 1, amount: 98000, color: 'var(--info)' },
    { name: 'أكسا للتأمين', patients: 15, claims: 6, approved: 5, pending: 1, amount: 48000, color: 'var(--success)' },
    { name: 'الأهلي للتأمين', patients: 9, claims: 4, approved: 4, pending: 0, amount: 27000, color: 'var(--purple)' },
  ];
  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'التأمين الطبي'),
        h('div', { className: 'page-subtitle' }, '4 شركات تأمين · 40 مطالبة نشطة'),
      ),
      h('button', { className: 'btn primary' }, h(Icons.Plus, { size: 16 }), 'مطالبة جديدة'),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'grid cols-4 mb-24' },
        providers.map((p, i) => h('div', { key: i, className: 'card p-20' },
          h('div', { style: { width: 40, height: 40, borderRadius: 10, background: 'color-mix(in oklab, ' + p.color + ' 15%, var(--bg-elevated))', color: p.color, display: 'grid', placeItems: 'center', marginBottom: 12 } },
            h(Icons.Shield, { size: 20 }),
          ),
          h('div', { style: { fontWeight: 800, fontSize: 14 } }, p.name),
          h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 } }, p.patients + ' مريض'),
          h('div', { style: { fontSize: 20, fontWeight: 800, marginTop: 10 } }, window.fmtEGP(p.amount)),
          h('div', { className: 'flex gap-8 mt-8' },
            h('span', { className: 'chip success', style: { fontSize: 10 } }, p.approved + ' موافقة'),
            p.pending > 0 ? h('span', { className: 'chip warning', style: { fontSize: 10 } }, p.pending + ' معلقة') : null,
          ),
        )),
      ),
      h('div', { className: 'card', style: { overflow: 'hidden' } },
        h('div', { style: { padding: '16px 20px', borderBottom: '1px solid var(--border)', fontWeight: 800 } }, 'المطالبات الأخيرة'),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, ['رقم المطالبة', 'المريض', 'الشركة', 'التاريخ', 'المبلغ', 'المغطى', 'الحالة'].map((t, i) => h('th', { key: i }, t)))),
          h('tbody', null,
            [
              { id: 'CL-0142', patient: 'أحمد محمد', company: 'مصر للتأمين', date: '2026-04-12', amount: 2500, covered: 2000, status: 'approved' },
              { id: 'CL-0143', patient: 'فاطمة علي', company: 'أكسا', date: '2026-04-15', amount: 1500, covered: 1200, status: 'approved' },
              { id: 'CL-0144', patient: 'محمد عبد الرحمن', company: 'بوبا', date: '2026-04-10', amount: 4500, covered: 3600, status: 'pending' },
              { id: 'CL-0145', patient: 'نورهان إبراهيم', company: 'بوبا', date: '2026-03-28', amount: 500, covered: 0, status: 'rejected' },
            ].map(c => h('tr', { key: c.id },
              h('td', { style: { fontFamily: 'monospace', fontSize: 12, fontWeight: 700 } }, c.id),
              h('td', null, c.patient),
              h('td', null, c.company),
              h('td', { style: { fontSize: 13, color: 'var(--text-secondary)' } }, c.date),
              h('td', { style: { fontWeight: 700 } }, window.fmtEGP(c.amount)),
              h('td', { style: { fontWeight: 700, color: 'var(--success)' } }, window.fmtEGP(c.covered)),
              h('td', null, h('span', { className: 'chip ' + (c.status === 'approved' ? 'success' : c.status === 'pending' ? 'warning' : 'danger') },
                c.status === 'approved' ? 'موافق' : c.status === 'pending' ? 'قيد المراجعة' : 'مرفوض')),
            )),
          ),
        ),
      ),
    ),
  );
}

// ==================== Accounting ====================
const ACCOUNTING_EXPENSE_CATEGORY_OPTIONS = [
  'رواتب',
  'إيجار ومرافق',
  'صيانة ومعدات',
  'تسويق',
  'نقل',
  'اشتراكات',
  'أخرى',
];

function accountingTodayStr() {
  return getClinicTodayKey();
}

function accountingMonthKey(dateValue) {
  return String(dateValue || '').slice(0, 7);
}

function formatAccountingDate(dateValue) {
  if (!dateValue) return '—';
  const date = new Date(dateValue);
  if (Number.isNaN(date.getTime())) return String(dateValue);
  return window.fmtDate(date);
}

function classifyAccountingExpenseCategory(category) {
  const value = String(category || '').trim();
  if (!value) return 'other';
  if (/راتب|رواتب/u.test(value)) return 'salaries';
  if (/إيجار|ايجار|مرافق|كهرباء|مياه|إنترنت|انترنت/u.test(value)) return 'rent';
  if (/صيانة|معدات/u.test(value)) return 'maintenance';
  return 'other';
}

function openAccountingPrint(title, sections) {
  const body = `
    <div style="font-family:Arial, sans-serif; direction:rtl; padding:24px; max-width:900px; margin:auto">
      <h1 style="margin-bottom:8px">${printableText(title, '')}</h1>
      ${sections.map(section => `
        <div style="margin-bottom:24px">
          <h2 style="font-size:18px; margin:0 0 10px">${printableText(section.title, '')}</h2>
          ${section.rows && section.rows.length ? `
            <table style="width:100%; border-collapse:collapse">
              <thead>
                <tr>
                  ${section.columns.map(col => `<th style="border:1px solid #ddd; padding:8px; text-align:right; background:#f8fafc">${printableText(col, '')}</th>`).join('')}
                </tr>
              </thead>
              <tbody>
                ${section.rows.map(row => `
                  <tr>
                    ${row.map(cell => `<td style="border:1px solid #ddd; padding:8px; text-align:right">${printableText(cell, '')}</td>`).join('')}
                  </tr>
                `).join('')}
              </tbody>
            </table>
          ` : `<p style="color:#64748b">لا توجد بيانات</p>`}
        </div>
      `).join('')}
    </div>
  `;
  return openPrintableWindow({ title, bodyHtml: body, features: 'width=980,height=820' });
}

const ACCOUNTING_PAYMENT_METHOD_LABELS = {
  cash: 'كاش',
  card: 'كارت',
  transfer: 'تحويل',
  insurance: 'تأمين',
};

const ACCOUNTING_AUDIT_ENTITY_LABELS = {
  patient: 'مريض',
  patient_profile: 'ملف المريض',
  appointment: 'موعد',
  invoice: 'فاتورة',
  payment: 'دفعة',
  session: 'جلسة',
  cash_shift: 'وردية نقدية',
};

const ACCOUNTING_AUDIT_ACTION_LABELS = {
  create: 'إضافة',
  update: 'تعديل',
  delete: 'حذف',
  open: 'فتح',
  close: 'إقفال',
};

function formatAccountingPaymentMethod(method) {
  return ACCOUNTING_PAYMENT_METHOD_LABELS[String(method || '').trim()] || String(method || 'غير محدد');
}

function isAccountingPaymentActive(payment) {
  return String(payment?.status || 'posted').trim() !== 'cancelled';
}

function formatAccountingAuditEntity(entityType) {
  const key = String(entityType || '').trim();
  return ACCOUNTING_AUDIT_ENTITY_LABELS[key] || key || 'سجل';
}

function formatAccountingAuditAction(action) {
  const key = String(action || '').trim();
  return ACCOUNTING_AUDIT_ACTION_LABELS[key] || key || 'إجراء';
}

function formatAccountingAuditDetails(details = {}) {
  if (!details || typeof details !== 'object' || Array.isArray(details)) return '';
  if (details.name) return String(details.name);
  if (details.amount != null) return `المبلغ ${window.fmtEGP(details.amount)}`;
  if (details.total != null) return `الإجمالي ${window.fmtEGP(details.total)}`;
  if (details.openingBalance != null) return `رصيد افتتاحي ${window.fmtEGP(details.openingBalance)}`;
  if (details.expectedClose != null) return `إقفال متوقع ${window.fmtEGP(details.expectedClose)}`;
  if (Array.isArray(details.updatedFields) && details.updatedFields.length) return `${details.updatedFields.length} حقول تم تعديلها`;
  if (details.date || details.time) return [details.date, details.time].filter(Boolean).join(' · ');
  return '';
}

function CashShiftModal({ mode, shift, suggestedCashIn, onClose, onSaved }) {
  const { clinicId, toast } = useContext(AppContext);
  const isCloseMode = mode === 'close';
  const [saving, setSaving] = useState(false);
  const [form, setForm] = useState(() => (
    isCloseMode
      ? {
        closedBy: '',
        cashOut: 0,
        actualClose: Math.max(0, (Number(shift?.openingBalance) || 0) + (Number(suggestedCashIn) || 0)),
        notes: shift?.notes || '',
      }
      : {
        openingBalance: 0,
        openedBy: '',
        notes: '',
      }
  ));

  useEffect(() => {
    if (!isCloseMode) return;
    setForm({
      closedBy: '',
      cashOut: 0,
      actualClose: Math.max(0, (Number(shift?.openingBalance) || 0) + (Number(suggestedCashIn) || 0)),
      notes: shift?.notes || '',
    });
  }, [isCloseMode, shift, suggestedCashIn]);

  const closePreview = useMemo(() => {
    const openingBalance = Number(shift?.openingBalance) || 0;
    const cashIn = Number(suggestedCashIn) || 0;
    const cashOut = Number(form.cashOut) || 0;
    const expectedClose = openingBalance + cashIn - cashOut;
    const actualClose = Number(form.actualClose) || 0;
    const variance = actualClose - expectedClose;
    return { openingBalance, cashIn, cashOut, expectedClose, actualClose, variance };
  }, [form.actualClose, form.cashOut, shift, suggestedCashIn]);

  const handleSave = async () => {
    setSaving(true);
    try {
      if (isCloseMode) {
        if (!shift?.id) {
          toast('لا توجد وردية مفتوحة للإقفال');
          return;
        }
        const saved = await DB.closeCashShift(shift.id, {
          cash_in: closePreview.cashIn,
          cash_out: closePreview.cashOut,
          expected_close: closePreview.expectedClose,
          actual_close: closePreview.actualClose,
          variance: closePreview.variance,
          closed_by: form.closedBy,
          notes: form.notes,
        });
        toast('تم إقفال الوردية');
        onSaved(saved);
      } else {
        const saved = await DB.openCashShift(clinicId, {
          opening_balance: Number(form.openingBalance) || 0,
          opened_by: form.openedBy,
          notes: form.notes,
        });
        toast('تم فتح وردية جديدة');
        onSaved(saved);
      }
      onClose();
    } catch (error) {
      console.error(error);
      toast(isCloseMode ? 'تعذر إقفال الوردية' : 'تعذر فتح الوردية');
    } finally {
      setSaving(false);
    }
  };

  if (isCloseMode && !shift) return null;

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 452 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(520px, calc(100vw - 24px))',
        zIndex: 453,
        padding: 0,
        overflow: 'hidden',
      },
      onClick: (e) => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, isCloseMode ? 'إقفال الوردية النقدية' : 'فتح وردية نقدية'),
          h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 4 } }, isCloseMode ? 'راجع التحصيل النقدي ثم سجّل الإقفال الفعلي' : 'سجّل الرصيد الافتتاحي واسم المستلم'),
        ),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
      ),
      h('div', { style: { padding: 22, display: 'grid', gap: 14 } },
        isCloseMode ? h(Fragment, null,
          h('div', { className: 'grid cols-2', style: { gap: 10 } },
            [
              { label: 'الرصيد الافتتاحي', value: closePreview.openingBalance, color: 'var(--accent)' },
              { label: 'التحصيل النقدي', value: closePreview.cashIn, color: 'var(--success)' },
              { label: 'المصروف النقدي', value: closePreview.cashOut, color: 'var(--danger)' },
              { label: 'الإقفال المتوقع', value: closePreview.expectedClose, color: 'var(--info)' },
            ].map((item) => h('div', { key: item.label, className: 'card', style: { padding: 14, background: 'var(--bg-subtle)' } },
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 4 } }, item.label),
              h('div', { style: { fontSize: 18, fontWeight: 900, color: item.color } }, window.fmtEGP(item.value)),
            )),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 12 } },
            h('div', null,
              h('div', { className: 'label' }, 'المصروف النقدي'),
              h('input', { className: 'input', type: 'number', min: 0, value: form.cashOut, onChange: (e) => setForm(prev => ({ ...prev, cashOut: e.target.value })) }),
            ),
            h('div', null,
              h('div', { className: 'label' }, 'الإقفال الفعلي'),
              h('input', { className: 'input', type: 'number', min: 0, value: form.actualClose, onChange: (e) => setForm(prev => ({ ...prev, actualClose: e.target.value })) }),
            ),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 12 } },
            h('div', null,
              h('div', { className: 'label' }, 'أغلق بواسطة'),
              h('input', { className: 'input', value: form.closedBy, onChange: (e) => setForm(prev => ({ ...prev, closedBy: e.target.value })), placeholder: 'اسم المستلم' }),
            ),
            h('div', { className: 'card', style: { padding: 14, background: 'var(--bg-subtle)' } },
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 4 } }, 'الفارق'),
              h('div', { style: { fontSize: 18, fontWeight: 900, color: closePreview.variance === 0 ? 'var(--success)' : 'var(--warning)' } }, window.fmtEGP(closePreview.variance)),
            ),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'ملاحظات'),
            h('textarea', { className: 'textarea', rows: 3, value: form.notes, onChange: (e) => setForm(prev => ({ ...prev, notes: e.target.value })), placeholder: 'أي ملاحظات على الإقفال' }),
          ),
        ) : h(Fragment, null,
          h('div', { className: 'grid cols-2', style: { gap: 12 } },
            h('div', null,
              h('div', { className: 'label' }, 'الرصيد الافتتاحي'),
              h('input', { className: 'input', type: 'number', min: 0, value: form.openingBalance, onChange: (e) => setForm(prev => ({ ...prev, openingBalance: e.target.value })) }),
            ),
            h('div', null,
              h('div', { className: 'label' }, 'فتح بواسطة'),
              h('input', { className: 'input', value: form.openedBy, onChange: (e) => setForm(prev => ({ ...prev, openedBy: e.target.value })), placeholder: 'اسم المستلم' }),
            ),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'ملاحظات'),
            h('textarea', { className: 'textarea', rows: 3, value: form.notes, onChange: (e) => setForm(prev => ({ ...prev, notes: e.target.value })), placeholder: 'ملاحظات بداية الوردية' }),
          ),
        ),
      ),
      h('div', { style: { padding: '16px 22px', borderTop: '1px solid var(--border)', display: 'flex', gap: 8 } },
        h('button', { className: 'btn outline', style: { flex: 1 }, onClick: onClose }, 'إلغاء'),
        h('button', { className: 'btn primary', style: { flex: 1 }, disabled: saving, onClick: handleSave }, saving ? 'جاري الحفظ...' : (isCloseMode ? 'تأكيد الإقفال' : 'فتح الوردية')),
      ),
    ),
  );
}

function AccountingReportModal({ monthLabel, summary, monthlyInvoices, monthlyExpenses, monthlyPurchases, monthlySessions, onClose }) {
  const handlePrint = () => {
    openAccountingPrint('التقرير الشهري - ' + monthLabel, [
      {
        title: 'ملخص الشهر',
        columns: ['المؤشر', 'القيمة'],
        rows: [
          ['الإيرادات', window.fmtEGP(summary.revenue)],
          ['التحصيلات', window.fmtEGP(summary.collections)],
          ['نسبة التحصيل', summary.collectionRate.toFixed(1) + '%'],
          ['المديونيات', window.fmtEGP(summary.receivables)],
          ['المصروفات', window.fmtEGP(summary.expenses)],
          ['الرصيد الحالي', window.fmtEGP(summary.balance)],
          ['متوسط الدفع لكل جلسة', window.fmtEGP(summary.averagePerSession)],
          ['عدد الجلسات', String(summary.sessionCount)],
        ],
      },
      {
        title: 'فواتير الشهر',
        columns: ['التاريخ', 'المريض', 'الطبيب', 'الإجمالي', 'المدفوع'],
        rows: monthlyInvoices.map(inv => [
          formatAccountingDate(inv.date),
          inv.patient || '—',
          inv.doctorName || '—',
          window.fmtEGP(inv.total),
          window.fmtEGP(inv.paid),
        ]),
      },
      {
        title: 'المصروفات العامة',
        columns: ['التاريخ', 'الفئة', 'المستفيد', 'المبلغ'],
        rows: monthlyExpenses.map(exp => [
          formatAccountingDate(exp.date),
          exp.category || 'أخرى',
          exp.recipient || '—',
          window.fmtEGP(Number(exp.amount) || 0),
        ]),
      },
      {
        title: 'مشتريات الماتريال والأدوات',
        columns: ['التاريخ', 'المورد', 'الإجمالي', 'ملاحظات'],
        rows: monthlyPurchases.map(purchase => [
          formatAccountingDate(purchase.date),
          purchase.supplier || '—',
          window.fmtEGP(purchase.total),
          purchase.notes || '—',
        ]),
      },
      {
        title: 'الجلسات',
        columns: ['التاريخ', 'المريض', 'الطبيب', 'المدفوع', 'الشغل المنجز'],
        rows: monthlySessions.map(session => [
          formatAccountingDate(session.date),
          session.patient || '—',
          session.doctor || '—',
          window.fmtEGP(session.paidAmount),
          session.workDone || '—',
        ]),
      },
    ]);
  };

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 440 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(980px, calc(100vw - 32px))',
        maxHeight: '88vh',
        overflowY: 'auto',
        zIndex: 441,
        padding: 0,
      },
      onClick: (e) => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, 'التقرير الشهري'),
          h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, monthLabel),
        ),
        h('div', { className: 'flex gap-8' },
          h('button', { className: 'btn outline sm', onClick: handlePrint }, h(Icons.Printer, { size: 14 }), 'طباعة / حفظ PDF'),
          h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
        ),
      ),
      h('div', { style: { padding: 22 } },
        h('div', { className: 'grid cols-4 mb-16' },
          [
            { label: 'الإيرادات', value: summary.revenue, color: 'var(--accent)' },
            { label: 'التحصيلات', value: summary.collections, color: 'var(--success)' },
            { label: 'المديونيات', value: summary.receivables, color: 'var(--danger)' },
            { label: 'المصروفات', value: summary.expenses, color: 'var(--warning)' },
          ].map((card) => h('div', { key: card.label, className: 'card', style: { padding: 16, background: 'var(--bg-subtle)' } },
            h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 6 } }, card.label),
            h('div', { style: { fontSize: 24, fontWeight: 900, color: card.color } }, window.fmtEGP(card.value)),
          )),
        ),
        h('div', { style: { display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: 16, marginBottom: 16 } },
          h('div', { className: 'card', style: { padding: 18 } },
            h('div', { style: { fontWeight: 800, marginBottom: 12 } }, 'ملخص الأداء'),
            [
              ['نسبة التحصيل', summary.collectionRate.toFixed(1) + '%'],
              ['الرصيد الحالي', window.fmtEGP(summary.balance)],
              ['متوسط الدفع لكل جلسة', window.fmtEGP(summary.averagePerSession)],
              ['عدد الفواتير', String(monthlyInvoices.length)],
              ['عدد الجلسات', String(summary.sessionCount)],
            ].map(([label, value]) => h('div', {
              key: label,
              style: { display: 'flex', justifyContent: 'space-between', padding: '10px 0', borderBottom: '1px solid var(--border)' },
            },
              h('span', { style: { color: 'var(--text-secondary)' } }, label),
              h('span', { style: { fontWeight: 800 } }, value),
            )),
          ),
          h('div', { className: 'card', style: { padding: 18 } },
            h('div', { style: { fontWeight: 800, marginBottom: 12 } }, 'آخر حركة هذا الشهر'),
            ([
              ...monthlyInvoices.slice(0, 3).map(inv => ({ label: `فاتورة ${inv.patient || '—'}`, date: inv.date, amount: inv.paid, type: 'in' })),
              ...monthlyExpenses.slice(0, 2).map(exp => ({ label: exp.category || 'مصروف', date: exp.date, amount: Number(exp.amount) || 0, type: 'out' })),
              ...monthlyPurchases.slice(0, 2).map(purchase => ({ label: `شراء من ${purchase.supplier || 'مورد'}`, date: purchase.date, amount: purchase.total, type: 'out' })),
            ].sort((a, b) => new Date(b.date || 0) - new Date(a.date || 0)).slice(0, 6)).map((row, idx) => h('div', {
              key: idx,
              style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px 0', borderBottom: idx < 5 ? '1px solid var(--border)' : 'none' },
            },
              h('div', null,
                h('div', { style: { fontWeight: 700, fontSize: 13 } }, row.label),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, formatAccountingDate(row.date)),
              ),
              h('div', { style: { fontWeight: 800, color: row.type === 'in' ? 'var(--success)' : 'var(--danger)' } },
                (row.type === 'in' ? '+' : '-') + window.fmtEGP(row.amount),
              ),
            )),
          ),
        ),
      ),
    ),
  );
}

function AccountingBreakdownModal({ title, total, rows, type, onClose }) {
  const columnsByType = {
    materials: ['المادة / الصنف', 'المورد', 'التاريخ', 'الكمية', 'سعر الوحدة', 'الإجمالي'],
    salaries: ['الاسم', 'النوع', 'التاريخ', 'المبلغ', 'ملاحظات'],
    generic: ['الوصف', 'الفئة', 'التاريخ', 'المبلغ', 'ملاحظات'],
  };
  const columns = columnsByType[type] || columnsByType.generic;

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 442 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(980px, calc(100vw - 32px))',
        maxHeight: '88vh',
        overflowY: 'auto',
        zIndex: 443,
        padding: 0,
      },
      onClick: (e) => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, title),
          h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, 'إجمالي ' + window.fmtEGP(total)),
        ),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
      ),
      h('div', { style: { padding: 22 } },
        rows.length ? h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, columns.map(col => h('th', { key: col }, col)))),
          h('tbody', null,
            rows.map((row, idx) => h('tr', { key: row.id || idx },
              type === 'materials' ? [
                h('td', { key: 'name' }, row.name || '—'),
                h('td', { key: 'supplier' }, row.supplier || '—'),
                h('td', { key: 'date' }, formatAccountingDate(row.date)),
                h('td', { key: 'qty' }, row.qty || '—'),
                h('td', { key: 'unitPrice' }, window.fmtEGP(row.unitPrice || 0)),
                h('td', { key: 'total', style: { fontWeight: 800 } }, window.fmtEGP(row.total || 0)),
              ] : type === 'salaries' ? [
                h('td', { key: 'recipient' }, row.recipient || '—'),
                h('td', { key: 'source' }, row.source === 'staff' ? 'راتب مسجل على الموظف' : 'مصروف رواتب'),
                h('td', { key: 'date' }, formatAccountingDate(row.date)),
                h('td', { key: 'amount', style: { fontWeight: 800 } }, window.fmtEGP(row.amount || 0)),
                h('td', { key: 'notes' }, row.notes || '—'),
              ] : [
                h('td', { key: 'desc' }, row.description || row.recipient || '—'),
                h('td', { key: 'category' }, row.category || 'أخرى'),
                h('td', { key: 'date' }, formatAccountingDate(row.date)),
                h('td', { key: 'amount', style: { fontWeight: 800 } }, window.fmtEGP(row.amount || 0)),
                h('td', { key: 'notes' }, row.notes || '—'),
              ],
            )),
          ),
        ) : h('div', {
          style: { padding: 40, textAlign: 'center', color: 'var(--text-tertiary)' },
        }, 'لا توجد تفاصيل متاحة حالياً'),
      ),
    ),
  );
}

function AddAccountingExpenseModal({ inventory, onClose, onSaved }) {
  const { clinicId, toast } = useContext(AppContext);
  const today = accountingTodayStr();
  const usageUnitsKey = `senan-inventory-usage-units:${clinicId || 'default'}`;
  const [mode, setMode] = useState('purchase');
  const [saving, setSaving] = useState(false);
  const [usageUnitsMap, setUsageUnitsMap] = useState({});
  const [purchaseForm, setPurchaseForm] = useState({
    supplier: '',
    date: today,
    notes: '',
    items: [{ inventory_id: '', name: '', qty: 1, unit_price: '' }],
  });
  const [expenseForm, setExpenseForm] = useState({
    category: ACCOUNTING_EXPENSE_CATEGORY_OPTIONS[0],
    amount: '',
    recipient: '',
    date: today,
    notes: '',
  });

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(usageUnitsKey);
      setUsageUnitsMap(raw ? JSON.parse(raw) : {});
    } catch (error) {
      console.warn('[Accounting Purchase] failed to load usage units map:', error);
      setUsageUnitsMap({});
    }
  }, [usageUnitsKey]);

  const extractInventoryPackMeta = (invItem) => {
    const cleanName = getInventoryDisplayName(invItem);
    const mappedUsageUnits = getInventoryUsageUnitsPerPack(invItem, usageUnitsMap);
    return {
      cleanName,
      usageUnitsPerPack: mappedUsageUnits,
      unit: invItem?.unit || 'قطعة',
    };
  };

  const getSelectedInventoryMeta = (inventoryId) => {
    const selected = (inventory || []).find(invItem => invItem.id === inventoryId);
    if (!selected) return null;
    return { ...selected, ...extractInventoryPackMeta(selected) };
  };

  const updatePurchaseItem = (index, key, value) => {
    setPurchaseForm(prev => ({
      ...prev,
      items: prev.items.map((item, itemIndex) => {
        if (itemIndex !== index) return item;
        if (key === 'inventory_id') {
          const selected = (inventory || []).find(invItem => invItem.id === value);
          const selectedMeta = selected ? extractInventoryPackMeta(selected) : null;
          return {
            ...item,
            inventory_id: value,
            name: selectedMeta ? selectedMeta.cleanName : item.name,
          };
        }
        return { ...item, [key]: value };
      }),
    }));
  };

  const addPurchaseItem = () => {
    setPurchaseForm(prev => ({
      ...prev,
      items: [...prev.items, { inventory_id: '', name: '', qty: 1, unit_price: '' }],
    }));
  };

  const removePurchaseItem = (index) => {
    setPurchaseForm(prev => ({
      ...prev,
      items: prev.items.filter((_, itemIndex) => itemIndex !== index),
    }));
  };
  const purchaseItemsTotal = purchaseForm.items.reduce((sum, item) => {
    return sum + ((Number(item.qty) || 0) * (Number(item.unit_price) || 0));
  }, 0);
  const handleSave = async () => {
    setSaving(true);
    try {
      if (mode === 'purchase') {
        const rows = purchaseForm.items
          .map(item => ({
            inventory_id: item.inventory_id || null,
            name: String(item.name || '').trim(),
            qty: Number(item.qty) || 0,
            unit_price: Number(item.unit_price) || 0,
          }))
          .filter(item => item.name && item.qty > 0 && item.unit_price >= 0);
        if (!rows.length) {
          toast('أضف صنف شراء واحد على الأقل');
          setSaving(false);
          return;
        }
        const purchase = await DB.addPurchaseInvoice(clinicId, {
          supplier: purchaseForm.supplier.trim() || null,
          date: purchaseForm.date || today,
          notes: purchaseForm.notes.trim() || null,
        }, rows);
        toast('تم تسجيل مشتريات الماتريال ✅');
        onSaved({ type: 'purchase', record: purchase });
      } else {
        const amount = Number(expenseForm.amount) || 0;
        if (amount <= 0) {
          toast('أدخل مبلغ المصروف');
          setSaving(false);
          return;
        }
        const expense = await DB.addExpense(clinicId, {
          category: expenseForm.category || 'أخرى',
          amount,
          recipient: expenseForm.recipient.trim() || null,
          date: expenseForm.date || today,
          notes: expenseForm.notes.trim() || null,
        });
        toast('تم تسجيل المصروف ✅');
        onSaved({ type: 'expense', record: expense });
      }
      onClose();
    } catch (error) {
      console.error(error);
      toast('تعذر حفظ العملية');
    } finally {
      setSaving(false);
    }
  };

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 444 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(920px, calc(100vw - 32px))',
        maxHeight: '88vh',
        overflowY: 'auto',
        zIndex: 445,
        padding: 0,
      },
      onClick: (e) => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, 'مصروف جديد'),
          h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, 'سجل شراء ماتريال أو مصروف عام من نفس الشاشة'),
        ),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
      ),
      h('div', { style: { padding: 22 } },
        h('div', { className: 'flex gap-8 mb-16' },
          [
            ['purchase', 'مشتريات الماتريال / الأدوات'],
            ['expense', 'مصروف عام'],
          ].map(([value, label]) => h('button', {
            key: value,
            className: 'btn ' + (mode === value ? 'primary' : 'outline'),
            onClick: () => setMode(value),
          }, label)),
        ),
        mode === 'purchase' ? h('div', null,
          h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12, marginBottom: 16 } },
            h('div', null,
              h('div', { className: 'label' }, 'المورد'),
              h('input', {
                className: 'input',
                value: purchaseForm.supplier,
                onChange: (e) => setPurchaseForm(prev => ({ ...prev, supplier: e.target.value })),
                placeholder: 'اسم المورد',
              }),
            ),
            h('div', null,
              h('div', { className: 'label' }, 'التاريخ'),
              h('input', {
                className: 'input',
                type: 'date',
                value: purchaseForm.date,
                onChange: (e) => setPurchaseForm(prev => ({ ...prev, date: e.target.value })),
              }),
            ),
            h('div', { style: { display: 'flex', alignItems: 'flex-end' } },
              h('button', { className: 'btn outline w-full', onClick: addPurchaseItem }, h(Icons.Plus, { size: 14 }), 'إضافة صنف'),
            ),
          ),
          h('div', { className: 'grid', style: { gap: 12 } },
            purchaseForm.items.map((item, index) => {
              const selectedMeta = getSelectedInventoryMeta(item.inventory_id);
              const lineTotal = (Number(item.qty) || 0) * (Number(item.unit_price) || 0);
              return h('div', {
              key: index,
              className: 'card',
              style: { padding: 16, background: 'var(--bg-subtle)' },
            },
              h('div', { style: { display: 'grid', gridTemplateColumns: '1.2fr 1fr 0.6fr 0.6fr 0.7fr auto', gap: 10, alignItems: 'end' } },
                h('div', null,
                  h('div', { className: 'label' }, 'الصنف / المادة'),
                  h('input', {
                    className: 'input',
                    value: item.name,
                    onChange: (e) => updatePurchaseItem(index, 'name', e.target.value),
                    placeholder: 'مثلاً: قفازات، كمامات، بوند',
                  }),
                ),
                h('div', null,
                  h('div', { className: 'label' }, 'من المخزون الحالي'),
                  h('select', {
                    className: 'input',
                    value: item.inventory_id,
                    onChange: (e) => updatePurchaseItem(index, 'inventory_id', e.target.value),
                  },
                    h('option', { value: '' }, 'اختياري'),
                    (inventory || []).map(invItem => {
                      const meta = extractInventoryPackMeta(invItem);
                      return h('option', { key: invItem.id, value: invItem.id }, meta.cleanName);
                    }),
                  ),
                ),
                h('div', null,
                  h('div', { className: 'label' }, selectedMeta ? `الكمية (${selectedMeta.unit})` : 'الكمية'),
                  h('input', {
                    className: 'input',
                    type: 'number',
                    min: '0',
                    value: item.qty,
                    onChange: (e) => updatePurchaseItem(index, 'qty', e.target.value),
                  }),
                ),
                h('div', null,
                  h('div', { className: 'label' }, selectedMeta ? `سعر ${selectedMeta.unit}` : 'سعر الوحدة'),
                  h('input', {
                    className: 'input',
                    type: 'number',
                    min: '0',
                    value: item.unit_price,
                    onChange: (e) => updatePurchaseItem(index, 'unit_price', e.target.value),
                  }),
                ),
                h('div', null,
                  h('div', { className: 'label' }, 'الإجمالي'),
                  h('div', { className: 'input', style: { display: 'flex', alignItems: 'center', fontWeight: 800, background: 'var(--bg-elevated)' } }, window.fmtEGP(lineTotal)),
                ),
                h('button', {
                  className: 'icon-btn',
                  style: { color: 'var(--danger)' },
                  onClick: () => removePurchaseItem(index),
                  disabled: purchaseForm.items.length === 1,
                }, h(Icons.Trash, { size: 14 })),
              ),
              selectedMeta && selectedMeta.usageUnitsPerPack > 0 ? h('div', {
                style: { marginTop: 10, fontSize: 12, color: 'var(--text-tertiary)' },
              }, `هذا الصنف يشتري كوحدة ${selectedMeta.unit}، والعبوة تكفي ${window.fmtNum(selectedMeta.usageUnitsPerPack)} حالة.`) : null,
            );
            }),
          ),
          h('div', {
            style: {
              marginTop: 16,
              padding: 16,
              borderRadius: 'var(--radius-md)',
              background: 'var(--bg-subtle)',
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'center',
              fontWeight: 800,
            },
          },
            h('span', { style: { color: 'var(--text-secondary)' } }, 'إجمالي المشتريات'),
            h('span', { style: { fontSize: 18 } }, window.fmtEGP(purchaseItemsTotal)),
          ),
          h('div', { style: { marginTop: 16 } },
            h('div', { className: 'label' }, 'ملاحظات'),
            h('textarea', {
              className: 'textarea',
              rows: 3,
              value: purchaseForm.notes,
              onChange: (e) => setPurchaseForm(prev => ({ ...prev, notes: e.target.value })),
              placeholder: 'أي ملاحظات على الفاتورة أو المشتريات',
            }),
          ),
        ) : h('div', null,
          h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 12, marginBottom: 16 } },
            h('div', null,
              h('div', { className: 'label' }, 'الفئة'),
              h('select', {
                className: 'input',
                value: expenseForm.category,
                onChange: (e) => setExpenseForm(prev => ({ ...prev, category: e.target.value })),
              },
                ACCOUNTING_EXPENSE_CATEGORY_OPTIONS.map(option => h('option', { key: option, value: option }, option)),
              ),
            ),
            h('div', null,
              h('div', { className: 'label' }, 'المبلغ'),
              h('input', {
                className: 'input',
                type: 'number',
                min: '0',
                value: expenseForm.amount,
                onChange: (e) => setExpenseForm(prev => ({ ...prev, amount: e.target.value })),
                placeholder: '0',
              }),
            ),
            h('div', null,
              h('div', { className: 'label' }, 'المستفيد / الجهة'),
              h('input', {
                className: 'input',
                value: expenseForm.recipient,
                onChange: (e) => setExpenseForm(prev => ({ ...prev, recipient: e.target.value })),
                placeholder: 'اسم الشخص أو الجهة',
              }),
            ),
            h('div', null,
              h('div', { className: 'label' }, 'التاريخ'),
              h('input', {
                className: 'input',
                type: 'date',
                value: expenseForm.date,
                onChange: (e) => setExpenseForm(prev => ({ ...prev, date: e.target.value })),
              }),
            ),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'ملاحظات'),
            h('textarea', {
              className: 'textarea',
              rows: 4,
              value: expenseForm.notes,
              onChange: (e) => setExpenseForm(prev => ({ ...prev, notes: e.target.value })),
              placeholder: 'سبب المصروف أو أي تفاصيل إضافية',
            }),
          ),
        ),
      ),
      h('div', { style: { padding: '18px 22px', borderTop: '1px solid var(--border)', display: 'flex', gap: 10, justifyContent: 'flex-end' } },
        h('button', { className: 'btn outline', onClick: onClose }, 'إلغاء'),
        h('button', { className: 'btn primary', onClick: handleSave, disabled: saving },
          saving ? 'جاري الحفظ...' : 'حفظ العملية',
        ),
      ),
    ),
  );
}

function AccountingTransactionsModal({ transactions, onClose, onEdit, onDelete }) {
  const [typeFilter, setTypeFilter] = useState('all');
  const [fromDate, setFromDate] = useState('');
  const [toDate, setToDate] = useState('');
  const [showDateFilter, setShowDateFilter] = useState(false);
  const [activeDatePreset, setActiveDatePreset] = useState('all');
  const selectedRangeLabel = window.getDateRangeLabel
    ? window.getDateRangeLabel(fromDate, toDate)
    : 'كل التواريخ';

  const applyDatePreset = (presetKey) => {
    const { fromValue, toValue } = window.resolveDateRangePreset
      ? window.resolveDateRangePreset(presetKey)
      : { fromValue: '', toValue: '' };
    setFromDate(fromValue || '');
    setToDate(toValue || '');
    setActiveDatePreset(presetKey);
    setShowDateFilter(false);
  };

  const clearDateRange = () => {
    setFromDate('');
    setToDate('');
    setActiveDatePreset('all');
    setShowDateFilter(false);
  };

  const visibleTransactions = useMemo(() => (
    (transactions || []).filter(tx => {
      if (typeFilter !== 'all') {
        if (typeFilter === 'income' && tx.flow !== 'in') return false;
        if (typeFilter === 'payment' && tx.kind !== 'payment') return false;
        if (typeFilter === 'expense' && tx.kind !== 'expense') return false;
        if (typeFilter === 'purchase' && tx.kind !== 'purchase') return false;
      }
      if (fromDate && (tx.date || '') < fromDate) return false;
      if (toDate && (tx.date || '') > toDate) return false;
      return true;
    })
  ), [transactions, typeFilter, fromDate, toDate]);

  const filteredTotalIn = visibleTransactions.filter(tx => tx.flow === 'in').reduce((sum, tx) => sum + (Number(tx.amount) || 0), 0);
  const filteredTotalOut = visibleTransactions.filter(tx => tx.flow === 'out').reduce((sum, tx) => sum + (Number(tx.amount) || 0), 0);

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 446 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(1180px, calc(100vw - 24px))',
        maxHeight: '90vh',
        overflowY: 'auto',
        zIndex: 447,
        padding: 0,
      },
      onClick: (e) => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, 'عرض كل المعاملات'),
          h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, 'فلتر بالتاريخ ثم عدّل أو احذف المصروفات والمشتريات'),
        ),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
      ),
      h('div', { style: { padding: 22 } },
        h('div', { className: 'grid cols-4 mb-16' },
          [
            { label: 'إجمالي الداخل', value: filteredTotalIn, color: 'var(--success)' },
            { label: 'إجمالي الخارج', value: filteredTotalOut, color: 'var(--danger)' },
            { label: 'عدد البنود', value: visibleTransactions.length, color: 'var(--accent)' },
            { label: 'الفرق', value: filteredTotalIn - filteredTotalOut, color: filteredTotalIn - filteredTotalOut >= 0 ? 'var(--success)' : 'var(--danger)' },
          ].map(card => h('div', { key: card.label, className: 'card', style: { padding: 14, background: 'var(--bg-subtle)' } },
            h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 6 } }, card.label),
            h('div', { style: { fontSize: 20, fontWeight: 900, color: card.color } }, typeof card.value === 'number' ? window.fmtEGP(card.value) : card.value),
          )),
        ),
        h('div', { className: 'card', style: { padding: 16, marginBottom: 16, background: 'var(--bg-subtle)' } },
          h('div', { style: { display: 'grid', gridTemplateColumns: 'minmax(260px, 1.2fr) 1fr auto', gap: 10, alignItems: 'end' } },
            h(Shell.DateRangeFilter, {
              title: 'فلتر التاريخ',
              subtitle: 'اختر فترة جاهزة أو حدد من يوم إلى يوم',
              dateFrom: fromDate,
              dateTo: toDate,
              open: showDateFilter,
              onToggle: () => setShowDateFilter(prev => !prev),
              onClose: () => setShowDateFilter(false),
              onPresetSelect: applyDatePreset,
              activePreset: activeDatePreset,
              onFromChange: (value) => {
                setFromDate(value);
                setActiveDatePreset('custom');
              },
              onToChange: (value) => {
                setToDate(value);
                setActiveDatePreset('custom');
              },
              onClear: clearDateRange,
              onApply: () => setShowDateFilter(false),
              align: 'start',
              buttonWidth: '100%',
              menuWidth: 'min(420px, calc(100vw - 48px))',
            }),
            h('div', null,
              h('div', { className: 'label' }, 'النوع'),
              h('select', { className: 'input', value: typeFilter, onChange: e => setTypeFilter(e.target.value) },
                h('option', { value: 'all' }, 'الكل'),
                h('option', { value: 'income' }, 'تحصيلات'),
                h('option', { value: 'payment' }, 'دفعات'),
                h('option', { value: 'expense' }, 'مصروفات'),
                h('option', { value: 'purchase' }, 'مشتريات'),
              ),
            ),
            h('button', {
              className: 'btn outline',
              onClick: () => { clearDateRange(); setTypeFilter('all'); },
            }, 'إعادة ضبط'),
          ),
          h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 10 } }, selectedRangeLabel),
        ),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null, ['التاريخ', 'النوع', 'البيان', 'المبلغ', 'الإجراء'].map((t, i) => h('th', { key: i }, t)))),
          h('tbody', null,
            visibleTransactions.length ? visibleTransactions.map(tx => h('tr', { key: tx.id },
              h('td', null, formatAccountingDate(tx.date)),
              h('td', null,
                h('span', {
                  className: 'chip ' + (tx.flow === 'in' ? 'success' : tx.kind === 'purchase' ? 'accent' : 'danger'),
                }, tx.kind === 'payment' ? 'دفعة' : tx.kind === 'purchase' ? 'مشتريات' : 'مصروف'),
              ),
              h('td', null,
                h('div', null,
                  h('div', { style: { fontWeight: 700 } }, tx.label),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2 } }, tx.subLabel || '—'),
                ),
              ),
              h('td', { style: { fontWeight: 800, color: tx.flow === 'in' ? 'var(--success)' : 'var(--danger)' } },
                (tx.flow === 'in' ? '+' : '-') + window.fmtEGP(tx.amount),
              ),
              h('td', null,
                h('div', { className: 'flex gap-4' },
                  tx.editable ? h('button', {
                    className: 'icon-btn',
                    title: 'تعديل',
                    onClick: () => onEdit(tx),
                  }, h(Icons.Edit, { size: 14 })) : h('span', { style: { color: 'var(--text-tertiary)', fontSize: 12 } }, '—'),
                  tx.editable ? h('button', {
                    className: 'icon-btn',
                    title: 'حذف',
                    style: { color: 'var(--danger)' },
                    onClick: () => onDelete(tx),
                  }, h(Icons.Trash, { size: 14 })) : null,
                ),
              ),
            )) : h('tr', null, h('td', { colSpan: 5, style: { textAlign: 'center', padding: 30, color: 'var(--text-tertiary)' } }, 'لا توجد معاملات مطابقة للفلتر')),
          ),
        ),
      ),
    ),
  );
}

function EditAccountingExpenseModal({ expense, onClose, onSaved, onDeleted }) {
  const { toast } = useContext(AppContext);
  const [form, setForm] = useState({
    category: expense.category || 'أخرى',
    amount: String(expense.amount || ''),
    recipient: expense.recipient || '',
    date: expense.date || new Date().toISOString().split('T')[0],
    notes: expense.notes || '',
  });
  const [saving, setSaving] = useState(false);

  const handleSave = async () => {
    const amount = Number(form.amount) || 0;
    if (amount <= 0) { toast('أدخل مبلغ المصروف'); return; }
    setSaving(true);
    try {
      const updated = await DB.updateExpense(expense.id, {
        category: form.category || 'أخرى',
        amount,
        recipient: form.recipient.trim() || null,
        date: form.date || new Date().toISOString().split('T')[0],
        notes: form.notes.trim() || null,
      });
      onSaved(updated);
      toast('تم تعديل المصروف');
      onClose();
    } catch (error) {
      console.error(error);
      toast('تعذر تعديل المصروف');
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!confirm('حذف هذا المصروف؟')) return;
    setSaving(true);
    try {
      await DB.deleteExpense(expense.id);
      onDeleted(expense.id);
      toast('تم حذف المصروف');
      onClose();
    } catch (error) {
      console.error(error);
      toast('تعذر حذف المصروف');
    } finally {
      setSaving(false);
    }
  };

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 448 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(760px, calc(100vw - 24px))',
        zIndex: 449,
        padding: 0,
      },
      onClick: e => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, 'تعديل مصروف'),
          h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, 'يمكنك تعديل الفئة أو المبلغ أو المستفيد'),
        ),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
      ),
      h('div', { style: { padding: 22 } },
        h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 12 } },
          h('div', null,
            h('div', { className: 'label' }, 'الفئة'),
            h('select', {
              className: 'input',
              value: form.category,
              onChange: e => setForm(prev => ({ ...prev, category: e.target.value })),
            },
              ACCOUNTING_EXPENSE_CATEGORY_OPTIONS.map(option => h('option', { key: option, value: option }, option)),
            ),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'المبلغ'),
            h('input', {
              className: 'input',
              type: 'number',
              min: '0',
              value: form.amount,
              onChange: e => setForm(prev => ({ ...prev, amount: e.target.value })),
            }),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'المستفيد / الجهة'),
            h('input', {
              className: 'input',
              value: form.recipient,
              onChange: e => setForm(prev => ({ ...prev, recipient: e.target.value })),
            }),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'التاريخ'),
            h('input', {
              className: 'input',
              type: 'date',
              value: form.date,
              onChange: e => setForm(prev => ({ ...prev, date: e.target.value })),
            }),
          ),
        ),
        h('div', { style: { marginTop: 16 } },
          h('div', { className: 'label' }, 'ملاحظات'),
          h('textarea', {
            className: 'textarea',
            rows: 4,
            value: form.notes,
            onChange: e => setForm(prev => ({ ...prev, notes: e.target.value })),
          }),
        ),
      ),
      h('div', { style: { padding: '18px 22px', borderTop: '1px solid var(--border)', display: 'flex', gap: 10, justifyContent: 'space-between' } },
        h('button', { className: 'btn outline', style: { color: 'var(--danger)' }, onClick: handleDelete, disabled: saving }, h(Icons.Trash, { size: 14 }), 'حذف'),
        h('div', { className: 'flex gap-8' },
          h('button', { className: 'btn outline', onClick: onClose }, 'إلغاء'),
          h('button', { className: 'btn primary', onClick: handleSave, disabled: saving }, saving ? 'جاري الحفظ...' : 'حفظ التعديل'),
        ),
      ),
    ),
  );
}

function EditPurchaseInvoiceModal({ purchase, inventory, onClose, onSaved, onDeleted }) {
  const { toast, clinicId } = useContext(AppContext);
  const usageUnitsKey = `senan-inventory-usage-units:${clinicId || 'default'}`;
  const [usageUnitsMap, setUsageUnitsMap] = useState({});
  const [form, setForm] = useState({
    supplier: purchase.supplier || '',
    date: purchase.date || new Date().toISOString().split('T')[0],
    notes: purchase.notes || '',
    items: (purchase.items && purchase.items.length ? purchase.items : [{ inventoryId: '', name: '', qty: 1, unitPrice: 0 }]).map(item => ({
      inventory_id: item.inventoryId || item.inventory_id || '',
      name: item.name || '',
      qty: item.qty || 1,
      unit_price: item.unitPrice || item.unit_price || 0,
    })),
  });
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(usageUnitsKey);
      setUsageUnitsMap(raw ? JSON.parse(raw) : {});
    } catch (error) {
      console.warn('[Edit Purchase] failed to load usage units map:', error);
      setUsageUnitsMap({});
    }
  }, [usageUnitsKey]);

  const extractInventoryPackMeta = (invItem) => {
    const cleanName = getInventoryDisplayName(invItem);
    const mappedUsageUnits = getInventoryUsageUnitsPerPack(invItem, usageUnitsMap);
    return {
      cleanName,
      usageUnitsPerPack: mappedUsageUnits,
      unit: invItem?.unit || 'قطعة',
    };
  };

  const getSelectedInventoryMeta = (inventoryId) => {
    const selected = (inventory || []).find(invItem => invItem.id === inventoryId);
    if (!selected) return null;
    return { ...selected, ...extractInventoryPackMeta(selected) };
  };

  const setItem = (index, key, value) => {
    setForm(prev => ({
      ...prev,
      items: prev.items.map((item, itemIndex) => {
        if (itemIndex !== index) return item;
        if (key === 'inventory_id') {
          const selected = (inventory || []).find(invItem => invItem.id === value);
          const selectedMeta = selected ? extractInventoryPackMeta(selected) : null;
          return { ...item, inventory_id: value, name: selectedMeta ? selectedMeta.cleanName : item.name };
        }
        return { ...item, [key]: value };
      }),
    }));
  };

  const addItem = () => setForm(prev => ({ ...prev, items: [...prev.items, { inventory_id: '', name: '', qty: 1, unit_price: 0 }] }));
  const removeItem = (index) => setForm(prev => ({ ...prev, items: prev.items.filter((_, itemIndex) => itemIndex !== index) }));
  const purchaseItemsTotal = form.items.reduce((sum, item) => {
    return sum + ((Number(item.qty) || 0) * (Number(item.unit_price) || 0));
  }, 0);

  const handleSave = async () => {
    const rows = form.items
      .map(item => ({
        inventory_id: item.inventory_id || null,
        name: String(item.name || '').trim(),
        qty: Number(item.qty) || 0,
        unit_price: Number(item.unit_price) || 0,
      }))
      .filter(item => item.name && item.qty > 0 && item.unit_price >= 0);
    if (!rows.length) {
      toast('أضف صنف شراء واحد على الأقل');
      return;
    }
    setSaving(true);
    try {
      const updated = await DB.updatePurchaseInvoice(purchase.id, {
        supplier: form.supplier.trim() || null,
        date: form.date || new Date().toISOString().split('T')[0],
        notes: form.notes.trim() || null,
      }, rows);
      onSaved(updated);
      toast('تم تعديل فاتورة المشتريات');
      onClose();
    } catch (error) {
      console.error(error);
      toast('تعذر تعديل الفاتورة');
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!confirm('حذف فاتورة المشتريات؟ سيتم عكس تأثيرها على المخزون.')) return;
    setSaving(true);
    try {
      await DB.deletePurchaseInvoice(purchase.id);
      onDeleted(purchase.id);
      toast('تم حذف فاتورة المشتريات');
      onClose();
    } catch (error) {
      console.error(error);
      toast('تعذر حذف الفاتورة');
    } finally {
      setSaving(false);
    }
  };

  return h(Fragment, null,
    h('div', { className: 'accounting-backdrop', onClick: onClose, style: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.35)', zIndex: 450 } }),
    h('div', {
      className: 'card accounting-modal',
      style: {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: 'min(980px, calc(100vw - 24px))',
        maxHeight: '90vh',
        overflowY: 'auto',
        zIndex: 451,
        padding: 0,
      },
      onClick: e => e.stopPropagation(),
    },
      h('div', { style: { padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 } },
        h('div', null,
          h('div', { style: { fontSize: 18, fontWeight: 800 } }, 'تعديل فاتورة مشتريات'),
          h('div', { style: { fontSize: 13, color: 'var(--text-tertiary)', marginTop: 4 } }, purchase.supplier || 'فاتورة مشتريات'),
        ),
        h('button', { className: 'icon-btn', onClick: onClose }, h(Icons.X, { size: 16 })),
      ),
      h('div', { style: { padding: 22 } },
        h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12, marginBottom: 16 } },
          h('div', null,
            h('div', { className: 'label' }, 'المورد'),
            h('input', { className: 'input', value: form.supplier, onChange: e => setForm(prev => ({ ...prev, supplier: e.target.value })) }),
          ),
          h('div', null,
            h('div', { className: 'label' }, 'التاريخ'),
            h('input', { className: 'input', type: 'date', value: form.date, onChange: e => setForm(prev => ({ ...prev, date: e.target.value })) }),
          ),
          h('div', { style: { display: 'flex', alignItems: 'flex-end' } },
            h('button', { className: 'btn outline w-full', onClick: addItem }, h(Icons.Plus, { size: 14 }), 'إضافة صنف'),
          ),
        ),
        h('div', { className: 'grid', style: { gap: 12 } },
          form.items.map((item, index) => {
            const selectedMeta = getSelectedInventoryMeta(item.inventory_id);
            const lineTotal = (Number(item.qty) || 0) * (Number(item.unit_price) || 0);
            return h('div', { key: index, className: 'card', style: { padding: 16, background: 'var(--bg-subtle)' } },
            h('div', { style: { display: 'grid', gridTemplateColumns: '1.2fr 1fr 0.6fr 0.6fr 0.7fr auto', gap: 10, alignItems: 'end' } },
              h('div', null,
                h('div', { className: 'label' }, 'الصنف / المادة'),
                h('input', { className: 'input', value: item.name, onChange: e => setItem(index, 'name', e.target.value) }),
              ),
              h('div', null,
                h('div', { className: 'label' }, 'من المخزون الحالي'),
                h('select', { className: 'input', value: item.inventory_id, onChange: e => setItem(index, 'inventory_id', e.target.value) },
                  h('option', { value: '' }, 'اختياري'),
                  (inventory || []).map(invItem => {
                    const meta = extractInventoryPackMeta(invItem);
                    return h('option', { key: invItem.id, value: invItem.id }, meta.cleanName);
                  }),
                ),
              ),
              h('div', null,
                h('div', { className: 'label' }, selectedMeta ? `الكمية (${selectedMeta.unit})` : 'الكمية'),
                h('input', { className: 'input', type: 'number', min: '0', value: item.qty, onChange: e => setItem(index, 'qty', e.target.value) }),
              ),
              h('div', null,
                h('div', { className: 'label' }, selectedMeta ? `سعر ${selectedMeta.unit}` : 'سعر الوحدة'),
                h('input', { className: 'input', type: 'number', min: '0', value: item.unit_price, onChange: e => setItem(index, 'unit_price', e.target.value) }),
              ),
              h('div', null,
                h('div', { className: 'label' }, 'الإجمالي'),
                h('div', { className: 'input', style: { display: 'flex', alignItems: 'center', fontWeight: 800, background: 'var(--bg-elevated)' } }, window.fmtEGP(lineTotal)),
              ),
              h('button', {
                className: 'icon-btn',
                style: { color: 'var(--danger)' },
                onClick: () => removeItem(index),
                disabled: form.items.length === 1,
              }, h(Icons.Trash, { size: 14 })),
            ),
            selectedMeta && selectedMeta.usageUnitsPerPack > 0 ? h('div', {
              style: { marginTop: 10, fontSize: 12, color: 'var(--text-tertiary)' },
            }, `هذا الصنف يشتري كوحدة ${selectedMeta.unit}، والعبوة تكفي ${window.fmtNum(selectedMeta.usageUnitsPerPack)} حالة.`) : null,
          );
          }),
        ),
        h('div', {
          style: {
            marginTop: 16,
            padding: 16,
            borderRadius: 'var(--radius-md)',
            background: 'var(--bg-subtle)',
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            fontWeight: 800,
          },
        },
          h('span', { style: { color: 'var(--text-secondary)' } }, 'إجمالي المشتريات'),
          h('span', { style: { fontSize: 18 } }, window.fmtEGP(purchaseItemsTotal)),
        ),
        h('div', { style: { marginTop: 16 } },
          h('div', { className: 'label' }, 'ملاحظات'),
          h('textarea', { className: 'textarea', rows: 4, value: form.notes, onChange: e => setForm(prev => ({ ...prev, notes: e.target.value })) }),
        ),
      ),
      h('div', { style: { padding: '18px 22px', borderTop: '1px solid var(--border)', display: 'flex', gap: 10, justifyContent: 'space-between' } },
        h('button', { className: 'btn outline', style: { color: 'var(--danger)' }, onClick: handleDelete, disabled: saving }, h(Icons.Trash, { size: 14 }), 'حذف'),
        h('div', { className: 'flex gap-8' },
          h('button', { className: 'btn outline', onClick: onClose }, 'إلغاء'),
          h('button', { className: 'btn primary', onClick: handleSave, disabled: saving }, saving ? 'جاري الحفظ...' : 'حفظ التعديل'),
        ),
      ),
    ),
  );
}

function Accounting() {
  const {
    invoices,
    expenses,
    inventory,
    staff,
    clinicId,
    toast,
    setExpenses,
    refreshData,
    payments,
    cashShifts,
    auditLog,
    setCashShifts,
  } = useContext(AppContext);
  const [purchaseInvoices, setPurchaseInvoices] = useState([]);
  const [sessions, setSessions] = useState([]);
  const [loadingExtras, setLoadingExtras] = useState(false);
  const [detailModal, setDetailModal] = useState(null);
  const [showExpenseModal, setShowExpenseModal] = useState(false);
  const [showReportModal, setShowReportModal] = useState(false);
  const [showTransactionsModal, setShowTransactionsModal] = useState(false);
  const [editingTransaction, setEditingTransaction] = useState(null);
  const [shiftModalMode, setShiftModalMode] = useState(null);

  const allInvoices = (invoices && invoices.length) ? invoices : (window.INVOICES || []);
  const allExpenses = (expenses && expenses.length) ? expenses : [];
  const allInventory = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
  const allPayments = Array.isArray(payments) ? payments : (window.PAYMENTS || []);
  const allCashShifts = Array.isArray(cashShifts) ? cashShifts : (window.CASH_SHIFTS || []);
  const allAuditLog = Array.isArray(auditLog) ? auditLog : (window.AUDIT_LOG || []);
  const todayStr = accountingTodayStr();
  const currentMonth = accountingMonthKey(todayStr);
  const monthLabel = window.fmtMonthYear(new Date(todayStr));
  const activePayments = useMemo(() => allPayments.filter(isAccountingPaymentActive), [allPayments]);
  const sortedPayments = useMemo(() => (
    [...activePayments].sort((a, b) => new Date(b.created_at || b.date || 0) - new Date(a.created_at || a.date || 0))
  ), [activePayments]);
  const sortedCashShifts = useMemo(() => (
    [...allCashShifts].sort((a, b) => new Date(b.openedAt || b.created_at || 0) - new Date(a.openedAt || a.created_at || 0))
  ), [allCashShifts]);
  const openCashShift = useMemo(() => sortedCashShifts.find(shift => shift.status === 'open') || null, [sortedCashShifts]);
  const recentAuditEntries = useMemo(() => (
    [...allAuditLog].sort((a, b) => new Date(b.created_at || 0) - new Date(a.created_at || 0)).slice(0, 7)
  ), [allAuditLog]);
  const paymentMethodSummary = useMemo(() => {
    const methodMap = new Map();
    activePayments.forEach((payment) => {
      const key = String(payment.method || 'cash').trim() || 'cash';
      const current = methodMap.get(key) || { key, label: formatAccountingPaymentMethod(key), total: 0, count: 0 };
      current.total += Number(payment.amount) || 0;
      current.count += 1;
      methodMap.set(key, current);
    });
    return [...methodMap.values()].sort((a, b) => b.total - a.total);
  }, [activePayments]);
  const todayPaymentTotal = useMemo(() => (
    activePayments
      .filter(payment => String(payment.date || '').slice(0, 10) === todayStr)
      .reduce((sum, payment) => sum + (Number(payment.amount) || 0), 0)
  ), [activePayments, todayStr]);
  const currentShiftCashIn = useMemo(() => {
    if (!openCashShift) return 0;
    const openedAt = new Date(openCashShift.openedAt || openCashShift.created_at || 0).getTime();
    const closedAt = openCashShift.closedAt ? new Date(openCashShift.closedAt).getTime() : Number.POSITIVE_INFINITY;
    return activePayments
      .filter(payment => String(payment.method || '').trim() === 'cash')
      .filter((payment) => {
        const paymentTime = new Date(payment.created_at || payment.date || 0).getTime();
        return paymentTime >= openedAt && paymentTime <= closedAt;
      })
      .reduce((sum, payment) => sum + (Number(payment.amount) || 0), 0);
  }, [activePayments, openCashShift]);
  const currentShiftExpectedClose = (Number(openCashShift?.openingBalance) || 0) + currentShiftCashIn;

  const loadAccountingExtras = useCallback(async () => {
    if (!clinicId) return;
    setLoadingExtras(true);
    try {
      const [purchaseRows, sessionRows] = await Promise.all([
        DB.getPurchaseInvoices(clinicId),
        DB.getClinicSessions(clinicId),
      ]);
      setPurchaseInvoices(purchaseRows || []);
      setSessions(sessionRows || []);
    } catch (error) {
      console.error('[Accounting] failed to load extras:', error);
      setPurchaseInvoices([]);
      setSessions([]);
      toast('تعذر تحميل تفاصيل المحاسبة');
    } finally {
      setLoadingExtras(false);
    }
  }, [clinicId, toast]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      if (cancelled) return;
      await loadAccountingExtras();
    })();
    return () => { cancelled = true; };
  }, [loadAccountingExtras]);

  useEffect(() => {
    const onRefresh = () => loadAccountingExtras();
    window.addEventListener('senan:accounting-refresh', onRefresh);
    return () => window.removeEventListener('senan:accounting-refresh', onRefresh);
  }, [loadAccountingExtras]);

  const metrics = useMemo(() => {
    const revenue = allInvoices.reduce((sum, inv) => sum + (Number(inv.total) || 0), 0);
    const collectionsFromInvoices = allInvoices.reduce((sum, inv) => sum + (Number(inv.paid) || 0), 0);
    const collectionsFromPayments = activePayments.reduce((sum, payment) => sum + (Number(payment.amount) || 0), 0);
    const collections = collectionsFromPayments > 0 ? collectionsFromPayments : collectionsFromInvoices;
    const receivables = Math.max(0, revenue - collections);
    const expensesOnly = allExpenses.reduce((sum, exp) => sum + (Number(exp.amount) || 0), 0);
    const materialsExpenses = purchaseInvoices.reduce((sum, purchase) => sum + (Number(purchase.total) || 0), 0);
    const totalExpenses = expensesOnly + materialsExpenses;
    const sessionCount = sessions.length;
    return {
      revenue,
      collections,
      collectionRate: revenue > 0 ? (collections / revenue) * 100 : 0,
      receivables,
      expenses: totalExpenses,
      materialsExpenses,
      expensesOnly,
      balance: collections - totalExpenses,
      averagePerSession: sessionCount > 0 ? collections / sessionCount : 0,
      sessionCount,
    };
  }, [activePayments, allExpenses, allInvoices, purchaseInvoices, sessions]);

  const salaryEntries = useMemo(() => {
    const expenseRows = allExpenses
      .filter(exp => classifyAccountingExpenseCategory(exp.category) === 'salaries')
      .map(exp => ({
        id: exp.id,
        recipient: exp.recipient || 'موظف غير محدد',
        amount: Number(exp.amount) || 0,
        date: exp.date || exp.created_at || '',
        notes: exp.notes || '',
        source: 'expense',
      }));
    const existingRecipients = new Set(expenseRows.map(row => `${row.recipient}|${row.amount}`));
    const fallbackStaffRows = (staff || [])
      .map(member => {
        const amount = Number(member.salary || member.base_salary || member.monthly_salary || 0) || 0;
        if (!amount) return null;
        const key = `${member.name || ''}|${amount}`;
        if (existingRecipients.has(key)) return null;
        return {
          id: member.id,
          recipient: member.name || 'موظف',
          amount,
          date: todayStr,
          notes: member.role || '',
          source: 'staff',
        };
      })
      .filter(Boolean);
    return [...expenseRows, ...fallbackStaffRows];
  }, [allExpenses, staff, todayStr]);

  const materialEntries = useMemo(() => (
    purchaseInvoices.flatMap(purchase => {
      if (!Array.isArray(purchase.items) || !purchase.items.length) {
        return [{
          id: purchase.id,
          name: purchase.notes || 'فاتورة مشتريات',
          supplier: purchase.supplier || '—',
          date: purchase.date,
          qty: 1,
          unitPrice: Number(purchase.total) || 0,
          total: Number(purchase.total) || 0,
        }];
      }
      return purchase.items.map(item => ({
        id: item.id,
        name: item.name || 'صنف غير محدد',
        supplier: purchase.supplier || '—',
        date: purchase.date,
        qty: item.qty || 0,
        unitPrice: item.unitPrice || 0,
        total: item.total || 0,
      }));
    })
  ), [purchaseInvoices]);

  const otherExpenseGroups = useMemo(() => {
    const groups = {
      rent: allExpenses.filter(exp => classifyAccountingExpenseCategory(exp.category) === 'rent'),
      maintenance: allExpenses.filter(exp => classifyAccountingExpenseCategory(exp.category) === 'maintenance'),
      other: allExpenses.filter(exp => classifyAccountingExpenseCategory(exp.category) === 'other'),
    };
    return groups;
  }, [allExpenses]);

  const expenseDistribution = useMemo(() => {
    const rows = [
      {
        key: 'materials',
        label: 'الماتريال والمستلزمات',
        color: 'var(--info)',
        total: metrics.materialsExpenses,
        rows: materialEntries,
        type: 'materials',
      },
      {
        key: 'salaries',
        label: 'الرواتب',
        color: 'var(--accent)',
        total: salaryEntries.reduce((sum, row) => sum + (row.amount || 0), 0),
        rows: salaryEntries,
        type: 'salaries',
      },
      {
        key: 'rent',
        label: 'الإيجار والمرافق',
        color: 'var(--warning)',
        total: otherExpenseGroups.rent.reduce((sum, row) => sum + (Number(row.amount) || 0), 0),
        rows: otherExpenseGroups.rent.map(row => ({
          id: row.id,
          description: row.recipient || row.notes || 'مصروف مرافق',
          category: row.category,
          date: row.date || row.created_at || '',
          amount: Number(row.amount) || 0,
          notes: row.notes || '',
        })),
        type: 'generic',
      },
      {
        key: 'maintenance',
        label: 'الصيانة والمعدات',
        color: 'var(--success)',
        total: otherExpenseGroups.maintenance.reduce((sum, row) => sum + (Number(row.amount) || 0), 0),
        rows: otherExpenseGroups.maintenance.map(row => ({
          id: row.id,
          description: row.recipient || row.notes || 'صيانة أو معدات',
          category: row.category,
          date: row.date || row.created_at || '',
          amount: Number(row.amount) || 0,
          notes: row.notes || '',
        })),
        type: 'generic',
      },
      {
        key: 'other',
        label: 'مصاريف أخرى',
        color: 'var(--purple)',
        total: otherExpenseGroups.other.reduce((sum, row) => sum + (Number(row.amount) || 0), 0),
        rows: otherExpenseGroups.other.map(row => ({
          id: row.id,
          description: row.recipient || row.notes || 'مصروف عام',
          category: row.category,
          date: row.date || row.created_at || '',
          amount: Number(row.amount) || 0,
          notes: row.notes || '',
        })),
        type: 'generic',
      },
    ];
    return rows.filter(row => row.total > 0 || row.rows.length > 0);
  }, [materialEntries, metrics.materialsExpenses, otherExpenseGroups, salaryEntries]);

  const allTransactions = useMemo(() => (
    [
      ...(sortedPayments.length ? sortedPayments : sessions
        .filter(session => (Number(session.paidAmount) || 0) > 0)
      )
        .map((row) => {
          if (row.amount != null) {
            return {
              id: 'payment-' + row.id,
              kind: 'payment',
              flow: 'in',
              label: `دفعة ${row.patient || '—'}`,
              subLabel: [
                formatAccountingPaymentMethod(row.method),
                row.sourceType === 'session' ? 'ناتجة من جلسة' : 'تحصيل يدوي',
                row.receivedBy || '',
              ].filter(Boolean).join(' · ') || '—',
              amount: Number(row.amount) || 0,
              date: row.date || row.created_at || '',
              created_at: row.created_at || '',
              editable: false,
            };
          }
          return {
            id: 'session-' + row.id,
            kind: 'payment',
            flow: 'in',
            label: `جلسة ${row.patient || '—'}`,
            subLabel: [
              row.doctor || '',
              row.workDone || '',
              'دفعة جلسة',
            ].filter(Boolean).join(' · ') || '—',
            amount: Number(row.paidAmount) || 0,
            date: row.date || row.created_at || '',
            created_at: row.created_at || '',
            editable: false,
          };
        }),
      ...allExpenses.map(exp => ({
        id: 'expense-' + exp.id,
        kind: 'expense',
        flow: 'out',
        label: exp.category || 'مصروف عام',
        subLabel: exp.recipient || exp.notes || '—',
        amount: Number(exp.amount) || 0,
        date: exp.date || exp.created_at || '',
        created_at: exp.created_at || '',
        editable: true,
        record: exp,
      })),
      ...purchaseInvoices.map(purchase => ({
        id: 'purchase-' + purchase.id,
        kind: 'purchase',
        flow: 'out',
        label: `شراء ${purchase.supplier || 'مورد'}`,
        subLabel: `${(purchase.items || []).length} أصناف`,
        amount: Number(purchase.total) || 0,
        date: purchase.date || purchase.created_at || '',
        created_at: purchase.created_at || '',
        editable: true,
        record: purchase,
      })),
    ]
      .filter(item => item.amount > 0)
      .sort((a, b) => {
        const aTime = new Date(a.created_at || a.date || 0).getTime();
        const bTime = new Date(b.created_at || b.date || 0).getTime();
        if (bTime !== aTime) return bTime - aTime;
        return new Date(b.date || 0).getTime() - new Date(a.date || 0).getTime();
      })
  ), [allExpenses, purchaseInvoices, sessions, sortedPayments]);

  const latestTransactions = useMemo(() => allTransactions.slice(0, 8), [allTransactions]);

  const monthlyData = useMemo(() => {
    const monthlyInvoices = allInvoices.filter(inv => accountingMonthKey(inv.date || inv.created_at) === currentMonth);
    const monthlyExpenses = allExpenses.filter(exp => accountingMonthKey(exp.date || exp.created_at) === currentMonth);
    const monthlyPurchases = purchaseInvoices.filter(purchase => accountingMonthKey(purchase.date || purchase.created_at) === currentMonth);
    const monthlySessions = sessions.filter(session => accountingMonthKey(session.date || session.created_at) === currentMonth);
    const monthlyPayments = activePayments.filter(payment => accountingMonthKey(payment.date || payment.created_at) === currentMonth);
    const monthlyRevenue = monthlyInvoices.reduce((sum, inv) => sum + (Number(inv.total) || 0), 0);
    const monthlyCollectionsFromInvoices = monthlyInvoices.reduce((sum, inv) => sum + (Number(inv.paid) || 0), 0);
    const monthlyCollectionsFromPayments = monthlyPayments.reduce((sum, payment) => sum + (Number(payment.amount) || 0), 0);
    const monthlyCollections = monthlyCollectionsFromPayments > 0 ? monthlyCollectionsFromPayments : monthlyCollectionsFromInvoices;
    const monthlyExpensesTotal = monthlyExpenses.reduce((sum, exp) => sum + (Number(exp.amount) || 0), 0)
      + monthlyPurchases.reduce((sum, purchase) => sum + (Number(purchase.total) || 0), 0);
    return {
      monthlyInvoices,
      monthlyExpenses,
      monthlyPurchases,
      monthlySessions,
      summary: {
        revenue: monthlyRevenue,
        collections: monthlyCollections,
        collectionRate: monthlyRevenue > 0 ? (monthlyCollections / monthlyRevenue) * 100 : 0,
        receivables: Math.max(0, monthlyRevenue - monthlyCollections),
        expenses: monthlyExpensesTotal,
        balance: monthlyCollections - monthlyExpensesTotal,
        averagePerSession: monthlySessions.length ? monthlyCollections / monthlySessions.length : 0,
        sessionCount: monthlySessions.length,
      },
    };
  }, [activePayments, allExpenses, allInvoices, currentMonth, purchaseInvoices, sessions]);

  const handleAccountingSaved = ({ type, record }) => {
    if (type === 'expense') {
      setExpenses(prev => [record, ...(prev || [])]);
      return;
    }
    if (type === 'purchase') {
      setPurchaseInvoices(prev => [record, ...(prev || [])]);
      refreshData && refreshData();
      loadAccountingExtras();
    }
  };

  const handleExpenseUpdated = (updated) => {
    setExpenses(prev => (prev || []).map(exp => exp.id === updated.id ? updated : exp));
  };

  const handleExpenseDeleted = (id) => {
    setExpenses(prev => (prev || []).filter(exp => exp.id !== id));
  };

  const handlePurchaseUpdated = (updated) => {
    setPurchaseInvoices(prev => (prev || []).map(item => item.id === updated.id ? updated : item));
    refreshData && refreshData();
    loadAccountingExtras();
  };

  const handlePurchaseDeleted = (id) => {
    setPurchaseInvoices(prev => (prev || []).filter(item => item.id !== id));
    refreshData && refreshData();
    loadAccountingExtras();
  };

  const openTransactionEditor = (tx) => {
    if (!tx || !tx.editable) return;
    setEditingTransaction(tx);
    setShowTransactionsModal(false);
  };

  const deleteTransaction = async (tx) => {
    if (!tx || !tx.editable) return;
    if (!confirm(tx.kind === 'purchase' ? 'حذف فاتورة المشتريات؟' : 'حذف هذا المصروف؟')) return;
    try {
      if (tx.kind === 'purchase') {
        await DB.deletePurchaseInvoice(tx.record.id);
        handlePurchaseDeleted(tx.record.id);
      } else if (tx.kind === 'expense') {
        await DB.deleteExpense(tx.record.id);
        handleExpenseDeleted(tx.record.id);
      }
      toast('تم الحذف بنجاح');
    } catch (error) {
      console.error(error);
      toast('تعذر الحذف');
    }
  };

  const handleCashShiftSaved = (savedShift) => {
    setCashShifts((prev) => (
      [savedShift, ...((prev || []).filter(shift => shift.id !== savedShift.id))]
        .sort((a, b) => new Date(b.openedAt || b.created_at || 0) - new Date(a.openedAt || a.created_at || 0))
    ));
    refreshData && refreshData();
  };

  return h('div', { className: 'fade-in' },
    showTransactionsModal ? h(AccountingTransactionsModal, {
      transactions: allTransactions,
      onClose: () => setShowTransactionsModal(false),
      onEdit: openTransactionEditor,
      onDelete: deleteTransaction,
    }) : null,
    editingTransaction && editingTransaction.kind === 'expense' ? h(EditAccountingExpenseModal, {
      expense: editingTransaction.record,
      onClose: () => setEditingTransaction(null),
      onSaved: handleExpenseUpdated,
      onDeleted: handleExpenseDeleted,
    }) : null,
    editingTransaction && editingTransaction.kind === 'purchase' ? h(EditPurchaseInvoiceModal, {
      purchase: editingTransaction.record,
      inventory: allInventory,
      onClose: () => setEditingTransaction(null),
      onSaved: handlePurchaseUpdated,
      onDeleted: handlePurchaseDeleted,
    }) : null,
    detailModal ? h(AccountingBreakdownModal, {
      title: detailModal.label,
      total: detailModal.total,
      rows: detailModal.rows,
      type: detailModal.type,
      onClose: () => setDetailModal(null),
    }) : null,
    showExpenseModal ? h(AddAccountingExpenseModal, {
      inventory: allInventory,
      onClose: () => setShowExpenseModal(false),
      onSaved: handleAccountingSaved,
    }) : null,
    showReportModal ? h(AccountingReportModal, {
      monthLabel,
      summary: monthlyData.summary,
      monthlyInvoices: monthlyData.monthlyInvoices,
      monthlyExpenses: monthlyData.monthlyExpenses,
      monthlyPurchases: monthlyData.monthlyPurchases,
      monthlySessions: monthlyData.monthlySessions,
      onClose: () => setShowReportModal(false),
    }) : null,
    shiftModalMode ? h(CashShiftModal, {
      mode: shiftModalMode,
      shift: openCashShift,
      suggestedCashIn: currentShiftCashIn,
      onClose: () => setShiftModalMode(null),
      onSaved: handleCashShiftSaved,
    }) : null,
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'المحاسبة'),
        h('div', { className: 'page-subtitle' }, 'الإيرادات، التحصيلات، المديونيات، والمصروفات الفعلية'),
      ),
      h('div', { className: 'flex gap-8' },
        h('button', { className: openCashShift ? 'btn outline' : 'btn ghost', onClick: () => setShiftModalMode(openCashShift ? 'close' : 'open') }, h(Icons.CreditCard, { size: 16 }), openCashShift ? 'إقفال وردية' : 'فتح وردية'),
        h('button', { className: 'btn outline', onClick: () => setShowReportModal(true) }, h(Icons.Download, { size: 16 }), 'تقرير شهري'),
        h('button', { className: 'btn primary', onClick: () => setShowExpenseModal(true) }, h(Icons.Plus, { size: 16 }), 'مصروف جديد'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { className: 'grid cols-4 mb-16' },
        [
          { label: 'الإيرادات', value: metrics.revenue, hint: `${allInvoices.length} فاتورة`, color: 'var(--accent)' },
          { label: 'التحصيلات', value: metrics.collections, hint: `${activePayments.length || allInvoices.length} حركة تحصيل`, color: 'var(--success)' },
          { label: 'نسبة التحصيل', value: metrics.collectionRate.toFixed(1) + '%', hint: 'المدفوع ÷ إجمالي الفواتير', color: 'var(--info)' },
          { label: 'المديونيات', value: metrics.receivables, hint: 'المبالغ المتبقية على المرضى', color: 'var(--danger)' },
          { label: 'المصروفات', value: metrics.expenses, hint: 'تشمل المشتريات والمصاريف العامة', color: 'var(--warning)' },
          { label: 'الرصيد الحالي', value: metrics.balance, hint: 'التحصيلات - المصروفات', color: metrics.balance >= 0 ? 'var(--success)' : 'var(--danger)' },
          { label: 'متوسط الدفع لكل جلسة', value: metrics.averagePerSession, hint: `${metrics.sessionCount} جلسة مسجلة`, color: 'var(--purple)' },
        ].map((card) => h('div', { key: card.label, className: 'card kpi' },
          h('div', { className: 'label' }, card.label),
          h('div', { className: 'value', style: { color: card.color } }, typeof card.value === 'string' ? card.value : window.fmtEGP(card.value)),
          h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 6 } }, card.hint),
        )),
      ),
    h('div', { style: { display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
            h('div', { style: { fontWeight: 800, fontSize: 15 } }, 'توزيع المصروفات'),
            loadingExtras ? h('span', { className: 'chip' }, 'جاري تحميل التفاصيل...') : h('span', { className: 'chip accent' }, 'اضغط على أي بند للتفاصيل'),
          ),
          expenseDistribution.length ? expenseDistribution.map((entry) => {
            const pct = metrics.expenses > 0 ? Math.round((entry.total / metrics.expenses) * 100) : 0;
            return h('button', {
              key: entry.key,
              className: 'btn ghost w-full',
              style: {
                justifyContent: 'space-between',
                alignItems: 'stretch',
                textAlign: 'right',
                padding: 0,
                marginBottom: 10,
                border: '1px solid var(--border)',
                background: 'var(--bg-subtle)',
              },
              onClick: () => setDetailModal(entry),
            },
              h('div', { style: { padding: 14, width: '100%' } },
                h('div', { className: 'flex jc-sb ai-c mb-8' },
                  h('div', null,
                    h('div', { style: { fontSize: 14, fontWeight: 800 } }, entry.label),
                    h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, `${entry.rows.length} بند مسجل`),
                  ),
                  h('div', { style: { display: 'flex', alignItems: 'center', gap: 10 } },
                    h('span', { style: { fontSize: 13, fontWeight: 800 } }, window.fmtEGP(entry.total)),
                    h(Icons.ChevronLeft, { size: 16 }),
                  ),
                ),
                h('div', { className: 'progress' },
                  h('div', { className: 'progress-bar', style: { width: pct + '%', background: entry.color } }),
                ),
              ),
            );
          }) : h('div', { style: { padding: 32, textAlign: 'center', color: 'var(--text-tertiary)' } }, 'لا توجد مصروفات مسجلة بعد'),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
            h('div', { style: { fontWeight: 800, fontSize: 15 } }, 'آخر المعاملات'),
            h('button', { className: 'btn outline sm', onClick: () => setShowTransactionsModal(true) }, 'عرض الكل'),
          ),
          latestTransactions.length ? latestTransactions.map((item, index) => h('div', {
            key: item.id,
            style: { display: 'flex', alignItems: 'center', gap: 12, padding: '10px 0', borderBottom: index < latestTransactions.length - 1 ? '1px solid var(--border)' : 'none' },
          },
            h('div', {
              style: {
                width: 34,
                height: 34,
                borderRadius: 10,
                display: 'grid',
                placeItems: 'center',
                background: item.flow === 'in' ? 'var(--success-soft)' : 'var(--danger-soft)',
                color: item.flow === 'in' ? 'var(--success)' : 'var(--danger)',
                flexShrink: 0,
              },
            }, h(item.flow === 'in' ? Icons.TrendingUp : Icons.TrendingDown, { size: 16 })),
            h('div', { style: { flex: 1, minWidth: 0 } },
              h('div', { style: { fontSize: 13, fontWeight: 700 } }, item.label),
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, formatAccountingDate(item.date)),
            ),
            h('div', {
              style: {
                fontSize: 14,
                fontWeight: 800,
                color: item.flow === 'in' ? 'var(--success)' : 'var(--danger)',
                whiteSpace: 'nowrap',
              },
            }, (item.flow === 'in' ? '+' : '-') + window.fmtEGP(item.amount)),
            item.editable ? h('div', { className: 'flex gap-4' },
              h('button', { className: 'icon-btn', title: 'تعديل', onClick: () => { setEditingTransaction(item); } }, h(Icons.Edit, { size: 14 })),
              h('button', {
                className: 'icon-btn',
                title: 'حذف',
                style: { color: 'var(--danger)' },
                onClick: () => deleteTransaction(item),
              }, h(Icons.Trash, { size: 14 })),
            ) : null,
          )) : h('div', { style: { padding: 32, textAlign: 'center', color: 'var(--text-tertiary)' } }, 'لا توجد معاملات حتى الآن'),
        ),
      ),
      h('div', { className: 'grid cols-3', style: { marginTop: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { className: 'flex jc-sb ai-c mb-16' },
            h('div', null,
              h('div', { style: { fontWeight: 800, fontSize: 15 } }, 'ملخص الدفعات'),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 4 } }, `تحصيل اليوم: ${window.fmtEGP(todayPaymentTotal)}`),
            ),
            h('span', { className: 'chip success' }, `${activePayments.length} دفعة`),
          ),
          paymentMethodSummary.length ? h(Fragment, null,
            h('div', { style: { display: 'grid', gap: 10, marginBottom: 16 } },
              paymentMethodSummary.map((item) => h('div', {
                key: item.key,
                style: { padding: '10px 12px', border: '1px solid var(--border)', borderRadius: 'var(--radius)', background: 'var(--bg-subtle)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 },
              },
                h('div', null,
                  h('div', { style: { fontWeight: 700, fontSize: 13 } }, item.label),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, `${item.count} حركة`),
                ),
                h('div', { style: { fontWeight: 800, color: 'var(--success)' } }, window.fmtEGP(item.total)),
              )),
            ),
            h('div', { style: { fontWeight: 800, fontSize: 13, marginBottom: 10 } }, 'آخر الدفعات'),
            h('div', { style: { display: 'grid', gap: 10 } },
              sortedPayments.slice(0, 4).map((payment) => h('div', {
                key: payment.id,
                style: { display: 'flex', justifyContent: 'space-between', gap: 12, paddingBottom: 10, borderBottom: '1px solid var(--border)' },
              },
                h('div', null,
                  h('div', { style: { fontWeight: 700, fontSize: 13 } }, payment.patient || 'دفعة'),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, [formatAccountingDate(payment.date), formatAccountingPaymentMethod(payment.method), payment.sourceType === 'session' ? 'جلسة' : 'مباشرة'].filter(Boolean).join(' · ')),
                ),
                h('div', { style: { fontWeight: 800, color: 'var(--success)' } }, window.fmtEGP(payment.amount)),
              )),
            ),
          ) : h('div', { style: { color: 'var(--text-tertiary)', fontSize: 13 } }, 'لا توجد دفعات مسجلة بعد'),
        ),
        h('div', { className: 'card p-20' },
          h('div', { className: 'flex jc-sb ai-c mb-16' },
            h('div', null,
              h('div', { style: { fontWeight: 800, fontSize: 15 } }, 'الوردية النقدية'),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 4 } }, openCashShift ? 'وردية مفتوحة حالياً' : 'لا توجد وردية مفتوحة'),
            ),
            h('span', { className: `chip ${openCashShift ? 'success' : 'warning'}` }, openCashShift ? 'مفتوحة' : 'مغلقة'),
          ),
          openCashShift ? h(Fragment, null,
            h('div', { className: 'grid cols-2', style: { gap: 10, marginBottom: 16 } },
              [
                { label: 'افتتاحية', value: openCashShift.openingBalance, color: 'var(--accent)' },
                { label: 'كاش داخل الوردية', value: currentShiftCashIn, color: 'var(--success)' },
                { label: 'الإقفال المتوقع', value: currentShiftExpectedClose, color: 'var(--info)' },
                { label: 'وقت الفتح', value: formatAccountingDate(openCashShift.openedAt), color: 'var(--text-primary)', format: 'text' },
              ].map((item) => h('div', { key: item.label, className: 'card', style: { padding: 14, background: 'var(--bg-subtle)' } },
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 4 } }, item.label),
                h('div', { style: { fontSize: 16, fontWeight: 900, color: item.color } }, item.format === 'text' ? item.value : window.fmtEGP(item.value)),
              )),
            ),
            h('button', { className: 'btn outline', style: { width: '100%', marginBottom: 16 }, onClick: () => setShiftModalMode('close') }, h(Icons.Lock, { size: 14 }), 'إقفال الوردية الحالية'),
          ) : h('button', { className: 'btn primary', style: { width: '100%', marginBottom: 16 }, onClick: () => setShiftModalMode('open') }, h(Icons.Plus, { size: 14 }), 'فتح وردية جديدة'),
          h('div', { style: { fontWeight: 800, fontSize: 13, marginBottom: 10 } }, 'آخر الورديات'),
          sortedCashShifts.length ? h('div', { style: { display: 'grid', gap: 10 } },
            sortedCashShifts.slice(0, 4).map((shift) => h('div', {
              key: shift.id,
              style: { display: 'flex', justifyContent: 'space-between', gap: 12, paddingBottom: 10, borderBottom: '1px solid var(--border)' },
            },
              h('div', null,
                h('div', { style: { fontWeight: 700, fontSize: 13 } }, shift.status === 'open' ? 'وردية مفتوحة' : 'وردية مغلقة'),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, [formatAccountingDate(shift.openedAt), shift.openedBy || shift.closedBy || '—'].filter(Boolean).join(' · ')),
              ),
              h('div', { style: { textAlign: 'left' } },
                h('div', { style: { fontWeight: 800, color: shift.status === 'open' ? 'var(--success)' : 'var(--text-primary)' } }, window.fmtEGP(shift.actualClose != null ? shift.actualClose : shift.expectedClose || shift.openingBalance || 0)),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, shift.status === 'open' ? 'قيد العمل' : 'تم الإقفال'),
              ),
            )),
          ) : h('div', { style: { color: 'var(--text-tertiary)', fontSize: 13 } }, 'لا توجد ورديات مسجلة'),
        ),
        h('div', { className: 'card p-20' },
          h('div', { className: 'flex jc-sb ai-c mb-16' },
            h('div', null,
              h('div', { style: { fontWeight: 800, fontSize: 15 } }, 'سجل التدقيق'),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginTop: 4 } }, 'آخر العمليات الإدارية والحركية'),
            ),
            h('span', { className: 'chip accent' }, `${allAuditLog.length} سجل`),
          ),
          recentAuditEntries.length ? h('div', { style: { display: 'grid', gap: 12 } },
            recentAuditEntries.map((entry) => {
              const detailText = formatAccountingAuditDetails(entry.details);
              return h('div', {
                key: entry.id,
                style: { paddingBottom: 12, borderBottom: '1px solid var(--border)' },
              },
                h('div', { className: 'flex jc-sb ai-c mb-4', style: { gap: 10 } },
                  h('div', { style: { fontWeight: 700, fontSize: 13 } }, `${formatAccountingAuditAction(entry.action)} ${formatAccountingAuditEntity(entry.entityType)}`),
                  h('span', { className: 'chip' }, formatAccountingDate(entry.created_at)),
                ),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, entry.actorName || 'مستخدم النظام'),
                detailText ? h('div', { style: { fontSize: 12, marginTop: 4, color: 'var(--text-secondary)' } }, detailText) : null,
              );
            }),
          ) : h('div', { style: { color: 'var(--text-tertiary)', fontSize: 13 } }, 'لا توجد سجلات تدقيق بعد'),
        ),
      ),
    ),
  );
}

// ==================== Prescriptions (all) ====================
function GlobalNewRxModal({ onClose, onSaved, patients }) {
  const { toast, clinicId, setPrescriptions } = useContext(AppContext);
  const today = new Date().toISOString().split('T')[0];
  const [patientName, setPatientName] = useState('');
  const [meds, setMeds] = useState([{ name: '', dose: '', duration: '7 أيام' }]);
  const [notes, setNotes] = useState('');
  const addMed = () => setMeds(m => [...m, { name: '', dose: '', duration: '7 أيام' }]);
  const removeMed = (i) => setMeds(m => m.filter((_, j) => j !== i));
  const upd = (i, k, v) => setMeds(m => m.map((med, j) => j === i ? { ...med, [k]: v } : med));

  const handlePrint = () => {
    const c = `<div style="font-family:Arial;direction:rtl;padding:24px;max-width:600px;margin:auto"><h2 style="text-align:center">وصفة طبية</h2><p><strong>المريض:</strong> ${printableText(patientName, '')}</p><p><strong>التاريخ:</strong> ${printableText(today, '')}</p><hr/>${meds.map((m, i) => `<p>${i + 1}. <strong>${printableText(m.name)}</strong> — ${printableText(m.dose)}</p><p style="margin:4px 0 10px;color:#4b5563">المدة: ${printableText(m.duration)}</p>`).join('')}${String(notes || '').trim() ? `<hr/><p><strong>ملاحظات:</strong> ${printableMultiline(notes)}</p>` : ''}<br/><p style="text-align:left;margin-top:40px">توقيع الطبيب: ___________</p></div>`;
    if (!openPrintableWindow({ title: 'وصفة طبية', bodyHtml: c, features: 'width=760,height=840' })) {
      toast('تعذر فتح نافذة الطباعة');
    }
  };
  const handleSave = async () => {
    const normalizedName = String(patientName || '').trim().toLowerCase();
    const selectedPatient = (patients || []).find(p => String(p?.name || '').trim().toLowerCase() === normalizedName);
    if (!meds[0].name.trim()) { toast('أضف دواء واحداً على الأقل'); return; }
    if (!selectedPatient?.id) { toast('اختر مريضاً من القائمة أولاً'); return; }
    try {
      const savedRx = await DB.addPrescription(clinicId, { patientId: selectedPatient.id, date: today, notes }, meds);
      setPrescriptions(prev => [savedRx, ...(prev || [])]);
      toast('تم حفظ الوصفة ✅');
      if (onSaved) onSaved(savedRx);
      onClose();
    } catch (error) {
      console.error(error);
      toast('تعذر حفظ الوصفة');
    }
  };

  return h(Fragment, null,
    h('div', { onClick: onClose, style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:500 } }),
    h('div', { onClick: e => e.stopPropagation(), style: { position:'fixed',top:'50%',left:'50%',transform:'translate(-50%,-50%)',background:'var(--bg-elevated)',borderRadius:'var(--radius-lg)',padding:28,width:520,zIndex:501,boxShadow:'var(--shadow-lg)',maxHeight:'90vh',overflowY:'auto' } },
      h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:20} },
        h('div', { style:{fontWeight:800,fontSize:16} }, '📋 وصفة طبية جديدة'),
        h('button', { className:'icon-btn', onClick:onClose }, h(Icons.X, {size:16})),
      ),
      h('div', { style:{marginBottom:14} },
        h('div', { className:'label' }, 'المريض'),
        h('input', { className:'input', list:'rx-patients', placeholder:'ابحث أو اكتب اسم المريض', value:patientName, onChange:e=>setPatientName(e.target.value) }),
        h('datalist', { id:'rx-patients' }, (patients||[]).map(p => h('option', { key:p.id, value:p.name }))),
      ),
      h('div', { style:{marginBottom:16} },
        h('div', { style:{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10} },
          h('div', { className:'label' }, 'الأدوية'),
          h('button', { className:'btn outline sm', onClick:addMed }, h(Icons.Plus,{size:12}), 'إضافة دواء'),
        ),
        meds.map((m,i) => h('div', { key:i, style:{border:'1px solid var(--border)',borderRadius:'var(--radius)',padding:12,marginBottom:8} },
          h('div', { style:{display:'grid',gridTemplateColumns:'1fr 1fr 1fr auto',gap:8} },
            h('input', { className:'input', placeholder:'اسم الدواء', value:m.name, onChange:e=>upd(i,'name',e.target.value) }),
            h('input', { className:'input', placeholder:'الجرعة', value:m.dose, onChange:e=>upd(i,'dose',e.target.value) }),
            h('select', { className:'input', value:m.duration, onChange:e=>upd(i,'duration',e.target.value) },
              ['3 أيام','5 أيام','7 أيام','10 أيام','14 أيام','شهر'].map(d => h('option',{key:d,value:d},d)),
            ),
            meds.length > 1 ? h('button', { className:'icon-btn', style:{color:'var(--danger)'}, onClick:()=>removeMed(i) }, h(Icons.X,{size:14})) : h('div'),
          ),
        )),
      ),
      h('div', { style:{marginBottom:20} },
        h('div', { className:'label' }, 'ملاحظات'),
        h('textarea', { className:'textarea', rows:2, placeholder:'تعليمات...', value:notes, onChange:e=>setNotes(e.target.value) }),
      ),
      h('div', { style:{display:'flex',gap:8} },
        h('button', { className:'btn outline', style:{flex:1}, onClick:onClose }, 'إلغاء'),
        h('button', { className:'btn outline', style:{flex:1}, onClick:handlePrint }, h(Icons.Printer,{size:14}), 'طباعة'),
        h('button', { className:'btn primary', style:{flex:1}, onClick:handleSave }, h(Icons.Check,{size:14}), 'حفظ'),
      ),
    ),
  );
}

function Prescriptions() {
  const { patients, prescriptions, toast } = useContext(AppContext);
  const allPatients = (patients && patients.length) ? patients : (window.PATIENTS || []);
  const [showNew, setShowNew] = useState(false);
  const rxList = Array.isArray(prescriptions) ? prescriptions : [];
  const getPatientPhone = (name) => String(allPatients.find(p => String(p.name || '').trim().toLowerCase() === String(name || '').trim().toLowerCase())?.phone || '').trim();

  const printRx = (r) => {
    const c = `<div style="font-family:Arial;direction:rtl;padding:24px;max-width:600px;margin:auto"><h2 style="text-align:center">وصفة طبية</h2><p><strong>المريض:</strong> ${printableText(r.patient, '')}</p><p><strong>التاريخ:</strong> ${printableText(r.date, '')}</p><hr/>${(r.meds || []).map((m, i) => `<p>${i + 1}. <strong>${printableText(m.name)}</strong> — ${printableText(m.dose)}</p><p style="margin:4px 0 10px;color:#4b5563">المدة: ${printableText(m.duration)}</p>`).join('')}<br/><p style="text-align:left;margin-top:40px">توقيع الطبيب: ___________</p></div>`;
    if (!openPrintableWindow({ title: `وصفة طبية - ${r.patient || ''}`, bodyHtml: c, features: 'width=760,height=840' })) {
      toast('تعذر فتح نافذة الطباعة');
    }
  };

  return h('div', { className: 'fade-in' },
    showNew ? h(GlobalNewRxModal, { patients: allPatients, onClose: () => setShowNew(false), onSaved: () => setShowNew(false) }) : null,
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الوصفات الطبية'),
        h('div', { className: 'page-subtitle' }, rxList.length + ' وصفة مسجلة'),
      ),
      h('button', { className: 'btn primary', onClick: () => setShowNew(true) }, h(Icons.Plus, { size: 16 }), 'وصفة جديدة'),
    ),
    h('div', { className: 'page-content' },
      rxList.length === 0 ? h('div', { className: 'card empty-state', style:{padding:60} },
        h('div', { className:'empty-state-icon' }, h(Icons.Pill,{size:32})),
        h('div', null, 'لا توجد وصفات مسجلة'),
        h('button', { className:'btn primary mt-16', onClick:()=>setShowNew(true) }, h(Icons.Plus,{size:14}), 'وصفة جديدة'),
      ) :
      h('div', { className: 'grid', style: { gap: 12 } },
        rxList.map(r => h('div', { key: r.id, className: 'card p-20' },
          h('div', { className: 'flex jc-sb ai-c mb-12' },
            h('div', null,
              h('div', { style: { fontWeight: 800, fontSize: 15 } }, r.patient),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, `${r.id} · ${r.date} · ${r.doctor || '—'}`),
            ),
            h('div', { className: 'flex gap-4' },
              h('button', { className: 'btn outline sm', onClick: () => printRx(r) }, h(Icons.Printer, { size: 14 }), 'طباعة'),
              h('button', { className: 'btn outline sm', onClick: () => toast('تم الإرسال للصيدلية ✅') }, h(Icons.Send, { size: 14 }), 'إرسال للصيدلية'),
              h('button', {
                className: 'btn outline sm',
                onClick: () => {
                  const phone = getPatientPhone(r.patient);
                  const url = buildWhatsAppUrl(phone, `مرحبًا، هذه وصفة ${r.patient} بتاريخ ${r.date}.`);
                  if (!url) { toast('رقم الهاتف غير متاح'); return; }
                  window.open(url, '_blank', 'noopener');
                },
              }, h(Icons.MessageCircle, { size: 14 }), 'واتساب'),
            ),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 8 } },
            r.meds.map((m, i) => h('div', { key: i, style: { padding: 12, background: 'var(--bg-subtle)', borderRadius: 'var(--radius)' } },
              h('div', { className: 'flex ai-c gap-8 mb-4' },
                h('div', { style: { color: 'var(--accent)' } }, h(Icons.Pill, { size: 16 })),
                h('div', { style: { fontWeight: 700, fontSize: 14 } }, m.name),
              ),
              h('div', { style: { fontSize: 12, color: 'var(--text-secondary)', marginTop: 6 } }, m.dose),
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2 } }, 'المدة: ' + m.duration),
            )),
          ),
        )),
      ),
    ),
  );
}

// ==================== Xrays (all) ====================
function XrayLightbox({ img, onClose }) {
  const sourceUrl = img?.dataUrl || '';
  return h('div', {
    onClick: onClose,
    style: { position:'fixed',inset:0,background:'rgba(0,0,0,0.9)',zIndex:1000,display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',cursor:'zoom-out' },
  },
    h('div', { style:{position:'absolute',top:16,insetInlineEnd:16} },
      h('button', { className:'icon-btn', style:{background:'rgba(255,255,255,0.15)',color:'#fff',width:40,height:40}, onClick:onClose }, h(Icons.X,{size:20})),
    ),
    h('div', { onClick:e=>e.stopPropagation(), style:{background:img.dataUrl ? 'transparent' : 'repeating-linear-gradient(45deg,#1a1a2e,#1a1a2e 12px,#2a2a3e 12px,#2a2a3e 24px)',width:640,height:480,borderRadius:12,overflow:'hidden',display:'grid',placeItems:'center',position:'relative'} },
      img.dataUrl
        ? h('img', { src:img.dataUrl, style:{width:'100%',height:'100%',objectFit:'contain'} })
        : h('div', { style:{textAlign:'center',color:'#fff',opacity:0.5} }, h(Icons.Image,{size:64}), h('div',{style:{fontFamily:'monospace',fontSize:14,marginTop:12}}, (img.type||'').toUpperCase())),
      h('div', { style:{position:'absolute',bottom:0,left:0,right:0,padding:'14px 20px',background:'rgba(0,0,0,0.6)'} },
        h('div', { style:{fontWeight:800,fontSize:15,color:'#fff'} }, img.label),
        h('div', { style:{fontSize:12,color:'rgba(255,255,255,0.7)',marginTop:4} }, `${img.patient} · ${img.date}`),
      ),
    ),
    h('div', { style:{marginTop:16,display:'flex',gap:8}, onClick:e=>e.stopPropagation() },
      h('button', { className:'btn outline', style:{color:'#fff',borderColor:'rgba(255,255,255,0.3)'}, onClick:()=>window.print() }, h(Icons.Printer,{size:14}), 'طباعة'),
      h('button', {
        className:'btn outline',
        style:{color:'#fff',borderColor:'rgba(255,255,255,0.3)'},
        onClick:()=> {
          if (!window.downloadFromUrl || !window.downloadFromUrl(sourceUrl, `${String(img?.label || 'xray').replace(/[\\/:*?"<>|]/g, '_')}.png`)) {
            window.print();
          }
        },
      }, h(Icons.Download,{size:14}), 'تحميل'),
    ),
  );
}

function Xrays() {
  const { toast, patients } = useContext(AppContext);
  const fileRef = React.useRef(null);
  const [lightbox, setLightbox] = useState(null);
  const allPatients = (patients && patients.length) ? patients : (window.PATIENTS || []);
  const [imgs, setImgs] = useState(() => loadGlobalXrays());
  useEffect(() => {
    setImgs(loadGlobalXrays());
  }, []);
  const [filterType, setFilterType] = useState('');
  const [search, setSearch] = useState('');

  const filtered = imgs.filter(im =>
    (!filterType || im.type === filterType) &&
    (!search || im.patient.includes(search) || im.label.includes(search))
  );

  const handleUpload = async (e) => {
    const file = e.target.files[0]; if (!file) return;
    const isImg = file.type.startsWith('image/');
    try {
      const dataUrl = await fileToStoredDataUrl(file);
      const newImg = { id:Date.now(), patient:'', date:new Date().toISOString().split('T')[0], type:isImg ? 'ديجيتال' : 'مستند', label:file.name.replace(/\.[^.]+$/,''), dataUrl };
      setImgs(prev => {
        const next = [newImg, ...prev];
        saveGlobalXrays(next);
        return next;
      });
      toast('تم رفع الصورة ✅');
      e.target.value = '';
    } catch (error) {
      console.error(error);
      toast('تعذر رفع الصورة');
    }
  };

  const handleDelete = (id, e) => {
    e.stopPropagation();
    if (!confirm('حذف هذه الصورة؟')) return;
    setImgs(prev => {
      const next = prev.filter(im => im.id !== id);
      saveGlobalXrays(next);
      return next;
    });
    if (lightbox?.id === id) setLightbox(null);
    toast('تم الحذف');
  };

  return h('div', { className: 'fade-in' },
    lightbox ? h(XrayLightbox, { img:lightbox, onClose:()=>setLightbox(null) }) : null,
    h('input', { ref:fileRef, type:'file', accept:'image/*,.pdf', style:{display:'none'}, onChange:handleUpload }),
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'الأشعة والصور'),
        h('div', { className: 'page-subtitle' }, `${filtered.length} صورة · تصفح وإدارة الأشعة`),
      ),
      h('div', { className:'flex gap-8' },
        h('input', { className:'input', placeholder:'بحث بالمريض أو الوصف...', value:search, onChange:e=>setSearch(e.target.value), style:{width:200} }),
        h('div', { style:{display:'flex',gap:4,padding:3,background:'var(--bg-subtle)',borderRadius:'var(--radius)'} },
          ['الكل','بانوراما','ديجيتال'].map(t => h('button', {
            key:t, className:'btn sm',
            style:{background:filterType===(t==='الكل'?'':t)?'var(--bg-elevated)':'transparent', boxShadow:filterType===(t==='الكل'?'':t)?'var(--shadow-sm)':'none'},
            onClick:()=>setFilterType(t==='الكل'?'':t),
          }, t)),
        ),
        h('button', { className:'btn primary', onClick:()=>fileRef.current.click() }, h(Icons.Upload,{size:16}), 'رفع صورة'),
      ),
    ),
    h('div', { className: 'page-content' },
      filtered.length === 0 ? h('div', { className:'card empty-state', style:{padding:60} },
        h('div', { className:'empty-state-icon' }, h(Icons.Image,{size:32})),
        h('div', null, 'لا توجد صور'),
        h('button', { className:'btn primary mt-16', onClick:()=>fileRef.current.click() }, h(Icons.Upload,{size:14}), 'رفع أول صورة'),
      ) :
      h('div', { className: 'grid cols-4', style:{gap:12} },
        filtered.map(im => h('div', { key:im.id, className:'card', style:{overflow:'hidden',cursor:'pointer',position:'relative'} },
          h('div', {
            onClick: ()=>setLightbox(im),
            style:{aspectRatio:'4/3', background:im.dataUrl ? `url(${im.dataUrl}) center/cover` : 'repeating-linear-gradient(45deg,#2a2a3a,#2a2a3a 10px,#3a3a4a 10px,#3a3a4a 20px)', display:'grid', placeItems:'center', color:'#fff', position:'relative'},
          },
            !im.dataUrl ? h('div', { style:{textAlign:'center',opacity:0.55} }, h(Icons.Image,{size:36}), h('div',{style:{fontFamily:'monospace',fontSize:10,marginTop:6}},im.type.toUpperCase())) : null,
            h('span', { className:'chip', style:{position:'absolute',top:8,insetInlineEnd:8,background:'rgba(0,0,0,0.55)',color:'#fff',border:'none',fontSize:10} }, im.type),
            h('div', { style:{position:'absolute',inset:0,background:'rgba(0,0,0,0)',transition:'background 0.2s',display:'grid',placeItems:'center'},
              onMouseEnter:e=>e.currentTarget.style.background='rgba(0,0,0,0.3)',
              onMouseLeave:e=>e.currentTarget.style.background='rgba(0,0,0,0)',
            }),
          ),
          h('div', { style:{padding:'10px 12px',display:'flex',justifyContent:'space-between',alignItems:'center'} },
            h('div', null,
              h('div', { style:{fontWeight:700,fontSize:13} }, im.label),
              h('div', { style:{fontSize:12,color:'var(--text-secondary)',marginTop:2} }, im.patient),
              h('div', { style:{fontSize:11,color:'var(--text-tertiary)',marginTop:1} }, im.date),
            ),
            h('button', { className:'icon-btn', style:{color:'var(--danger)',width:28,height:28}, onClick:e=>handleDelete(im.id,e) }, h(Icons.Trash,{size:13})),
          ),
        )),
      ),
    ),
  );
}

// ==================== Patient Portal ====================
function PatientPortal() {
  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, 'بوابة المريض'),
        h('div', { className: 'page-subtitle' }, 'معاينة — هكذا يرى المريض بياناته على الموبايل'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { style: { display: 'grid', gridTemplateColumns: '360px 1fr', gap: 24 } },
        // Phone preview
        h('div', { style: { display: 'flex', justifyContent: 'center' } },
          h('div', {
            style: {
              width: 340, height: 680, background: '#0b1020', borderRadius: 40, padding: 10,
              boxShadow: 'var(--shadow-lg)', position: 'relative',
            },
          },
            h('div', {
              style: {
                width: '100%', height: '100%', background: 'var(--bg)', borderRadius: 30,
                overflow: 'hidden', display: 'flex', flexDirection: 'column', direction: 'rtl',
              },
            },
              h('div', { style: { padding: '12px 20px 8px', background: 'linear-gradient(135deg, var(--accent), var(--info))', color: '#fff' } },
                h('div', { style: { fontSize: 11, opacity: 0.9 } }, 'مساء الخير'),
                h('div', { style: { fontSize: 18, fontWeight: 800, marginTop: 2 } }, 'أحمد محمد 👋'),
                h('div', {
                  style: {
                    marginTop: 12, padding: 12, background: 'rgba(255,255,255,0.15)',
                    borderRadius: 12, fontSize: 12,
                  },
                },
                  h('div', { style: { opacity: 0.9 } }, 'موعدك القادم'),
                  h('div', { style: { fontSize: 15, fontWeight: 800, marginTop: 4 } }, '22 أبريل · 14:30'),
                  h('div', { style: { opacity: 0.9, marginTop: 2 } }, 'متابعة حشو عصب — د. سارة'),
                ),
              ),
              h('div', { style: { padding: 16, overflow: 'auto', flex: 1 } },
                h('div', { style: { fontWeight: 800, fontSize: 13, marginBottom: 10 } }, 'الخدمات'),
                h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8, marginBottom: 16 } },
                  [
                    { icon: Icons.Calendar, label: 'حجز' },
                    { icon: Icons.File, label: 'ملفي' },
                    { icon: Icons.CreditCard, label: 'فواتير' },
                    { icon: Icons.Image, label: 'أشعة' },
                  ].map((s, i) => h('div', {
                    key: i,
                    style: { background: 'var(--bg-elevated)', borderRadius: 10, padding: 8, textAlign: 'center', border: '1px solid var(--border)' },
                  },
                    h('div', { style: { color: 'var(--accent)', display: 'flex', justifyContent: 'center' } }, h(s.icon, { size: 18 })),
                    h('div', { style: { fontSize: 10, marginTop: 4, fontWeight: 600 } }, s.label),
                  )),
                ),
                h('div', { style: { fontWeight: 800, fontSize: 13, marginBottom: 10 } }, 'خطة العلاج الحالية'),
                h('div', { style: { background: 'var(--bg-elevated)', padding: 12, borderRadius: 10, border: '1px solid var(--border)', marginBottom: 12 } },
                  h('div', { style: { fontSize: 13, fontWeight: 700 } }, 'علاج شامل للفك السفلي'),
                  h('div', { className: 'flex jc-sb ai-c mt-8', style: { fontSize: 10, color: 'var(--text-tertiary)' } },
                    h('span', null, '60% مكتمل'),
                    h('span', null, '4 من 6 جلسات'),
                  ),
                  h('div', { className: 'progress mt-8' }, h('div', { className: 'progress-bar', style: { width: '60%' } })),
                ),
                h('div', { style: { fontWeight: 800, fontSize: 13, marginBottom: 10 } }, 'آخر الوصفات'),
                h('div', { style: { background: 'var(--bg-elevated)', padding: 12, borderRadius: 10, border: '1px solid var(--border)' } },
                  h('div', { style: { fontSize: 12, fontWeight: 700 } }, 'أموكسيسيلين 500mg'),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2 } }, 'كبسولة كل 8 ساعات · 7 أيام'),
                ),
              ),
            ),
          ),
        ),
        // Features list
        h('div', null,
          h('div', { style: { fontWeight: 800, fontSize: 16, marginBottom: 16 } }, 'ما يستطيع المريض فعله'),
          h('div', { className: 'grid cols-2', style: { gap: 12 } },
            [
              { icon: Icons.Calendar, title: 'حجز وإدارة المواعيد', desc: 'حجز، تأجيل، أو إلغاء المواعيد أونلاين' },
              { icon: Icons.File, title: 'عرض الملف الطبي', desc: 'تاريخ العلاج، الأشعة، والملاحظات' },
              { icon: Icons.CreditCard, title: 'الفواتير والدفع', desc: 'سداد الفواتير عبر بوابة الدفع' },
              { icon: Icons.Pill, title: 'الوصفات الطبية', desc: 'عرض الوصفات وطلب إعادة صرفها' },
              { icon: Icons.Bell, title: 'التذكيرات', desc: 'تنبيهات قبل الموعد بيوم' },
              { icon: Icons.MessageCircle, title: 'التواصل مع العيادة', desc: 'رسائل مباشرة مع الاستقبال' },
            ].map((f, i) => h('div', { key: i, className: 'card p-16' },
              h('div', { style: { width: 40, height: 40, borderRadius: 10, background: 'var(--accent-soft)', color: 'var(--accent)', display: 'grid', placeItems: 'center', marginBottom: 10 } }, h(f.icon, { size: 18 })),
              h('div', { style: { fontWeight: 700, fontSize: 14, marginBottom: 2 } }, f.title),
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, f.desc),
            )),
          ),
        ),
      ),
    ),
  );
}

// ==================== Pricing & Profitability ====================
function Pricing() {
  const { services, inventory, clinicId } = useContext(AppContext);
  const allSvcs = (services && services.length) ? services : (window.TREATMENT_TYPES || []);
  const allInv  = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);

  // Fixed costs state (persisted in memory — in real app these go to a settings table)
  const [fixedCosts, setFixedCosts] = useState({
    rent: 5000,
    salaries: 20000,
    utilities: 2000,
    depreciation: 3000,
    other: 1000,
  });
  const [sessionsPerMonth, setSessionsPerMonth] = useState(120);
  const [bomCosts, setBomCosts] = useState({});
  const [loadingBom, setLoadingBom] = useState(false);
  const [bomLoaded, setBomLoaded] = useState(false);
  const [pricingUsageUnitsMap, setPricingUsageUnitsMap] = useState({});

  useEffect(() => {
    setPricingUsageUnitsMap(loadInventoryUsageUnitsMap(clinicId));
  }, [clinicId, allInv.length]);

  const totalFixedCost = Object.values(fixedCosts).reduce((s, v) => s + (+v || 0), 0);
  const fixedCostPerSession = sessionsPerMonth > 0 ? totalFixedCost / sessionsPerMonth : 0;

  // Load BOM data to calculate material cost per service
  const loadBomCosts = async () => {
    if (bomLoaded || !allSvcs.length) return;
    setLoadingBom(true);
    const costs = {};
    for (const svc of allSvcs) {
      try {
        const bom = await DB.getBomForService(svc.id);
        costs[svc.id] = bom.reduce((sum, b) => {
          const item = allInv.find(i => i.id === b.inventoryId);
          return sum + (item ? getInventoryMeasureUnitPrice(item, pricingUsageUnitsMap) * b.standardQty : 0);
        }, 0);
      } catch(e) { costs[svc.id] = 0; }
    }
    setBomCosts(costs);
    setBomLoaded(true);
    setLoadingBom(false);
  };

  useEffect(() => { loadBomCosts(); }, [allSvcs.length, allInv.length, clinicId, JSON.stringify(pricingUsageUnitsMap)]);

  const fixedLabels = [
    ['rent', '🏠 الإيجار الشهري'],
    ['salaries', '👥 رواتب ثابتة (غير الأطباء)'],
    ['utilities', '💡 كهرباء / مياه / إنترنت'],
    ['depreciation', '🔧 استهلاك الأجهزة (شهري)'],
    ['other', '📦 مصاريف أخرى ثابتة'],
  ];

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, '📊 التسعير والربحية'),
        h('div', { className: 'page-subtitle' }, 'احسب ربحك الحقيقي من كل خدمة بعد الخصم والتكاليف الثابتة'),
      ),
    ),
    h('div', { className: 'page-content' },

      /* ===== قسم 1: التكاليف الثابتة ===== */
      h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, marginBottom: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 14 } }, '🏗️ التكاليف الثابتة الشهرية'),
          h('div', { style: { display: 'grid', gap: 10 } },
            fixedLabels.map(([k, label]) => h('div', { key: k, style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 } },
              h('span', { style: { fontSize: 13, flex: 1 } }, label),
              h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
                h('input', {
                  className: 'input', type: 'number', min: 0,
                  style: { width: 110, padding: '5px 8px', fontSize: 13, textAlign: 'left' },
                  value: fixedCosts[k],
                  onChange: e => setFixedCosts(prev => ({ ...prev, [k]: +e.target.value })),
                }),
                h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'ج.م'),
              ),
            )),
          ),
          h('div', { style: { marginTop: 14, padding: '10px 14px', background: 'var(--bg-subtle)', borderRadius: 'var(--radius)', display: 'flex', justifyContent: 'space-between' } },
            h('span', { style: { fontWeight: 700 } }, 'إجمالي التكاليف الثابتة'),
            h('span', { style: { fontWeight: 800, fontSize: 16, color: 'var(--danger)' } }, window.fmtEGP(totalFixedCost)),
          ),
        ),

        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 14 } }, '⚙️ معادلة التوزيع'),
          h('div', { style: { fontSize: 13, color: 'var(--text-secondary)', marginBottom: 12 } },
            'التكلفة الثابتة لكل جلسة = إجمالي التكاليف ÷ عدد جلسات الشهر'),
          h('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 } },
            h('div', { className: 'label', style: { whiteSpace: 'nowrap' } }, 'جلسات الشهر التقديرية:'),
            h('input', { className: 'input', type: 'number', min: 1, value: sessionsPerMonth,
              style: { width: 90 }, onChange: e => setSessionsPerMonth(+e.target.value) }),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 12 } },
            [
              { label: 'إجمالي ثابت/شهر', val: window.fmtEGP(totalFixedCost), color: 'var(--danger)' },
              { label: 'ثابت/جلسة', val: window.fmtEGP(Math.round(fixedCostPerSession)), color: 'var(--warning)' },
            ].map((k, i) => h('div', { key: i, style: { padding: 14, background: 'var(--bg-subtle)', borderRadius: 'var(--radius)', textAlign: 'center' } },
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 4 } }, k.label),
              h('div', { style: { fontSize: 18, fontWeight: 800, color: k.color } }, k.val),
            )),
          ),
          h('div', { style: { marginTop: 16, padding: '12px 14px', background: 'var(--accent-soft)', borderRadius: 'var(--radius)', fontSize: 12, color: 'var(--accent)', fontWeight: 600 } },
            '💡 عشان تضيف استهلاك جهاز: سعر الجهاز ÷ عمره بالشهور. مثلاً: يونيت 120,000 ج.م ÷ 120 شهر = 1,000 ج.م/شهر'),
        ),
      ),

      /* ===== قسم 2: ربحية كل خدمة ===== */
      h('div', { className: 'card', style: { overflow: 'hidden' } },
        h('div', { style: { padding: '14px 20px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
          h('div', { style: { fontWeight: 800, fontSize: 15 } }, '💰 تحليل ربحية الخدمات'),
          loadingBom ? h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, 'جاري تحميل بيانات المواد...') : null,
        ),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null,
            ['الخدمة', 'سعر البيع', 'تكلفة المواد', 'تكلفة ثابتة/جلسة', 'تكلفة إجمالية', 'هامش الربح', 'نسبة الربح', 'التقييم'].map((t, i) =>
              h('th', { key: i }, t))
          )),
          h('tbody', null,
            allSvcs.length === 0 ?
              h('tr', null, h('td', { colSpan: 8, style: { textAlign: 'center', padding: 32, color: 'var(--text-tertiary)' } }, 'أضف خدمات أولاً من المخزون والخدمات')) :
            allSvcs.map(svc => {
              const materialCost = bomCosts[svc.id] || 0;
              const totalCost    = materialCost + fixedCostPerSession;
              const profit       = svc.price - totalCost;
              const margin       = svc.price > 0 ? (profit / svc.price) * 100 : 0;
              const rating       = margin >= 60 ? '🟢 ممتاز' : margin >= 40 ? '🟡 جيد' : margin >= 20 ? '🟠 مقبول' : '🔴 خسارة';
              return h('tr', { key: svc.id },
                h('td', { style: { fontWeight: 700 } }, svc.name),
                h('td', { style: { fontWeight: 800, color: 'var(--accent)' } }, window.fmtEGP(svc.price)),
                h('td', { style: { color: 'var(--danger)' } }, window.fmtEGP(Math.round(materialCost))),
                h('td', { style: { color: 'var(--warning)' } }, window.fmtEGP(Math.round(fixedCostPerSession))),
                h('td', { style: { fontWeight: 700, color: 'var(--danger)' } }, window.fmtEGP(Math.round(totalCost))),
                h('td', { style: { fontWeight: 800, color: profit >= 0 ? 'var(--success)' : 'var(--danger)' } }, window.fmtEGP(Math.round(profit))),
                h('td', null,
                  h('div', { className: 'flex ai-c gap-8' },
                    h('div', { className: 'progress', style: { flex: 1, height: 6 } },
                      h('div', { className: 'progress-bar', style: { width: Math.max(0, margin) + '%', background: margin >= 60 ? 'var(--success)' : margin >= 40 ? 'var(--accent)' : margin >= 20 ? 'var(--warning)' : 'var(--danger)' } }),
                    ),
                    h('span', { style: { fontSize: 12, fontWeight: 700, minWidth: 35 } }, Math.round(margin) + '%'),
                  ),
                ),
                h('td', null, h('span', { style: { fontSize: 12 } }, rating)),
              );
            }),
          ),
        ),
      ),
    ),
  );
}

function PricingV2() {
  const { services, inventory, clinicId } = useContext(AppContext);
  const allSvcs = (services && services.length) ? services : (window.TREATMENT_TYPES || []);
  const allInv = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
  const pricingModelKey = `senan-pricing-model:${clinicId || 'default'}`;
  const doctorCommissionKey = `senan-pricing-commissions:${clinicId || 'default'}`;
  const defaultCostModel = {
    workingHoursPerDay: 5,
    workingDaysPerWeek: 5,
    weeksPerMonth: 4,
    establishmentCostFiveYears: 600000,
    runningFixedMonthly: 10000,
    salariesMonthly: 10000,
    otherFixedMonthly: 0,
  };
  const [costModel, setCostModel] = useState(defaultCostModel);
  const [doctorCommissionMap, setDoctorCommissionMap] = useState({});
  const [bomStats, setBomStats] = useState({});
  const [loadingBom, setLoadingBom] = useState(false);
  const [pricingUsageUnitsMap, setPricingUsageUnitsMap] = useState({});

  useEffect(() => {
    setPricingUsageUnitsMap(loadInventoryUsageUnitsMap(clinicId));
  }, [clinicId, allInv.length]);

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(pricingModelKey);
      if (!raw) {
        setCostModel(defaultCostModel);
        return;
      }
      const parsed = JSON.parse(raw);
      setCostModel(prev => ({ ...prev, ...parsed }));
    } catch (error) {
      console.warn('[Pricing] failed to load cost model:', error);
      setCostModel(defaultCostModel);
    }
  }, [pricingModelKey]);

  useEffect(() => {
    try {
      window.localStorage.setItem(pricingModelKey, JSON.stringify(costModel));
    } catch (error) {
      console.warn('[Pricing] failed to save cost model:', error);
    }
  }, [pricingModelKey, costModel]);

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(doctorCommissionKey);
      setDoctorCommissionMap(raw ? JSON.parse(raw) : {});
    } catch (error) {
      console.warn('[Pricing] failed to load doctor commissions:', error);
      setDoctorCommissionMap({});
    }
  }, [doctorCommissionKey]);

  useEffect(() => {
    try {
      window.localStorage.setItem(doctorCommissionKey, JSON.stringify(doctorCommissionMap));
    } catch (error) {
      console.warn('[Pricing] failed to save doctor commissions:', error);
    }
  }, [doctorCommissionKey, doctorCommissionMap]);

  const updateCostModel = (key, value) => {
    const numericValue = Math.max(0, Number(value) || 0);
    setCostModel(prev => ({ ...prev, [key]: numericValue }));
  };

  const updateDoctorCommission = (serviceId, value) => {
    const numericValue = Math.max(0, Number(value) || 0);
    setDoctorCommissionMap(prev => ({ ...prev, [serviceId]: numericValue }));
  };

  const serviceSnapshot = allSvcs
    .map(svc => `${svc.id}:${Number(svc.price) || 0}:${Number(svc.duration) || 0}`)
    .join('|');
  const inventorySnapshot = allInv
    .map(item => `${item.id}:${Number(item.price) || 0}`)
    .join('|');

  useEffect(() => {
    let cancelled = false;

    const loadBomStats = async () => {
      if (!allSvcs.length) {
        setBomStats({});
        setLoadingBom(false);
        return;
      }

      setLoadingBom(true);
      const inventoryPriceMap = {};
      allInv.forEach(item => {
        inventoryPriceMap[item.id] = getInventoryMeasureUnitPrice(item, pricingUsageUnitsMap);
      });
      const nextStats = {};

      await Promise.all(allSvcs.map(async (svc) => {
        try {
          const bom = await DB.getBomForService(svc.id);
          nextStats[svc.id] = {
            cost: bom.reduce((sum, entry) => sum + ((inventoryPriceMap[entry.inventoryId] || 0) * (Number(entry.standardQty) || 0)), 0),
            itemsCount: bom.length,
          };
        } catch (error) {
          nextStats[svc.id] = { cost: 0, itemsCount: 0 };
        }
      }));

      if (!cancelled) {
        setBomStats(nextStats);
        setLoadingBom(false);
      }
    };

    loadBomStats();
    return () => { cancelled = true; };
  }, [clinicId, serviceSnapshot, inventorySnapshot, JSON.stringify(pricingUsageUnitsMap)]);

  const workingHoursPerMonth = Math.max(
    0,
    (Number(costModel.workingHoursPerDay) || 0)
      * (Number(costModel.workingDaysPerWeek) || 0)
      * (Number(costModel.weeksPerMonth) || 0)
  );
  const establishmentDepreciationPerYear = (Number(costModel.establishmentCostFiveYears) || 0) / 5;
  const establishmentDepreciationPerMonth = (Number(costModel.establishmentCostFiveYears) || 0) / 60;
  const establishmentDepreciationPerHour = workingHoursPerMonth > 0 ? establishmentDepreciationPerMonth / workingHoursPerMonth : 0;
  const runningFixedPerHour = workingHoursPerMonth > 0 ? (Number(costModel.runningFixedMonthly) || 0) / workingHoursPerMonth : 0;
  const salariesPerHour = workingHoursPerMonth > 0 ? (Number(costModel.salariesMonthly) || 0) / workingHoursPerMonth : 0;
  const otherFixedPerHour = workingHoursPerMonth > 0 ? (Number(costModel.otherFixedMonthly) || 0) / workingHoursPerMonth : 0;
  const totalFixedMonthly = establishmentDepreciationPerMonth
    + (Number(costModel.runningFixedMonthly) || 0)
    + (Number(costModel.salariesMonthly) || 0)
    + (Number(costModel.otherFixedMonthly) || 0);
  const totalFixedPerHour = workingHoursPerMonth > 0 ? totalFixedMonthly / workingHoursPerMonth : 0;

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, '📊 التسعير والربحية'),
        h('div', { className: 'page-subtitle' }, 'احسب تكلفة الساعة الحقيقية أولًا، ثم راقب ربحية كل خدمة مع المواد والزمن وعمولة الطبيب'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, marginBottom: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 8 } }, '⏱️ ساعات التشغيل'),
          h('div', { style: { fontSize: 13, color: 'var(--text-secondary)', marginBottom: 14 } },
            'ابدأ بعدد ساعات الشغل الفعلية في الشهر، لأننا سنقسم عليها كل التكلفة الثابتة بدل فكرة تكلفة الجلسة الموحدة.'
          ),
          h('div', { style: { display: 'grid', gap: 12 } },
            [
              ['workingHoursPerDay', 'ساعات العمل يوميًا', 'عدد الساعات الفعلية داخل اليوم'],
              ['workingDaysPerWeek', 'أيام العمل أسبوعيًا', 'عدد أيام الشغل في الأسبوع'],
              ['weeksPerMonth', 'أسابيع العمل شهريًا', 'اكتب 4 أو 4.3 حسب طريقتك'],
            ].map(([key, label, hint]) => h('div', {
              key,
              style: { display: 'grid', gridTemplateColumns: '1.3fr auto', gap: 12, alignItems: 'center' },
            },
              h('div', null,
                h('div', { style: { fontSize: 14, fontWeight: 700 } }, label),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, hint),
              ),
              h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
                h('input', {
                  className: 'input',
                  type: 'number',
                  min: 0,
                  style: { width: 110, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  value: costModel[key],
                  onChange: e => updateCostModel(key, e.target.value),
                }),
                h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, key === 'workingHoursPerDay' ? 'ساعة' : key === 'workingDaysPerWeek' ? 'يوم' : 'أسبوع'),
              ),
            )),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 12, marginTop: 18 } },
            [
              { label: 'ساعات العمل/شهر', value: `${workingHoursPerMonth.toFixed(0)} ساعة`, color: 'var(--accent)' },
              { label: 'إجمالي ثابت/ساعة', value: window.fmtEGP(totalFixedPerHour), color: 'var(--warning)' },
            ].map((item) => h('div', {
              key: item.label,
              style: { padding: 14, background: 'var(--bg-subtle)', borderRadius: 'var(--radius)', textAlign: 'center' },
            },
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 4 } }, item.label),
              h('div', { style: { fontSize: 20, fontWeight: 900, color: item.color } }, item.value),
            )),
          ),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 8 } }, '🏗️ التكلفة الثابتة الحقيقية'),
          h('div', { style: { fontSize: 13, color: 'var(--text-secondary)', marginBottom: 14 } },
            'بنفس منطق ملف الإكسل: استهلاك الأجهزة + التشغيل الثابت + الرواتب الثابتة + أي بند إضافي، ثم نقسمهم على ساعات العمل الشهرية.'
          ),
          h('div', { style: { display: 'grid', gap: 12 } },
            h('div', { style: { display: 'grid', gridTemplateColumns: '1.3fr auto', gap: 12, alignItems: 'center' } },
              h('div', null,
                h('div', { style: { fontSize: 14, fontWeight: 700 } }, 'تكلفة التأسيس والتجهيز لخمس سنوات'),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, 'اجمع فيها الأجهزة والكراسي والوحدات وكل أصل ثابت تريد استهلاكه'),
              ),
              h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
                h('input', {
                  className: 'input',
                  type: 'number',
                  min: 0,
                  style: { width: 130, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  value: costModel.establishmentCostFiveYears,
                  onChange: e => updateCostModel('establishmentCostFiveYears', e.target.value),
                }),
                h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'ج.م'),
              ),
            ),
            [
              ['runningFixedMonthly', 'التشغيل الثابت الشهري', 'إيجار، كهرباء، مياه، إنترنت، تسويق...'],
              ['salariesMonthly', 'الرواتب الثابتة', 'رواتب الفريق الثابتة بعيدًا عن عمولات الأطباء'],
              ['otherFixedMonthly', 'مصروفات ثابتة إضافية', 'أي بند شهري ثابت آخر'],
            ].map(([key, label, hint]) => h('div', {
              key,
              style: { display: 'grid', gridTemplateColumns: '1.3fr auto', gap: 12, alignItems: 'center' },
            },
              h('div', null,
                h('div', { style: { fontSize: 14, fontWeight: 700 } }, label),
                h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, hint),
              ),
              h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
                h('input', {
                  className: 'input',
                  type: 'number',
                  min: 0,
                  style: { width: 130, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  value: costModel[key],
                  onChange: e => updateCostModel(key, e.target.value),
                }),
                h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'ج.م'),
              ),
            )),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 12, marginTop: 16 } },
            [
              { label: 'إهلاك الأجهزة/سنة', val: window.fmtEGP(establishmentDepreciationPerYear), color: 'var(--accent)' },
              { label: 'إهلاك الأجهزة/شهر', val: window.fmtEGP(establishmentDepreciationPerMonth), color: 'var(--accent)' },
              { label: 'إهلاك الأجهزة/ساعة', val: window.fmtEGP(establishmentDepreciationPerHour), color: 'var(--warning)' },
              { label: 'التشغيل الثابت/ساعة', val: window.fmtEGP(runningFixedPerHour), color: 'var(--warning)' },
              { label: 'الرواتب الثابتة/ساعة', val: window.fmtEGP(salariesPerHour), color: 'var(--warning)' },
              { label: 'الإضافي الثابت/ساعة', val: window.fmtEGP(otherFixedPerHour), color: 'var(--warning)' },
              { label: 'إجمالي ثابت/شهر', val: window.fmtEGP(totalFixedMonthly), color: 'var(--danger)' },
              { label: 'إجمالي ثابت/ساعة', val: window.fmtEGP(totalFixedPerHour), color: 'var(--danger)' },
            ].map((item, index) => h('div', {
              key: item.label + index,
              style: { padding: 14, background: 'var(--bg-subtle)', borderRadius: 'var(--radius)', textAlign: 'center' },
            },
              h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 4 } }, item.label),
              h('div', { style: { fontSize: 18, fontWeight: 800, color: item.color } }, item.val),
            )),
          ),
          h('div', {
            style: {
              marginTop: 16,
              padding: '14px 16px',
              background: 'var(--accent-soft)',
              borderRadius: 'var(--radius)',
              fontSize: 12,
              color: 'var(--accent)',
              fontWeight: 600,
              display: 'grid',
              gap: 8,
            },
          },
            h('div', null, `• في الإعداد الحالي: ${window.fmtEGP(costModel.establishmentCostFiveYears)} ÷ 60 شهر = ${window.fmtEGP(establishmentDepreciationPerMonth)} شهريًا، ثم ÷ ${workingHoursPerMonth.toFixed(0) || '0'} ساعة = ${window.fmtEGP(establishmentDepreciationPerHour)} للساعة.`),
            h('div', null, '• لو عندك أكثر من جهاز، اجمعهم كلهم داخل بند التأسيس والتجهيز لخمس سنوات.'),
            h('div', null, '• الخدمة التي تستغرق 90 دقيقة ستتحمل 1.5 ساعة من التكلفة الثابتة تلقائيًا في الجدول التالي.'),
          ),
        ),
      ),
      h('div', { className: 'card', style: { overflow: 'hidden' } },
        h('div', { style: { padding: '14px 20px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
          h('div', { style: { fontWeight: 800, fontSize: 15 } }, '💰 تحليل ربحية الخدمات'),
          loadingBom ? h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, 'جاري تحميل تكاليف المواد من BOM والمخزون...') : null,
        ),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null,
            ['الخدمة', 'سعر البيع', 'تكلفة المواد', 'تكلفة الساعة', 'عمولة الطبيب', 'تكلفة إجمالية', 'هامش الربح', 'نسبة الربح', 'التقييم'].map((t, i) =>
              h('th', { key: i }, t))
          )),
          h('tbody', null,
            allSvcs.length === 0 ?
              h('tr', null, h('td', { colSpan: 9, style: { textAlign: 'center', padding: 32, color: 'var(--text-tertiary)' } }, 'أضف خدمات أولًا من المخزون والخدمات')) :
            allSvcs.map(svc => {
              const durationMinutes = Number(svc.duration) || 30;
              const durationHours = durationMinutes / 60;
              const materialStats = bomStats[svc.id] || { cost: 0, itemsCount: 0 };
              const materialCost = Number(materialStats.cost) || 0;
              const doctorCommission = Number(doctorCommissionMap[svc.id]) || 0;
              const loadedFixedCost = totalFixedPerHour * durationHours;
              const totalCost = materialCost + loadedFixedCost + doctorCommission;
              const profit = (Number(svc.price) || 0) - totalCost;
              const margin = (Number(svc.price) || 0) > 0 ? (profit / Number(svc.price)) * 100 : 0;
              const rating = profit < 0
                ? '🔴 خاسرة'
                : margin >= 55
                  ? '🟢 ممتازة'
                  : margin >= 35
                    ? '🟡 جيدة'
                    : margin >= 15
                      ? '🟠 تحتاج تحسين'
                      : '🔴 ضعيفة';
              return h('tr', { key: svc.id },
                h('td', null,
                  h('div', { style: { fontWeight: 700 } }, svc.name),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, `${durationMinutes} دقيقة`),
                ),
                h('td', { style: { fontWeight: 800, color: 'var(--accent)' } }, window.fmtEGP(Number(svc.price) || 0)),
                h('td', { style: { color: 'var(--danger)' } },
                  h('div', { style: { fontWeight: 700 } }, window.fmtEGP(Math.round(materialCost))),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, materialStats.itemsCount ? `${materialStats.itemsCount} مادة مرتبطة` : 'لا توجد مواد مرتبطة'),
                ),
                h('td', { style: { color: 'var(--warning)' } },
                  h('div', { style: { fontWeight: 700 } }, `${window.fmtEGP(Math.round(totalFixedPerHour))} / ساعة`),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, `تحميل الخدمة: ${window.fmtEGP(Math.round(loadedFixedCost))}`),
                ),
                h('td', null,
                  h('input', {
                    className: 'input',
                    type: 'number',
                    min: 0,
                    value: doctorCommission,
                    onChange: e => updateDoctorCommission(svc.id, e.target.value),
                    style: { width: 96, padding: '6px 8px', fontSize: 13, textAlign: 'left' },
                  }),
                ),
                h('td', { style: { fontWeight: 700, color: 'var(--danger)' } }, window.fmtEGP(Math.round(totalCost))),
                h('td', { style: { fontWeight: 800, color: profit >= 0 ? 'var(--success)' : 'var(--danger)' } }, window.fmtEGP(Math.round(profit))),
                h('td', null,
                  h('div', { className: 'flex ai-c gap-8' },
                    h('div', { className: 'progress', style: { flex: 1, height: 6 } },
                      h('div', { className: 'progress-bar', style: { width: Math.max(0, Math.min(100, margin)) + '%', background: margin >= 55 ? 'var(--success)' : margin >= 35 ? 'var(--accent)' : margin >= 15 ? 'var(--warning)' : 'var(--danger)' } }),
                    ),
                    h('span', { style: { fontSize: 12, fontWeight: 700, minWidth: 35 } }, Math.round(margin) + '%'),
                  ),
                ),
                h('td', null, h('span', { style: { fontSize: 12 } }, rating)),
              );
            }),
          ),
        ),
      ),
    ),
  );
}

function PricingV3() {
  const { services, inventory, clinicId, setServices, toast } = useContext(AppContext);
  const allSvcs = (services && services.length) ? services : (window.TREATMENT_TYPES || []);
  const allInv = (inventory && inventory.length) ? inventory : (window.INVENTORY || []);
  const pricingModelKey = `senan-pricing-model:${clinicId || 'default'}`;
  const doctorCommissionKey = `senan-pricing-commissions:${clinicId || 'default'}`;
  const defaultCostModel = {
    workingHoursPerDay: 5,
    workingDaysPerWeek: 5,
    weeksPerMonth: 4,
    equipmentInvestmentTotal: 600000,
    equipmentLifespanYears: 8,
    extraEquipmentGroups: [],
    runningFixedMonthly: 10000,
    salariesMonthly: 10000,
    otherFixedMonthly: 0,
  };
  const [costModel, setCostModel] = useState(defaultCostModel);
  const [doctorCommissionMap, setDoctorCommissionMap] = useState({});
  const [bomStats, setBomStats] = useState({});
  const [loadingBom, setLoadingBom] = useState(false);
  const [pricingUsageUnitsMap, setPricingUsageUnitsMap] = useState({});
  const [priceDrafts, setPriceDrafts] = useState({});
  const [showExtraEquipment, setShowExtraEquipment] = useState(false);
  const [showPricingGuidance, setShowPricingGuidance] = useState(false);

  useEffect(() => {
    setPricingUsageUnitsMap(loadInventoryUsageUnitsMap(clinicId));
  }, [clinicId, allInv.length]);

  const normalizeMoneyValue = (value) => {
    const number = Number(value) || 0;
    if (Math.abs(number) >= 100) return Math.round(number);
    return Math.round(number * 10) / 10;
  };
  const fmtMoney = (value) => {
    const roundedValue = normalizeMoneyValue(value);
    return `${new Intl.NumberFormat('en-US', {
      minimumFractionDigits: Number.isInteger(roundedValue) ? 0 : 1,
      maximumFractionDigits: 1,
    }).format(roundedValue)} ج.م`;
  };
  const fmtNumber = (value) => {
    const roundedValue = normalizeMoneyValue(value);
    return new Intl.NumberFormat('en-US', {
      minimumFractionDigits: Number.isInteger(roundedValue) ? 0 : 1,
      maximumFractionDigits: 1,
    }).format(roundedValue);
  };
  const fmtPercent = value => `${new Intl.NumberFormat('en-US', {
    minimumFractionDigits: 0,
    maximumFractionDigits: 1,
  }).format(Math.max(0, Number(value) || 0))}%`;
  const hintBadgeStyle = {
    width: 18,
    height: 18,
    borderRadius: 999,
    display: 'inline-grid',
    placeItems: 'center',
    background: 'var(--bg-subtle)',
    color: 'var(--text-secondary)',
    fontSize: 11,
    fontWeight: 900,
    cursor: 'help',
    border: '1px solid var(--border)',
  };
  const renderHintBadge = (hint) => h('span', {
    title: hint,
    'aria-label': hint,
    style: hintBadgeStyle,
  }, 'i');
  const renderFieldLabel = (label, hint) => h('div', {
    style: { display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 14, fontWeight: 700 },
  },
    h('span', null, label),
    renderHintBadge(hint),
  );
  const normalizeCommissionEntry = (entry) => {
    if (typeof entry === 'number') {
      return { mode: 'amount', value: Math.max(0, entry || 0) };
    }
    if (entry && typeof entry === 'object') {
      return {
        mode: entry.mode === 'percent' ? 'percent' : 'amount',
        value: Math.max(0, Number(entry.value) || 0),
      };
    }
    return { mode: 'amount', value: 0 };
  };

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(pricingModelKey);
      if (!raw) {
        setCostModel(defaultCostModel);
        return;
      }
      const parsed = JSON.parse(raw);
      const migrated = {
        ...defaultCostModel,
        ...parsed,
      };
      if (parsed.establishmentCostFiveYears != null && parsed.equipmentInvestmentTotal == null) {
        migrated.equipmentInvestmentTotal = Math.max(0, Number(parsed.establishmentCostFiveYears) || 0);
      }
      if (parsed.equipmentLifespanYears == null) {
        migrated.equipmentLifespanYears = defaultCostModel.equipmentLifespanYears;
      }
      migrated.extraEquipmentGroups = Array.isArray(parsed.extraEquipmentGroups)
        ? parsed.extraEquipmentGroups.map(group => ({
            name: String(group.name || ''),
            cost: Math.max(0, Number(group.cost) || 0),
            lifespanYears: Math.max(1, Number(group.lifespanYears) || 1),
          }))
        : [];
      setCostModel(migrated);
    } catch (error) {
      console.warn('[Pricing] failed to load cost model:', error);
      setCostModel(defaultCostModel);
    }
  }, [pricingModelKey]);

  useEffect(() => {
    try {
      window.localStorage.setItem(pricingModelKey, JSON.stringify(costModel));
    } catch (error) {
      console.warn('[Pricing] failed to save cost model:', error);
    }
  }, [pricingModelKey, costModel]);

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(doctorCommissionKey);
      if (!raw) {
        setDoctorCommissionMap({});
        return;
      }
      const parsed = JSON.parse(raw);
      const migrated = {};
      Object.entries(parsed || {}).forEach(([serviceId, entry]) => {
        migrated[serviceId] = normalizeCommissionEntry(entry);
      });
      setDoctorCommissionMap(migrated);
    } catch (error) {
      console.warn('[Pricing] failed to load doctor commissions:', error);
      setDoctorCommissionMap({});
    }
  }, [doctorCommissionKey]);

  useEffect(() => {
    try {
      window.localStorage.setItem(doctorCommissionKey, JSON.stringify(doctorCommissionMap));
    } catch (error) {
      console.warn('[Pricing] failed to save doctor commissions:', error);
    }
  }, [doctorCommissionKey, doctorCommissionMap]);

  const updateCostModel = (key, value) => {
    const numericValue = Math.max(0, Number(value) || 0);
    setCostModel(prev => ({ ...prev, [key]: numericValue }));
  };
  const addExtraEquipmentGroup = () => {
    setCostModel(prev => ({
      ...prev,
      extraEquipmentGroups: [...(prev.extraEquipmentGroups || []), { name: '', cost: 0, lifespanYears: 8 }],
    }));
  };
  const updateExtraEquipmentGroup = (index, key, value) => {
    const numericValue = key === 'lifespanYears'
      ? Math.max(1, Number(value) || 1)
      : Math.max(0, Number(value) || 0);
    setCostModel(prev => ({
      ...prev,
      extraEquipmentGroups: (prev.extraEquipmentGroups || []).map((group, groupIndex) => (
        groupIndex === index ? { ...group, [key]: key === 'name' ? String(value || '') : numericValue } : group
      )),
    }));
  };
  const removeExtraEquipmentGroup = (index) => {
    setCostModel(prev => ({
      ...prev,
      extraEquipmentGroups: (prev.extraEquipmentGroups || []).filter((_, groupIndex) => groupIndex !== index),
    }));
  };

  const updateDoctorCommission = (serviceId, patch) => {
    setDoctorCommissionMap(prev => {
      const current = normalizeCommissionEntry(prev[serviceId]);
      return {
        ...prev,
        [serviceId]: {
          ...current,
          ...patch,
          mode: patch.mode === 'percent' ? 'percent' : patch.mode === 'amount' ? 'amount' : current.mode,
          value: patch.value != null ? Math.max(0, Number(patch.value) || 0) : current.value,
        },
      };
    });
  };
  useEffect(() => {
    const nextDrafts = {};
    allSvcs.forEach(svc => {
      nextDrafts[svc.id] = Number(svc.price) || 0;
    });
    setPriceDrafts(nextDrafts);
  }, [allSvcs]);
  const saveServicePrice = async (serviceId) => {
    const draftValue = Math.max(0, Number(priceDrafts[serviceId]) || 0);
    const service = allSvcs.find(svc => svc.id === serviceId);
    if (!service) return;
    if (draftValue === (Number(service.price) || 0)) return;
    try {
      const { data, error } = await SB.from('services')
        .update({ price: draftValue })
        .eq('id', serviceId)
        .select()
        .single();
      if (error) throw error;
      const updatedService = {
        ...service,
        ...(data || {}),
        price: Number((data && data.price) != null ? data.price : draftValue) || 0,
      };
      if (setServices) {
        setServices(prev => prev.map(item => item.id === serviceId ? updatedService : item));
      }
    } catch (error) {
      console.warn('[Pricing] failed to update service price:', error);
      setPriceDrafts(prev => ({ ...prev, [serviceId]: Number(service.price) || 0 }));
      if (toast) toast('تعذر حفظ سعر الخدمة');
    }
  };

  const serviceSnapshot = allSvcs
    .map(svc => `${svc.id}:${Number(svc.price) || 0}:${Number(svc.duration) || 0}`)
    .join('|');
  const inventorySnapshot = allInv
    .map(item => `${item.id}:${Number(item.price) || 0}`)
    .join('|');

  useEffect(() => {
    let cancelled = false;

    const loadBomStats = async () => {
      if (!allSvcs.length) {
        setBomStats({});
        setLoadingBom(false);
        return;
      }

      setLoadingBom(true);
      const inventoryPriceMap = {};
      allInv.forEach(item => {
        inventoryPriceMap[item.id] = getInventoryMeasureUnitPrice(item, pricingUsageUnitsMap);
      });
      const nextStats = {};

      await Promise.all(allSvcs.map(async (svc) => {
        try {
          const bom = await DB.getBomForService(svc.id);
          nextStats[svc.id] = {
            cost: bom.reduce((sum, entry) => sum + ((inventoryPriceMap[entry.inventoryId] || 0) * (Number(entry.standardQty) || 0)), 0),
            itemsCount: bom.length,
          };
        } catch (error) {
          nextStats[svc.id] = { cost: 0, itemsCount: 0 };
        }
      }));

      if (!cancelled) {
        setBomStats(nextStats);
        setLoadingBom(false);
      }
    };

    loadBomStats();
    return () => { cancelled = true; };
  }, [clinicId, serviceSnapshot, inventorySnapshot, JSON.stringify(pricingUsageUnitsMap)]);

  const workingHoursPerMonth = Math.max(
    0,
    (Number(costModel.workingHoursPerDay) || 0)
      * (Number(costModel.workingDaysPerWeek) || 0)
      * (Number(costModel.weeksPerMonth) || 0)
  );
  const extraEquipmentGroups = Array.isArray(costModel.extraEquipmentGroups) ? costModel.extraEquipmentGroups : [];
  const extraEquipmentDepreciationPerYear = extraEquipmentGroups.reduce((sum, group) => (
    sum + ((Number(group.cost) || 0) / Math.max(1, Number(group.lifespanYears) || 1))
  ), 0);
  const extraEquipmentDepreciationPerMonth = extraEquipmentGroups.reduce((sum, group) => (
    sum + ((Number(group.cost) || 0) / (Math.max(1, Number(group.lifespanYears) || 1) * 12))
  ), 0);
  const equipmentLifespanYears = Math.max(1, Number(costModel.equipmentLifespanYears) || 1);
  const equipmentLifespanMonths = equipmentLifespanYears * 12;
  const equipmentDepreciationPerYear = ((Number(costModel.equipmentInvestmentTotal) || 0) / equipmentLifespanYears) + extraEquipmentDepreciationPerYear;
  const equipmentDepreciationPerMonth = ((Number(costModel.equipmentInvestmentTotal) || 0) / equipmentLifespanMonths) + extraEquipmentDepreciationPerMonth;
  const equipmentDepreciationPerHour = workingHoursPerMonth > 0 ? equipmentDepreciationPerMonth / workingHoursPerMonth : 0;
  const runningFixedPerHour = workingHoursPerMonth > 0 ? (Number(costModel.runningFixedMonthly) || 0) / workingHoursPerMonth : 0;
  const salariesPerHour = workingHoursPerMonth > 0 ? (Number(costModel.salariesMonthly) || 0) / workingHoursPerMonth : 0;
  const otherFixedPerHour = workingHoursPerMonth > 0 ? (Number(costModel.otherFixedMonthly) || 0) / workingHoursPerMonth : 0;
  const totalFixedMonthly = equipmentDepreciationPerMonth
    + (Number(costModel.runningFixedMonthly) || 0)
    + (Number(costModel.salariesMonthly) || 0)
    + (Number(costModel.otherFixedMonthly) || 0);
  const totalFixedPerHour = workingHoursPerMonth > 0 ? totalFixedMonthly / workingHoursPerMonth : 0;

  const pricingGuidance = [
    'ابدأ من تكلفة الساعة الحقيقية، ثم أضف المواد والعمولة قبل التفكير في سعر البيع.',
    'اربط كل خدمة بموادها الفعلية من المخزون حتى لا تظهر الربحية أعلى من الواقع.',
    'لو الطبيب يأخذ نسبة، اختر نسبة. ولو يأخذ مبلغًا ثابتًا، اختر مبلغًا ثابتًا كما هو.',
    'راجع مدة الخدمة بدقة لأن ربع ساعة أو ساعة ونصف يغيّران التكلفة الثابتة مباشرة.',
    'إذا كانت الربحية ضعيفة، راجع السعر أو الوقت أو المواد قبل اعتماد الخدمة.',
    'الإهلاك ليس ربحًا للسحب، بل حصالة شهرية تضمن سيولة لتجديد الأجهزة عند انتهاء عمرها.',
    'راجع أسعار خدماتك كل 6 أشهر لضبط هامش الربح ومواجهة التضخم وتغيرات السوق.',
  ];

  return h('div', { className: 'fade-in' },
    h('div', { className: 'page-header' },
      h('div', null,
        h('div', { className: 'page-title' }, '📊 التسعير والربحية'),
        h('div', { className: 'page-subtitle' }, 'احسب تكلفة الساعة الحقيقية أولًا، ثم أضف المواد وعمولة الطبيب، وبعدها فقط قرر هامش الربح وسعر البيع المناسب لكل خدمة.'),
      ),
    ),
    h('div', { className: 'page-content' },
      h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, marginBottom: 20 } },
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 8 } }, '⏱️ ساعات التشغيل الشهرية'),
          h('div', { style: { display: 'grid', gap: 12 } },
            [
              ['workingHoursPerDay', 'ساعات العمل يوميًا', 'عدد الساعات الفعلية التي تعملها العيادة كل يوم'],
              ['workingDaysPerWeek', 'أيام العمل أسبوعيًا', 'عدد الأيام الفعلية التي تعملها العيادة كل أسبوع'],
              ['weeksPerMonth', 'أسابيع العمل شهريًا', 'اكتب 4 أو 4.3 حسب متوسط التشغيل الشهري'],
            ].map(([key, label, hint]) => h('div', {
              key,
              style: { display: 'grid', gridTemplateColumns: '1.3fr auto', gap: 12, alignItems: 'center' },
            },
              h('div', null,
                renderFieldLabel(label, hint),
              ),
              h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
                h('input', {
                  className: 'input',
                  type: 'number',
                  min: 0,
                  style: { width: 110, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  value: costModel[key],
                  onChange: e => updateCostModel(key, e.target.value),
                }),
                h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, key === 'workingHoursPerDay' ? 'ساعة' : key === 'workingDaysPerWeek' ? 'يوم' : 'أسبوع'),
              ),
            )),
          ),
          h('div', {
            style: {
              marginTop: 18,
              padding: '16px 18px',
              background: 'var(--bg-subtle)',
              borderRadius: 'var(--radius-lg)',
              border: '1px solid var(--border)',
            },
          },
            h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 6 } }, 'ساعات العمل الشهرية الفعلية'),
            h('div', { style: { fontSize: 28, fontWeight: 900, color: 'var(--accent)', marginBottom: 6 } }, `${fmtNumber(workingHoursPerMonth)} ساعة`),
            h('div', { style: { fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.7 } }, 'هذا الرقم هو أساس توزيع التكاليف الثابتة على الخدمات. كلما كان أدق، كانت تكلفة الساعة أقرب للواقع.'),
          ),
          h('div', {
            style: {
              marginTop: 14,
              border: '1px solid var(--border)',
              borderRadius: 'var(--radius)',
              overflow: 'hidden',
              background: 'var(--panel)',
            },
          },
            h('button', {
              type: 'button',
              onClick: () => setShowPricingGuidance(v => !v),
              style: {
                width: '100%',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'space-between',
                gap: 12,
                padding: '14px 16px',
                background: 'transparent',
                border: 'none',
                color: 'var(--text)',
                cursor: 'pointer',
                fontSize: 14,
                fontWeight: 800,
              },
            },
              h('span', null, '💡 نصائح ذهبية لتسعير عيادتك'),
              h('span', { style: { fontSize: 18, color: 'var(--text-secondary)' } }, showPricingGuidance ? '−' : '+'),
            ),
            showPricingGuidance ? h('div', {
              style: {
                padding: '0 16px 16px',
                display: 'grid',
                gap: 8,
                fontSize: 12,
                color: 'var(--text-secondary)',
              },
            },
              pricingGuidance.map((note, index) => h('div', {
                key: index,
                style: { lineHeight: 1.8, fontWeight: 600 },
              }, `${index + 1}. ${note}`)),
            ) : null,
          ),
        ),
        h('div', { className: 'card p-20' },
          h('div', { style: { fontWeight: 800, fontSize: 15, marginBottom: 8 } }, '🏗️ التكلفة الثابتة الحقيقية'),
          h('div', { style: { display: 'grid', gap: 12 } },
            h('div', { style: { display: 'grid', gridTemplateColumns: '1.3fr auto auto', gap: 12, alignItems: 'center' } },
              h('div', null,
                renderFieldLabel('قيمة الأجهزة والتجهيزات', 'اجمع فيها الأجهزة والكرسي والوحدات وكل أصل تريد تحميل إهلاكه على الخدمات'),
              ),
              h('input', {
                className: 'input',
                type: 'number',
                min: 0,
                style: { width: 120, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                value: costModel.equipmentInvestmentTotal,
                onChange: e => updateCostModel('equipmentInvestmentTotal', e.target.value),
              }),
              h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'ج.م'),
            ),
            h('div', { style: { display: 'grid', gridTemplateColumns: '1.3fr auto auto', gap: 12, alignItems: 'center' } },
              h('div', null,
                renderFieldLabel('العمر المحاسبي للأجهزة والتجهيزات', 'يشمل الأجهزة والتجهيزات والديكورات والتشطيبات وكل أصل ثابت تريد تحميله على الخدمات. 5 سنوات للأجهزة الاقتصادية، و7-10 سنوات للأجهزة الأعلى تحمّلًا. أما Instruments والأدوات الدقيقة فغالبًا من سنة إلى 3 سنوات.'),
              ),
              h('input', {
                className: 'input',
                type: 'number',
                min: 1,
                style: { width: 90, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                value: costModel.equipmentLifespanYears,
                onChange: e => updateCostModel('equipmentLifespanYears', e.target.value),
              }),
              h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'سنة'),
            ),
            h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 10 } },
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, 'لو عندك أجهزة بأعمار مختلفة، أضفها هنا بشكل اختياري'),
              h('button', {
                className: 'btn sm outline',
                type: 'button',
                onClick: () => setShowExtraEquipment(v => !v),
              }, showExtraEquipment ? 'إخفاء الأعمار المختلفة' : 'إضافة أجهزة بعمر مختلف'),
            ),
            showExtraEquipment ? h('div', { style: { display: 'grid', gap: 10, padding: '12px 0 4px' } },
              extraEquipmentGroups.length ? extraEquipmentGroups.map((group, index) => h('div', {
                key: `equipment-group-${index}`,
                style: { display: 'grid', gridTemplateColumns: '1.2fr 120px 90px auto', gap: 10, alignItems: 'center' },
              },
                h('input', {
                  className: 'input',
                  type: 'text',
                  value: group.name || '',
                  onChange: e => updateExtraEquipmentGroup(index, 'name', e.target.value),
                  style: { padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  placeholder: 'اسم الأصل أو المجموعة',
                }),
                h('input', {
                  className: 'input',
                  type: 'number',
                  min: 0,
                  value: group.cost,
                  onChange: e => updateExtraEquipmentGroup(index, 'cost', e.target.value),
                  style: { padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  placeholder: 'التكلفة',
                }),
                h('input', {
                  className: 'input',
                  type: 'number',
                  min: 1,
                  value: group.lifespanYears,
                  onChange: e => updateExtraEquipmentGroup(index, 'lifespanYears', e.target.value),
                  style: { padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                  placeholder: 'السنوات',
                }),
                h('button', {
                  className: 'btn sm ghost',
                  type: 'button',
                  onClick: () => removeExtraEquipmentGroup(index),
                }, 'حذف'),
              )) : h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, 'لا توجد مجموعات إضافية بعد'),
              h('button', {
                className: 'btn sm outline',
                type: 'button',
                onClick: addExtraEquipmentGroup,
                style: { width: 'fit-content' },
              }, 'إضافة أصل آخر'),
            ) : null,
            [
              ['runningFixedMonthly', 'التشغيل الثابت الشهري', 'إيجار، كهرباء، مياه، إنترنت، تسويق...'],
              ['salariesMonthly', 'الرواتب الثابتة', 'الرواتب الثابتة بعيدًا عن عمولات الأطباء'],
              ['otherFixedMonthly', 'أي بند إضافي ثابت', 'أي بند شهري ثابت تريد إدخاله في تكلفة الساعة'],
            ].map(([key, label, hint]) => h('div', {
              key,
              style: { display: 'grid', gridTemplateColumns: '1.3fr auto auto', gap: 12, alignItems: 'center' },
            },
              h('div', null,
                renderFieldLabel(label, hint),
              ),
              h('input', {
                className: 'input',
                type: 'number',
                min: 0,
                style: { width: 120, padding: '6px 10px', fontSize: 13, textAlign: 'left' },
                value: costModel[key],
                onChange: e => updateCostModel(key, e.target.value),
              }),
              h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)' } }, 'ج.م'),
            )),
          ),
          h('div', { className: 'grid cols-2', style: { gap: 14, marginTop: 18 } },
            [
              {
                label: 'إجمالي التكاليف الشهرية الثابتة',
                value: fmtMoney(totalFixedMonthly),
                color: 'var(--danger)',
                details: [
                  `إهلاك شهري: ${fmtMoney(equipmentDepreciationPerMonth)}`,
                  `تشغيل: ${fmtMoney(costModel.runningFixedMonthly)}`,
                  `رواتب: ${fmtMoney(costModel.salariesMonthly)}`,
                  `إضافي: ${fmtMoney(costModel.otherFixedMonthly)}`,
                ],
              },
              {
                label: 'تكلفة الساعة الفعالة',
                value: fmtMoney(totalFixedPerHour),
                color: 'var(--warning)',
                details: [
                  `ساعات العمل/شهر: ${fmtNumber(workingHoursPerMonth)} ساعة`,
                  `إهلاك/ساعة: ${fmtMoney(equipmentDepreciationPerHour)}`,
                  `تشغيل/ساعة: ${fmtMoney(runningFixedPerHour)}`,
                  `رواتب/ساعة: ${fmtMoney(salariesPerHour)}`,
                  `إضافي/ساعة: ${fmtMoney(otherFixedPerHour)}`,
                ],
              },
            ].map((item) => h('div', {
              key: item.label,
              style: {
                padding: 18,
                background: 'var(--bg-subtle)',
                borderRadius: 'var(--radius-lg)',
                border: '1px solid var(--border)',
              },
            },
              h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 6 } }, item.label),
              h('div', { style: { fontSize: 28, fontWeight: 900, color: item.color, marginBottom: 10 } }, item.value),
              h('div', { style: { display: 'grid', gap: 4, fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.7 } },
                item.details.map((detail, index) => h('div', { key: index }, detail)),
              ),
            )),
          ),
        ),
      ),
      h('div', { className: 'card', style: { overflow: 'hidden' } },
        h('div', { style: { padding: '14px 20px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
          h('div', { style: { fontWeight: 800, fontSize: 15 } }, '💰 تحليل ربحية الخدمات'),
          loadingBom ? h('div', { style: { fontSize: 12, color: 'var(--text-tertiary)' } }, 'جاري تحميل تكاليف المواد من BOM والمخزون...') : null,
        ),
        h('table', { className: 'data-table' },
          h('thead', null, h('tr', null,
            ['الخدمة', 'سعر البيع', 'تكلفة المواد', 'التكلفة الثابتة', 'عمولة الطبيب', 'تكلفة إجمالية', 'هامش الربح', 'نسبة الربح', 'التقييم'].map((t, i) =>
              h('th', { key: i }, t))
          )),
          h('tbody', null,
            allSvcs.length === 0 ?
              h('tr', null, h('td', { colSpan: 9, style: { textAlign: 'center', padding: 32, color: 'var(--text-tertiary)' } }, 'أضف خدمات أولًا من المخزون والخدمات')) :
            allSvcs.map(svc => {
              const servicePrice = Number(svc.price) || 0;
              const durationMinutes = Number(svc.duration) || 30;
              const durationHours = durationMinutes / 60;
              const materialStats = bomStats[svc.id] || { cost: 0, itemsCount: 0 };
              const materialCost = Number(materialStats.cost) || 0;
              const commissionEntry = normalizeCommissionEntry(doctorCommissionMap[svc.id]);
              const doctorCommission = commissionEntry.mode === 'percent'
                ? (servicePrice * (commissionEntry.value || 0)) / 100
                : (commissionEntry.value || 0);
              const loadedFixedCost = totalFixedPerHour * durationHours;
              const totalCost = materialCost + loadedFixedCost + doctorCommission;
              const profit = servicePrice - totalCost;
              const margin = servicePrice > 0 ? (profit / servicePrice) * 100 : 0;
              const rating = profit < 0
                ? '🔴 خاسرة'
                : margin >= 55
                  ? '🟢 ممتازة'
                  : margin >= 35
                    ? '🟡 جيدة'
                    : margin >= 15
                      ? '🟠 تحتاج تحسين'
                      : '🔴 ضعيفة';

              return h('tr', { key: svc.id },
                h('td', null,
                  h('div', { style: { fontWeight: 700 } }, svc.name),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, `${fmtNumber(durationMinutes)} دقيقة`),
                ),
                h('td', null,
                  h('input', {
                    className: 'input',
                    type: 'number',
                    min: 0,
                    value: priceDrafts[svc.id] ?? servicePrice,
                    onChange: e => setPriceDrafts(prev => ({ ...prev, [svc.id]: e.target.value })),
                    onBlur: () => saveServicePrice(svc.id),
                    onKeyDown: e => { if (e.key === 'Enter') { e.currentTarget.blur(); } },
                    style: { width: 96, padding: '6px 8px', fontSize: 13, textAlign: 'left', fontWeight: 800, color: 'var(--accent)' },
                    title: 'يتحدث في الخدمات والأسعار أيضًا',
                  }),
                ),
                h('td', { style: { color: 'var(--danger)' } },
                  h('div', { style: { fontWeight: 700 } }, fmtMoney(materialCost)),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, materialStats.itemsCount ? `${fmtNumber(materialStats.itemsCount)} مادة مرتبطة` : 'لا توجد مواد مرتبطة'),
                ),
                h('td', { style: { color: 'var(--warning)' } },
                  h('div', { style: { fontWeight: 800, fontSize: 14 } }, fmtMoney(loadedFixedCost)),
                  h('div', { style: { fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 } }, `تكلفة الساعة: ${fmtMoney(totalFixedPerHour)}`),
                ),
                h('td', null,
                  h('div', {
                    style: { display: 'flex', alignItems: 'center', gap: 6, minWidth: 144 },
                    title: `العمولة الفعلية: ${fmtMoney(doctorCommission)}`,
                  },
                    h('select', {
                      className: 'input',
                      value: commissionEntry.mode,
                      onChange: e => updateDoctorCommission(svc.id, { mode: e.target.value }),
                      style: { width: 74, padding: '6px 4px', fontSize: 12 },
                    },
                      h('option', { value: 'amount' }, 'مبلغ'),
                      h('option', { value: 'percent' }, 'نسبة'),
                    ),
                    h('input', {
                      className: 'input',
                      type: 'number',
                      min: 0,
                      value: commissionEntry.value,
                      onChange: e => updateDoctorCommission(svc.id, { value: e.target.value }),
                      style: { width: 62, padding: '6px 8px', fontSize: 13, textAlign: 'left' },
                    }),
                    h('span', { style: { fontSize: 11, color: 'var(--text-tertiary)', minWidth: 28 } }, commissionEntry.mode === 'percent' ? '%' : 'ج.م'),
                  ),
                ),
                h('td', { style: { fontWeight: 700, color: 'var(--danger)' } }, fmtMoney(totalCost)),
                h('td', { style: { fontWeight: 800, color: profit >= 0 ? 'var(--success)' : 'var(--danger)' } }, fmtMoney(profit)),
                h('td', null,
                  h('div', { className: 'flex ai-c gap-8' },
                    h('div', { className: 'progress', style: { flex: 1, height: 6 } },
                      h('div', { className: 'progress-bar', style: { width: Math.max(0, Math.min(100, margin)) + '%', background: margin >= 55 ? 'var(--success)' : margin >= 35 ? 'var(--accent)' : margin >= 15 ? 'var(--warning)' : 'var(--danger)' } }),
                    ),
                    h('span', { style: { fontSize: 12, fontWeight: 700, minWidth: 50 } }, fmtPercent(margin)),
                  ),
                ),
                h('td', null, h('span', { style: { fontSize: 12 } }, rating)),
              );
            }),
          ),
        ),
      ),
    ),
  );
}

window.Screens = Object.assign(window.Screens || {}, {
  NewAppointment, Billing, Sessions, NewInvoice, Treatments, Inventory, Staff, Reports,
  Messages, Settings, Insurance, Accounting, Prescriptions, Xrays, PatientPortal,
  Pricing: PricingV3,
});
