// Affichage en euros à partir des centimes
function euros(c) { return (c/100).toFixed(2) + '€'; }
// Convertit une saisie en euros ("11.11" ou "11,11") en centimes (entier)
function parsePriceToCents(input) {
  let s = String(input ?? '').trim();
  if (!s) return NaN;
  // Be lenient: allow comma, convert to dot
  s = s.replace(',', '.');
  const num = Number.parseFloat(s);
  if (Number.isNaN(num)) return NaN;
  return Math.round(num * 100);
}

function AdminProducts() {
  const { user } = window.AuthContext.useAuth();
  const toast = window.Toast.useToast();
  const [list, setList] = React.useState([]);
  const [page, setPage] = React.useState(1);
  const limit = 50;
  const [total, setTotal] = React.useState(0);
  function totalPages() { return Math.max(1, Math.ceil((total||0) / (limit||50))); }
  function makePageList() {
    const tp = totalPages();
    const p = Math.min(Math.max(1, page||1), tp);
    if (tp <= 10) return Array.from({ length: tp }, (_, i) => i + 1);
    const pages = new Set([1, tp]);
    for (let i = p - 2; i <= p + 2; i++) if (i >= 1 && i <= tp) pages.add(i);
    const arr = Array.from(pages).sort((a, b) => a - b);
    const result = [];
    for (let i = 0; i < arr.length; i++) {
      result.push(arr[i]);
      if (i < arr.length - 1 && arr[i + 1] !== arr[i] + 1) result.push('…');
    }
    return result;
  }
  const [form, setForm] = React.useState({ name: '', description: '', price_euros: '', sku: '', stock: 0, image_url: '', category: '', top: false });
  const [error, setError] = React.useState('');
  const [editId, setEditId] = React.useState(null);
  const [editForm, setEditForm] = React.useState({ name: '', description: '', price_euros: '', sku: '', stock: 0, image_url: '', category: '', top: false });

  async function load(p = page) {
    const res = await window.ProductsAPI.list({ includeArchived: true, page: p, limit });
    // For each product, fetch variations summary (optional)
    const items = res.items || [];
    setList(items);
    setTotal(res.total || items.length);
    setPage(res.page || p || 1);
  }
  React.useEffect(() => { load(); }, []);

  if (!user || user.role !== 'admin') return <div className="container"><p>Accès réservé à l'admin.</p></div>;

  // Création d'un produit: on convertit le prix saisi en euros -> centimes pour l'API
  async function createProduct(e) {
    e.preventDefault(); setError('');
    try {
      const price_cents = parsePriceToCents(form.price_euros);
      if (!Number.isFinite(price_cents)) throw { error: { message: 'Prix invalide. Utilisez le format 11.11' } };
      await window.ProductsAPI.create({
        name: form.name,
        description: form.description,
        price_cents,
        sku: form.sku,
        stock: Number(form.stock),
        image_url: form.image_url,
        category: (form.category||'').toLowerCase(),
        top: !!form.top,
      });
      setForm({ name: '', description: '', price_euros: '', sku: '', stock: 0, image_url: '', category: '', top: false });
      load();
      toast.success('Produit créé');
    } catch (e) { setError(e?.error?.message || 'Erreur de création'); }
  }

  // Suppression "hard" (échoue si le produit est référencé dans une commande)
  async function remove(id) {
    setError('');
    try {
      await window.ProductsAPI.remove(id);
      load();
      toast.success('Produit supprimé');
    } catch (e) {
      const msg = e?.error?.message || "Impossible de supprimer ce produit (peut-être utilisé dans des commandes).";
      setError(msg);
      toast.error(msg);
    }
  }

  // Retrait du catalogue: met simplement le stock à 0
  async function softRemove(id) {
    setError('');
    try {
      const p = list.find(x=>x.id===id);
      if (!p) return;
      await window.ProductsAPI.update(id, { stock: 0 });
      load();
      toast.info('Produit retiré du catalogue (stock=0)');
    } catch (e) {
      setError(e?.error?.message || "Impossible de retirer du catalogue.");
      toast.error('Impossible de retirer du catalogue');
    }
  }

  // Archive/désarchive un produit (caché du catalogue)
  async function toggleArchive(p) {
    setError('');
    try {
      await window.ProductsAPI.update(p.id, { archived: !p.archived });
      load();
      toast.success(p.archived ? 'Produit désarchivé' : 'Produit archivé');
    } catch (e) {
      setError(e?.error?.message || 'Impossible de changer le statut archivé.');
      toast.error('Impossible de changer le statut archivé');
    }
  }

  // Passage en mode édition: prépare le formulaire avec les valeurs actuelles
  function startEdit(p) {
    setError('');
    setEditId(p.id);
    setEditForm({
      name: p.name,
      description: p.description || '',
      price_euros: (p.price_cents / 100).toFixed(2),
      sku: p.sku,
      stock: p.stock,
      image_url: p.image_url || '',
      category: p.category || '',
      top: !!p.top,
    });
  }

  function cancelEdit() {
    setEditId(null);
  }

  // Sauvegarde des modifications (mêmes conversions que pour la création)
  async function saveEdit(e) {
    e?.preventDefault?.();
    if (!editId) return;
    setError('');
    try {
      const price_cents = parsePriceToCents(editForm.price_euros);
      if (!Number.isFinite(price_cents)) throw { error: { message: 'Prix invalide. Utilisez le format 11.11' } };
      await window.ProductsAPI.update(editId, {
        name: editForm.name,
        description: editForm.description,
        price_cents,
        sku: editForm.sku,
        stock: Number(editForm.stock),
        image_url: editForm.image_url,
        category: (editForm.category||'').toLowerCase(),
        top: !!editForm.top,
      });
      setEditId(null);
      load();
      toast.success('Produit mis à jour');
    } catch (e) {
      setError(e?.error?.message || 'Erreur lors de la mise à jour');
      toast.error('Erreur lors de la mise à jour');
    }
  }

  return (
    <div className="container">
      <h1>Produits</h1>
      <form onSubmit={createProduct} style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8, alignItems: 'end' }}>
        <label>Nom<br/><input value={form.name} onChange={e=>setForm({...form,name:e.target.value})} required /></label>
  <label>SKU<br/><input value={form.sku} onChange={e=>setForm({...form,sku:e.target.value})} required /></label>
  <label>Catégorie<br/><input placeholder="tshirt, mug, stickers..." value={form.category} onChange={e=>setForm({...form,category:e.target.value})} /></label>
        <label>Prix (€)<br/>
          <input type="number" step="0.01" min="0" placeholder="11.11" value={form.price_euros} onChange={e=>setForm({...form,price_euros:e.target.value})} required />
        </label>
        <label>Description<br/><input value={form.description} onChange={e=>setForm({...form,description:e.target.value})} /></label>
        <label>Stock<br/><input type="number" value={form.stock} onChange={e=>setForm({...form,stock:e.target.value})} /></label>
  <label><input type="checkbox" checked={!!form.top} onChange={e=>setForm({...form, top: e.target.checked})} /> Coup de coeur</label>
        <div>
          <div style={{ fontSize: 12, color: '#666', marginBottom: 4 }}>Image (drag & drop ou upload)</div>
          <window.Components.ImageUploader value={form.image_url} onChange={(url)=>setForm({...form, image_url:url})} />
        </div>
        <button type="submit">Créer</button>
      </form>
      {error && <p style={{ color: 'red' }}>{error}</p>}

  <h3 style={{ marginTop: 16 }}>Liste</h3>
  <p style={{ color:'#666', marginTop: 0 }}>Astuce: Si la suppression échoue, le produit a peut-être déjà été commandé. Vous ne pouvez pas le supprimer s'il est référencé par une commande.</p>
  <table style={{ width: '100%', borderCollapse: 'collapse' }}>
  <thead><tr><th>Img</th><th align="left">Nom</th><th>SKU</th><th>Prix</th><th>Stock</th><th>Coup de coeur</th><th>Archivé</th><th></th></tr></thead>
        <tbody>
          {list.map(p => (
            <React.Fragment key={p.id}>
              <tr>
                <td align="center"><img src={p.image_url || '/images/placeholder.svg'} alt="" width="40" height="40" style={{ objectFit:'cover', borderRadius:4 }} onError={(e)=>{ e.currentTarget.src='/images/placeholder.svg'; }} /></td>
                <td>{p.name}</td>
                <td align="center">{p.sku}</td>
                <td align="right">{euros(p.price_cents)}</td>
                <td align="right">{p.stock}</td>
                <td align="center">{p.top ? '★' : ''}</td>
                <td align="center">{p.archived ? 'Oui' : 'Non'}</td>
                <td align="right" style={{ display:'flex', gap:8, justifyContent:'flex-end' }}>
                  <button onClick={()=>startEdit(p)}>Modifier</button>
                  <button onClick={()=>toggleArchive(p)}>{p.archived ? 'Désarchiver' : 'Archiver'}</button>
                  <button onClick={()=>remove(p.id)}>Supprimer</button>
                  <button onClick={()=>softRemove(p.id)} title="Met le stock à 0">Retirer du catalogue</button>
                </td>
              </tr>
              {/* Personnalisation (collapsible) */}
              <tr>
                <td colSpan="8" style={{ background:'transparent', padding: 0 }}>
                  <ProductPersonalizationCollapse product={p} onChanged={load} />
                </td>
              </tr>
              {editId === p.id && (
                <tr>
                  <td colSpan="8">
                    <form onSubmit={saveEdit} style={{ display:'grid', gridTemplateColumns:'repeat(6, 1fr)', gap:8, alignItems:'end' }}>
                      <label>Nom<br/><input value={editForm.name} onChange={e=>setEditForm({...editForm, name:e.target.value})} required /></label>
                      <label>SKU<br/><input value={editForm.sku} onChange={e=>setEditForm({...editForm, sku:e.target.value})} required /></label>
                      <label>Catégorie<br/><input placeholder="tshirt, mug, stickers..." value={editForm.category} onChange={e=>setEditForm({...editForm, category:e.target.value})} /></label>
                      <label>Prix (€)<br/>
                        <input type="number" step="0.01" min="0" placeholder="11.11" value={editForm.price_euros} onChange={e=>setEditForm({...editForm, price_euros:e.target.value})} required />
                      </label>
                      <label>Stock<br/><input type="number" value={editForm.stock} onChange={e=>setEditForm({...editForm, stock:e.target.value})} /></label>
                      <label>Description<br/><input value={editForm.description} onChange={e=>setEditForm({...editForm, description:e.target.value})} /></label>
                      <label style={{ alignSelf:'center' }}><input type="checkbox" checked={!!editForm.top} onChange={e=>setEditForm({...editForm, top: e.target.checked})} /> Top</label>
                      <div style={{ gridColumn:'1 / span 2' }}>
                        <div style={{ fontSize: 12, color: '#666', marginBottom: 4 }}>Image (drag & drop ou upload)</div>
                        <window.Components.ImageUploader value={editForm.image_url} onChange={(url)=>setEditForm({...editForm, image_url:url})} />
                      </div>
                      <div style={{ display:'flex', gap:8 }}>
                        <button type="submit">Enregistrer</button>
                        <button type="button" onClick={cancelEdit}>Annuler</button>
                      </div>
                    </form>
                  </td>
                </tr>
              )}
            </React.Fragment>
          ))}
        </tbody>
      </table>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginTop: 12 }}>
        <button onClick={()=>load(Math.max(1, page-1))} disabled={page<=1}>« Précédent</button>
        <div style={{ display:'flex', gap:6, alignItems:'center' }}>
          {makePageList().map((p, idx) => (
            typeof p === 'number' ? (
              <button key={idx} onClick={()=>load(p)} disabled={p===page} style={{ padding:'4px 8px', borderRadius:6, border: p===page?'1px solid #2563eb':'1px solid #ddd', background: p===page?'#eff6ff':'#fff' }}>{p}</button>
            ) : (
              <span key={idx} style={{ color:'#999' }}>…</span>
            )
          ))}
        </div>
        <button onClick={()=>load(page+1)} disabled={page*limit >= total}>Suivant »</button>
      </div>
    </div>
  );
}

window.Pages = window.Pages || {};
window.Pages.AdminProducts = AdminProducts;

function ProductPersonalizationCollapse({ product, onChanged }) {
  const [open, setOpen] = React.useState(false);
  const [counts, setCounts] = React.useState({ vars: 0, imgs: 0, opts: 0 });

  // Load quick counts to show in the header without fetching full data again
  React.useEffect(() => {
    let mounted = true;
    (async () => {
      try {
        const [v, i, o] = await Promise.all([
          window.VariationsAPI.list(product.id).catch(()=>({ items: [] })),
          window.ProductImagesAPI.list(product.id).catch(()=>({ items: [] })),
          window.ProductOptionsAPI.list(product.id).catch(()=>({ items: [] })),
        ]);
        if (mounted) setCounts({ vars: (v.items||[]).length, imgs: (i.items||[]).length, opts: (o.items||[]).length });
      } catch {}
    })();
    return () => { mounted = false; };
  }, [product.id]);

  return (
    <div style={{ marginTop:8, marginBottom:12, borderTop:'1px solid #eaeaea', borderRadius:8, background:'var(--brand-card)' }}>
      <button onClick={()=>setOpen(!open)} style={{
        width:'100%', textAlign:'left', padding:'10px 12px', background:'transparent', border:'none', display:'flex', alignItems:'center', justifyContent:'space-between', cursor:'pointer'
      }}>
        <span style={{ display:'flex', alignItems:'center', gap:8 }}>
          <b>Personnalisation</b>
          <span style={{ color:'#666', fontSize:12 }}>
            ({counts.vars} variante{counts.vars>1?'s':''} • {counts.imgs} image{counts.imgs>1?'s':''} • {counts.opts} option{counts.opts>1?'s':''})
          </span>
        </span>
        <span aria-hidden>{open ? '▾' : '▸'}</span>
      </button>
      {open && (
        <div style={{ padding:'0 10px 10px' }}>
          <ProductVariationsManager product={product} onChanged={()=>{ onChanged && onChanged(); }} />
          <ProductGalleryManager product={product} onChanged={()=>{ onChanged && onChanged(); }} />
          <ProductOptionsManager product={product} onChanged={()=>{ onChanged && onChanged(); }} />
        </div>
      )}
    </div>
  );
}

function ProductVariationsManager({ product, onChanged }) {
  const [items, setItems] = React.useState([]);
  const [form, setForm] = React.useState({ name: '', price_euros: '', sku: '', stock: '', image_url: '' });
  const toast = window.Toast.useToast();
  const [editVarId, setEditVarId] = React.useState(null);
  const [editVarForm, setEditVarForm] = React.useState({ name: '', price_euros: '', sku: '', stock: '', image_url: '' });

  React.useEffect(() => {
    (async () => {
      try {
        const res = await window.VariationsAPI.list(product.id);
        setItems(res.items || []);
      } catch {}
    })();
  }, [product.id]);

  async function createVar(e) {
    e.preventDefault();
    try {
      const payload = {
        name: form.name,
        price_cents: form.price_euros === '' ? null : Math.round(Number(String(form.price_euros).replace(',', '.'))*100),
        sku: form.sku || null,
        stock: form.stock === '' ? null : Number(form.stock),
        image_url: form.image_url || null,
      };
      await window.VariationsAPI.create(product.id, payload);
      setForm({ name: '', price_euros: '', sku: '', stock: '', image_url: '' });
      const res = await window.VariationsAPI.list(product.id);
      setItems(res.items || []);
      onChanged && onChanged();
      toast.success('Variante créée');
    } catch (e) { toast.error(e?.error?.message || 'Erreur création variante'); }
  }

  async function removeVar(id) {
    try { await window.VariationsAPI.remove(product.id, id); setItems(items.filter(x=>x.id!==id)); onChanged && onChanged(); }
    catch (e) { toast.error('Suppression impossible'); }
  }

  function startEditVar(v) {
    setEditVarId(v.id);
    setEditVarForm({
      name: v.name || '',
      sku: v.sku || '',
      price_euros: v.price_cents != null ? (v.price_cents/100).toFixed(2) : '',
      stock: v.stock != null ? String(v.stock) : '',
      image_url: v.image_url || '',
    });
  }

  function cancelEditVar() {
    setEditVarId(null);
  }

  async function saveEditVar(e) {
    e?.preventDefault?.();
    if (!editVarId) return;
    if (!editVarForm.name || !String(editVarForm.name).trim()) {
      toast.error('Le nom est obligatoire');
      return;
    }
    try {
      const payload = {
        name: editVarForm.name,
        sku: editVarForm.sku || null,
        price_cents: editVarForm.price_euros === '' ? null : Math.round(Number(String(editVarForm.price_euros).replace(',', '.'))*100),
        stock: editVarForm.stock === '' ? null : Number(editVarForm.stock),
        image_url: editVarForm.image_url || null,
      };
      await window.VariationsAPI.update(product.id, editVarId, payload);
      const res = await window.VariationsAPI.list(product.id);
      setItems(res.items || []);
      setEditVarId(null);
      onChanged && onChanged();
      toast.success('Variante mise à jour');
    } catch (e2) {
      toast.error(e2?.error?.message || 'Erreur de mise à jour');
    }
  }

  return (
    <div style={{ marginTop:8, marginBottom:12, padding:10, background:'var(--brand-card)', borderTop:'1px solid #eaeaea', borderRadius:8 }}>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
        <b style={{ fontSize:14 }}>Variantes</b>
        <span style={{ fontSize:12, color:'#888' }}>{items.length} variante{items.length>1?'s':''}</span>
      </div>
      {items.length === 0 ? (
        <p style={{ color:'#888', marginTop:6, fontSize:13 }}>Aucune variante pour le moment.</p>
      ) : (
        <table style={{ width:'100%', marginTop:8, borderCollapse:'collapse' }}>
          <thead>
            <tr>
              <th style={{ textAlign:'left', padding:'6px 4px', color:'#666', fontWeight:600 }}>Nom</th>
              <th style={{ textAlign:'left', padding:'6px 4px', color:'#666', fontWeight:600 }}>SKU</th>
              <th style={{ textAlign:'right', padding:'6px 4px', color:'#666', fontWeight:600 }}>PU</th>
              <th style={{ textAlign:'right', padding:'6px 4px', color:'#666', fontWeight:600 }}>Stock</th>
              <th style={{ textAlign:'left', padding:'6px 4px', color:'#666', fontWeight:600 }}>Image</th>
              <th style={{ width:1 }}></th>
            </tr>
          </thead>
          <tbody>
            {items.map(v => (
              editVarId === v.id ? (
                <tr key={v.id} style={{ borderTop:'1px solid #eee' }}>
                  <td style={{ padding:'6px 4px' }}>
                    <input value={editVarForm.name} onChange={e=>setEditVarForm({...editVarForm, name:e.target.value})} required />
                  </td>
                  <td style={{ padding:'6px 4px' }}>
                    <input value={editVarForm.sku} onChange={e=>setEditVarForm({...editVarForm, sku:e.target.value})} />
                  </td>
                  <td style={{ padding:'6px 4px' }} align="right">
                    <input type="number" step="0.01" min="0" value={editVarForm.price_euros} onChange={e=>setEditVarForm({...editVarForm, price_euros:e.target.value})} placeholder="optionnel" style={{ textAlign:'right' }} />
                  </td>
                  <td style={{ padding:'6px 4px' }} align="right">
                    <input type="number" min="0" value={editVarForm.stock} onChange={e=>setEditVarForm({...editVarForm, stock:e.target.value})} placeholder="optionnel" style={{ textAlign:'right' }} />
                  </td>
                  <td style={{ padding:'6px 4px' }}>
                    <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                      {editVarForm.image_url ? <img src={editVarForm.image_url} alt="" width="32" height="32" style={{ objectFit:'cover', borderRadius:4, border:'1px solid #eee' }} onError={(e)=>{ e.currentTarget.src='/images/placeholder.svg'; }} /> : <i>-</i>}
                      <window.Components.ImageUploader value={editVarForm.image_url} onChange={(url)=>setEditVarForm({...editVarForm, image_url:url})} />
                    </div>
                  </td>
                  <td style={{ padding:'6px 4px', whiteSpace:'nowrap' }} align="right">
                    <button onClick={saveEditVar} style={{ marginRight:6 }}>Enregistrer</button>
                    <button onClick={cancelEditVar} type="button">Annuler</button>
                  </td>
                </tr>
              ) : (
                <tr key={v.id} style={{ borderTop:'1px solid #eee' }}>
                  <td style={{ padding:'6px 4px' }}>{v.name}</td>
                  <td style={{ padding:'6px 4px' }}>{v.sku || <i>-</i>}</td>
                  <td style={{ padding:'6px 4px' }} align="right">{v.price_cents != null ? euros(v.price_cents) : <i>par défaut</i>}</td>
                  <td style={{ padding:'6px 4px' }} align="right">{v.stock != null ? v.stock : <i>par défaut</i>}</td>
                  <td style={{ padding:'6px 4px' }}>{v.image_url ? <img src={v.image_url} alt="" width="32" height="32" style={{ objectFit:'cover', borderRadius:4, border:'1px solid #eee' }} onError={(e)=>{ e.currentTarget.src='/images/placeholder.svg'; }} /> : <i>-</i>}</td>
                  <td style={{ padding:'6px 4px', whiteSpace:'nowrap' }} align="right">
                    <button onClick={()=>startEditVar(v)} style={{ marginRight:6 }}>Modifier</button>
                    <button onClick={()=>removeVar(v.id)}>Supprimer</button>
                  </td>
                </tr>
              )
            ))}
          </tbody>
        </table>
      )}
      <form onSubmit={createVar} style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:8, alignItems:'end', marginTop:10 }}>
        <label>Nom<br/><input value={form.name} onChange={e=>setForm({...form, name:e.target.value})} required /></label>
        <label>SKU<br/><input value={form.sku} onChange={e=>setForm({...form, sku:e.target.value})} /></label>
        <label>Prix (€)<br/><input type="number" step="0.01" min="0" value={form.price_euros} onChange={e=>setForm({...form, price_euros:e.target.value})} placeholder="optionnel" /></label>
        <label>Stock<br/><input type="number" min="0" value={form.stock} onChange={e=>setForm({...form, stock:e.target.value})} placeholder="optionnel" /></label>
        <div style={{ gridColumn:'span 2' }}>
          <div style={{ fontSize:12, color:'#666', marginBottom:4 }}>Image</div>
          <window.Components.ImageUploader value={form.image_url} onChange={(url)=>setForm({...form, image_url:url})} />
        </div>
        <div style={{ display:'flex', justifyContent:'flex-end', gap:8 }}>
          <button type="submit">Ajouter la variante</button>
        </div>
      </form>
    </div>
  );
}

function ProductGalleryManager({ product, onChanged }) {
  const [items, setItems] = React.useState([]);
  const [url, setUrl] = React.useState('');
  const toast = window.Toast.useToast();
  React.useEffect(()=>{ (async()=>{ try{ const res = await window.ProductImagesAPI.list(product.id); setItems(res.items||[]);}catch{}})(); }, [product.id]);
  async function add(e){ e.preventDefault(); try{ const created = await window.ProductImagesAPI.create(product.id, { url, sort_index: items.length }); setItems([...items, created]); setUrl(''); onChanged&&onChanged(); toast.success('Image ajoutée'); } catch(e){ toast.error(e?.error?.message||'Erreur ajout image'); } }
  async function del(id){ try{ await window.ProductImagesAPI.remove(product.id, id); setItems(items.filter(x=>x.id!==id)); onChanged&&onChanged(); } catch{}}
  async function saveOrder(newItems){
    // Persist sort_index incrementally
    const updates = [];
    newItems.forEach((img, idx) => { if (img.sort_index !== idx) updates.push(window.ProductImagesAPI.update(product.id, img.id, { sort_index: idx })); });
    if (updates.length) { try { await Promise.all(updates); toast.success('Ordre enregistré'); } catch { toast.error('Erreur enregistrement ordre'); } }
  }
  function onDragStart(e, idx){ e.dataTransfer.setData('text/plain', String(idx)); }
  function onDragOver(e){ e.preventDefault(); }
  async function onDrop(e, idx){ e.preventDefault(); const from = Number(e.dataTransfer.getData('text/plain')); if (!Number.isInteger(from)) return; if (from===idx) return; const arr = items.slice(); const [moved] = arr.splice(from,1); arr.splice(idx,0,moved); setItems(arr); await saveOrder(arr); }
  return (
    <div style={{ marginTop:8, marginBottom:12, padding:10, background:'var(--brand-card)', borderTop:'1px solid #eaeaea', borderRadius:8 }}>
      <div style={{ display:'flex', alignItems:'center', gap:8 }}>
        <b style={{ fontSize:14 }}>Galerie</b>
        <span style={{ fontSize:12, color:'#666' }}>Glissez les vignettes pour les réordonner</span>
      </div>
      <div style={{ display:'flex', gap:8, flexWrap:'wrap', marginTop:8 }}>
        {items.map((img, idx) => (
          <div key={img.id} draggable onDragStart={(e)=>onDragStart(e, idx)} onDragOver={onDragOver} onDrop={(e)=>onDrop(e, idx)} title="Glissez pour réordonner" style={{ position:'relative', cursor:'grab', padding:'4px', borderRadius:8, border:'1px dashed #ddd' }}>
            <div style={{ position:'absolute', top:4, left:4, fontSize:14, color:'#888', display:'flex', alignItems:'center', gap:4 }}>
              <span style={{ cursor:'grab' }}>≡</span>
            </div>
            <img src={img.url} alt="" width="96" height="96" style={{ objectFit:'cover', borderRadius:6, border:'1px solid #eee' }} onError={(e)=>{ e.currentTarget.src='/images/placeholder.svg'; }} />
            <button onClick={()=>del(img.id)} style={{ position:'absolute', top:2, right:2 }}>×</button>
          </div>
        ))}
      </div>
      <form onSubmit={add} style={{ display:'flex', gap:8, alignItems:'end', marginTop:8 }}>
        <div style={{ width:260 }}>
          <div style={{ fontSize:12, color:'#666', marginBottom:4 }}>Ajouter une image</div>
          <window.Components.ImageUploader value={url} onChange={setUrl} />
        </div>
        <button type="submit" disabled={!url}>Ajouter</button>
      </form>
      <div style={{ marginTop:8, fontSize:12, color:'#666' }}>Astuce: vous pouvez également téléverser une nouvelle image en remplaçant une vignette via l’outil d’upload ci-dessus, puis supprimer l’ancienne.</div>
    </div>
  );
}

function ProductOptionsManager({ product, onChanged }) {
  const [items, setItems] = React.useState([]);
  const [form, setForm] = React.useState({ name:'', price_euros:'', required:false });
  const toast = window.Toast.useToast();
  React.useEffect(()=>{ (async()=>{ try{ const res = await window.ProductOptionsAPI.list(product.id); setItems(res.items||[]);}catch{}})(); }, [product.id]);
  async function add(e){ e.preventDefault(); try{ const price_cents = form.price_euros===''?0:Math.round(Number(String(form.price_euros).replace(',', '.'))*100); const created = await window.ProductOptionsAPI.create(product.id, { name: form.name, price_cents, required: !!form.required }); setItems([...items, created]); setForm({ name:'', price_euros:'', required:false }); onChanged&&onChanged(); toast.success('Option ajoutée'); } catch(e){ toast.error(e?.error?.message||'Erreur ajout option'); } }
  async function del(id){ try{ await window.ProductOptionsAPI.remove(product.id, id); setItems(items.filter(x=>x.id!==id)); onChanged&&onChanged(); } catch{}}
  async function save(opt){ try{ await window.ProductOptionsAPI.update(product.id, opt.id, { name: opt.name, price_cents: opt.price_cents, required: !!opt.required }); toast.success('Option mise à jour'); } catch{ toast.error('Erreur mise à jour'); } }
  return (
    <div style={{ marginTop:8, marginBottom:12, padding:10, background:'var(--brand-card)', borderTop:'1px solid #eaeaea', borderRadius:8 }}>
      <b style={{ fontSize:14 }}>Options (cases à cocher)</b>
      {items.length===0 ? <p style={{ color:'#888', marginTop:6, fontSize:13 }}>Aucune option.</p> : (
        <table style={{ width:'100%', marginTop:8, borderCollapse:'collapse' }}>
          <thead><tr><th align="left">Nom</th><th align="right">+ Prix</th><th align="center">Requise</th><th></th></tr></thead>
          <tbody>
            {items.map((opt, idx)=> (
              <tr key={opt.id}>
                <td><input value={opt.name} onChange={e=>{ const v=e.target.value; setItems(items.map((x,i)=>i===idx?{...x,name:v}:x)); }} onBlur={()=>save(items[idx])} /></td>
                <td align="right"><input type="number" step="0.01" min="0" value={opt.price_cents/100} onChange={e=>{ const v=e.target.value; const cents=Math.round(Number(String(v).replace(',', '.'))*100)||0; setItems(items.map((x,i)=>i===idx?{...x,price_cents:cents}:x)); }} onBlur={()=>save(items[idx])} /></td>
                <td align="center"><input type="checkbox" checked={!!opt.required} onChange={e=>{ const v=e.target.checked; setItems(items.map((x,i)=>i===idx?{...x,required:v?1:0}:x)); save({ ...items[idx], required: v?1:0 }); }} /></td>
                <td align="right"><button onClick={()=>del(opt.id)}>Supprimer</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      )}
      <form onSubmit={add} style={{ display:'grid', gridTemplateColumns:'2fr 1fr 1fr auto', gap:8, alignItems:'end', marginTop:8 }}>
        <label>Nom<br/><input value={form.name} onChange={e=>setForm({...form,name:e.target.value})} required /></label>
        <label>+ Prix (€)<br/><input type="number" step="0.01" min="0" value={form.price_euros} onChange={e=>setForm({...form,price_euros:e.target.value})} /></label>
        <label style={{ alignSelf:'center' }}><input type="checkbox" checked={!!form.required} onChange={e=>setForm({...form, required:e.target.checked})} /> Requise</label>
        <button type="submit">Ajouter</button>
      </form>
    </div>
  );
}
