// Reusable UI primitives for Rapport d'intervention
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Icons (inline SVG) ----------
const Icon = {
  Check: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="20 6 9 17 4 12"/></svg>,
  ChevronRight: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="9 18 15 12 9 6"/></svg>,
  ChevronLeft: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="15 18 9 12 15 6"/></svg>,
  Plus: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>,
  X: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>,
  Search: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>,
  MapPin: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>,
  Clock: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>,
  User: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
  Users: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>,
  Heart: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>,
  Activity: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>,
  AlertTriangle: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>,
  FileText: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>,
  Truck: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="1" y="3" width="15" height="13"/><polygon points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>,
  Stethoscope: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4.8 2.3A.3.3 0 1 0 5 2H4a2 2 0 0 0-2 2v5a6 6 0 0 0 6 6v0a6 6 0 0 0 6-6V4a2 2 0 0 0-2-2h-1a.2.2 0 1 0 .3.3"/><path d="M8 15v1a6 6 0 0 0 6 6v0a6 6 0 0 0 6-6v-4"/><circle cx="20" cy="10" r="2"/></svg>,
  Phone: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>,
  Bandage: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10 10.01h.01"/><path d="M14 14.01h.01"/><path d="M11 13.01h.01"/><path d="M13 11.01h.01"/><path d="M17.5 6.5l-11 11a4.95 4.95 0 0 1-7-7l11-11a4.95 4.95 0 0 1 7 7z"/></svg>,
  Mountain: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M8 3l-6 18h20L14 3"/><path d="M14 3l-3 9 3 6"/></svg>,
  Save: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>,
  Send: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>,
  Camera: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>,
};

// ---------- Field wrapper ----------
function Field({ label, hint, required, children, span = 6 }) {
  return (
    <div className={`field col-${span}`}>
      {label && (
        <label className="label">
          {label}
          {required && <span className="label-req">*</span>}
          {hint && <span className="label-hint">{hint}</span>}
        </label>
      )}
      {children}
    </div>
  );
}

// ---------- Text input ----------
function TextInput({ value, onChange, placeholder, icon, mono, type = "text" }) {
  const inputEl = (
    <input
      type={type}
      className={`input ${mono ? 'input-mono' : ''}`}
      value={value || ''}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
    />
  );
  if (icon) {
    return <div className="input-with-icon">{icon}{inputEl}</div>;
  }
  return inputEl;
}

// ---------- Textarea ----------
function TextArea({ value, onChange, placeholder, rows = 3 }) {
  return (
    <textarea
      className="textarea"
      value={value || ''}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      rows={rows}
    />
  );
}

// ---------- Native select ----------
function Select({ value, onChange, options, placeholder = "Sélectionner..." }) {
  return (
    <select
      className="select"
      value={value || ''}
      onChange={(e) => onChange(e.target.value)}
    >
      <option value="">{placeholder}</option>
      {options.map((opt) => {
        const v = typeof opt === 'string' ? opt : opt.value;
        const l = typeof opt === 'string' ? opt : opt.label;
        return <option key={v} value={v}>{l}</option>;
      })}
    </select>
  );
}

// ---------- Chip group (single-select) ----------
function ChipGroup({ value, onChange, options, large, square }) {
  return (
    <div className="chip-grid">
      {options.map((opt) => {
        const v = typeof opt === 'string' ? opt : opt.value;
        const l = typeof opt === 'string' ? opt : opt.label;
        return (
          <button
            key={v}
            type="button"
            className={`chip ${large ? 'chip-large' : ''} ${square ? 'chip-square' : ''} ${value === v ? 'selected' : ''}`}
            onClick={() => onChange(value === v ? '' : v)}
          >
            {l}
          </button>
        );
      })}
    </div>
  );
}

// ---------- Multi-select chips ----------
function ChipMulti({ value, onChange, options, square }) {
  const arr = value || [];
  return (
    <div className="chip-grid">
      {options.map((opt) => {
        const v = typeof opt === 'string' ? opt : opt.value;
        const l = typeof opt === 'string' ? opt : opt.label;
        const sel = arr.includes(v);
        return (
          <button
            key={v}
            type="button"
            className={`chip ${square ? 'chip-square' : ''} ${sel ? 'selected' : ''}`}
            onClick={() => {
              if (sel) onChange(arr.filter(x => x !== v));
              else onChange([...arr, v]);
            }}
          >
            {sel && <Icon.Check style={{ width: 12, height: 12 }} />} {l}
          </button>
        );
      })}
    </div>
  );
}

// ---------- Toggle ----------
function Toggle({ label, desc, value, onChange }) {
  return (
    <div className="toggle-row" onClick={() => onChange(!value)}>
      <div>
        <div className="toggle-label">{label}</div>
        {desc && <div className="toggle-desc">{desc}</div>}
      </div>
      <div className={`toggle ${value ? 'on' : ''}`}></div>
    </div>
  );
}

// ---------- Patrouilleur picker (modal w/ search) ----------
function PatrouillerPicker({ value, onChange, role, allowClear = true }) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState('');
  const list = window.RAPPORT_DATA.patrouilleurs;
  const filtered = useMemo(() => {
    if (!q) return list;
    const ql = q.toLowerCase();
    return list.filter(p => p.toLowerCase().includes(ql));
  }, [q, list]);

  const initials = value ? (value.match(/[A-Z]/g) || []).slice(-2).join('') : '';
  const filled = !!value;

  return (
    <>
      <div className={`patrouiller-pick ${filled ? 'filled' : 'patrouiller-pick-empty'}`} onClick={() => setOpen(true)}>
        <div className="patrouiller-pick-avatar">
          {filled ? initials : <Icon.User style={{ width: 16, height: 16 }} />}
        </div>
        <div className="patrouiller-pick-info">
          <div className="patrouiller-pick-role">{role}</div>
          <div className="patrouiller-pick-name">{value || "Choisir un patrouilleur"}</div>
        </div>
        {filled && allowClear && (
          <button className="btn btn-ghost btn-sm" onClick={(e) => { e.stopPropagation(); onChange(''); }} title="Retirer">
            <Icon.X />
          </button>
        )}
      </div>
      {open && (
        <div className="modal-backdrop" onClick={() => setOpen(false)}>
          <div className="modal" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">{role || 'Patrouilleur'}</div>
            </div>
            <div className="modal-search">
              <div className="input-with-icon">
                <Icon.Search />
                <input
                  autoFocus
                  className="input"
                  value={q}
                  onChange={(e) => setQ(e.target.value)}
                  placeholder="Rechercher par nom ou matricule…"
                />
              </div>
            </div>
            <div className="modal-body">
              {filtered.length === 0 ? (
                <div className="modal-empty">Aucun résultat</div>
              ) : filtered.map(p => {
                const [id, ...rest] = p.split(' ');
                return (
                  <div key={p} className="modal-option" onClick={() => { onChange(p); setOpen(false); setQ(''); }}>
                    <div className="modal-option-id">{id}</div>
                    <div className="modal-option-name">{rest.join(' ')}</div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      )}
    </>
  );
}

// ---------- Card ----------
function Card({ title, icon, subtitle, children, action }) {
  return (
    <div className="card">
      {(title || subtitle) && (
        <div className="card-header">
          <div>
            <div className="card-title">
              {icon && <span className="card-title-icon">{icon}</span>}
              {title}
            </div>
            {subtitle && <div className="card-subtitle">{subtitle}</div>}
          </div>
          {action}
        </div>
      )}
      {children}
    </div>
  );
}

// Export to window
Object.assign(window, {
  Icon, Field, TextInput, TextArea, Select, ChipGroup, ChipMulti, Toggle, PatrouillerPicker, Card
});
