/* =====================================================================
 * Socle commun : hooks React, icônes Lucide et utilitaires.
 * Tous les fichiers .jsx sont chargés dans l'ordre par Babel (voir
 * index.html) et partagent la même portée globale.
 * ===================================================================== */

const { useState, useEffect, useMemo, useCallback, useRef, useContext, createContext, Fragment } = React;

const {
  Activity,
  AlertTriangle,
  Ambulance,
  ArrowRight,
  Bandage,
  Brain,
  CalendarDays,
  Check,
  CheckCircle2,
  ChevronLeft,
  ChevronRight,
  CircleUser,
  ClipboardCheck,
  ClipboardList,
  Clock,
  Copy,
  Download,
  Droplet,
  Eye,
  FileText,
  FilePlus2,
  Flame,
  HeartPulse,
  History: HistoryIcon,
  Hospital,
  Info,
  LayoutDashboard,
  ListChecks,
  Lock: LockIcon,
  LogOut,
  MapPin,
  Menu,
  Package,
  PackageCheck,
  Pencil,
  Phone,
  Plus,
  Printer,
  RotateCcw,
  Save,
  ScrollText,
  Search,
  Settings,
  ShieldCheck,
  Shirt,
  ShoppingCart,
  Siren,
  Stethoscope,
  Thermometer,
  Trash2,
  Truck,
  Upload,
  UserCog,
  UserPlus,
  Users,
  Wind,
  X,
} = LucideReact;

/* ---------- Utilitaires ---------- */

/** Concatène des classes CSS en ignorant les valeurs falsy. */
function cx(...classes) {
  return classes.filter(Boolean).join(' ');
}

/** Identifiant unique court. */
function uid() {
  return Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
}

const pad2 = (n) => String(n).padStart(2, '0');

/** Valeur pour <input type="datetime-local"> correspondant à maintenant. */
function nowLocalInput() {
  const d = new Date();
  return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}T${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
}

/** Heure courante au format HH:MM. */
function nowTime() {
  const d = new Date();
  return `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
}

function fmtDateTime(value) {
  if (!value) return '—';
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return String(value);
  return d.toLocaleString('fr-FR', { dateStyle: 'short', timeStyle: 'short' });
}

function fmtDate(value) {
  if (!value) return '—';
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return String(value);
  return d.toLocaleDateString('fr-FR');
}

/** Convertit une saisie (virgule ou point) en nombre, ou null. */
function toNum(value) {
  if (value === '' || value === null || value === undefined) return null;
  const n = Number(String(value).replace(',', '.'));
  return Number.isFinite(n) ? n : null;
}

/** Lecture d'une valeur imbriquée : getIn(obj, 'a.b.c'). */
function getIn(obj, path) {
  const keys = Array.isArray(path) ? path : String(path).split('.');
  return keys.reduce((acc, k) => (acc == null ? undefined : acc[k]), obj);
}

/** Écriture immuable d'une valeur imbriquée : setIn(obj, 'a.b.c', v). */
function setIn(obj, path, value) {
  const keys = Array.isArray(path) ? path : String(path).split('.');
  if (keys.length === 0) return value;
  const [head, ...rest] = keys;
  const base = Array.isArray(obj) ? [...obj] : { ...(obj || {}) };
  base[head] = rest.length ? setIn(obj ? obj[head] : undefined, rest, value) : value;
  return base;
}

/** Affiche une valeur (chaîne, tableau, booléen) de façon lisible. */
function display(value, fallback = '—') {
  if (value === null || value === undefined || value === '') return fallback;
  if (Array.isArray(value)) return value.length ? value.join(', ') : fallback;
  if (value === true) return 'Oui';
  if (value === false) return 'Non';
  return String(value);
}

function initials(user) {
  if (!user) return '?';
  return `${(user.prenom || '?')[0]}${(user.nom || '')[0] || ''}`.toUpperCase();
}

/** Déclenche le téléchargement d'un fichier généré côté navigateur. */
function downloadFile(filename, content, mime = 'text/plain;charset=utf-8') {
  const blob = new Blob([content], { type: mime });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

/** Génère un CSV compatible Excel FR (séparateur ";" + BOM UTF-8). */
function toCsv(rows) {
  const esc = (v) => {
    const s = v === null || v === undefined ? '' : String(v);
    return /[;"\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
  };
  return '\uFEFF' + rows.map((r) => r.map(esc).join(';')).join('\r\n');
}
