// ─── Zubehör (accessories) — inventory management + overview ───
// Data model per accessory:
//   { id, name, cat, qty, price (number|null → "zugehörig"), forEquipmentId (string|null),
//     note, defectQty }
// Rental storage:  rental.accessoryItems = [{ accessoryId, name, quantity, given, returned }]
const { useState: useStateZ, useEffect: useEffectZ } = React;

// Category list is now user-managed (starts empty). This map only supplies a nice
// default emoji when a category name happens to match — new names fall back to 📦.
const ACC_CAT_EMOJI = { 'Kabel': '🔌', 'Ständer': '🎚️', 'Adapter': '🔗', 'Taschen': '🎒', 'Batterien': '🔋', 'Sonstiges': '📦' };

// How many of an accessory are currently out (active/reserved rentals), and how many free.
function accStock(acc, rentals = [], excludeRentalId = null) {
  const total = Math.max(0, Number(acc.qty) || 0);
  const defect = Math.max(0, Number(acc.defectQty) || 0);
  let out = 0;
  for (const r of rentals) {
    if (excludeRentalId && r.id === excludeRentalId) continue;
    if (r.status !== 'aktiv' && r.status !== 'reserviert') continue;
    for (const a of (r.accessoryItems || [])) {
      if (a.accessoryId === acc.id && !a.returned) out += Math.max(0, Number(a.quantity) || 0);
    }
  }
  const available = Math.max(0, total - defect - out);
  return { total, defect, out, available };
}
if (typeof window !== 'undefined') window.accStock = accStock;

// ─── Add / edit accessory sheet ───────────────────────────────
function AccessorySheet({ open, onClose, initial, onSave, equipment = [], accCats = [], setAccCats }) {
  const t = useTheme();
  const blank = { id: '', name: '', cat: '', qty: 1, price: '', forEquipmentId: '', note: '', defectQty: 0, emoji: '', photo: '' };
  const [form, setForm] = useStateZ(blank);
  const [newCat, setNewCat] = useStateZ('');
  const [uploading, setUploading] = useStateZ(false);
  const [addingCat, setAddingCat] = useStateZ(false);
  useEffectZ(() => {
    if (open) { setForm(initial ? { ...blank, ...initial, price: initial.price == null ? '' : String(initial.price) } : blank); setAddingCat(false); setNewCat(''); }
  }, [open, initial]);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const valid = form.name.trim();
  const commitNewCat = () => {
    const c = newCat.trim();
    if (!c) { setAddingCat(false); return; }
    if (setAccCats && !accCats.includes(c)) setAccCats(prev => [...prev, c]);
    set('cat', c);
    setNewCat(''); setAddingCat(false);
  };

  const save = () => {
    const priceNum = String(form.price).trim() === '' ? null : Math.max(0, Number(form.price) || 0);
    onSave({
      ...form,
      id: form.id || 'acc-' + Date.now().toString(36),
      name: form.name.trim(),
      qty: Math.max(0, Number(form.qty) || 0),
      defectQty: Math.max(0, Number(form.defectQty) || 0),
      price: priceNum,
      forEquipmentId: form.forEquipmentId || null,
    });
    onClose();
  };

  const inp = { width: '100%', boxSizing: 'border-box', padding: '11px 13px', borderRadius: 11, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 15, color: t.text, outline: 'none', fontFamily: 'inherit' };

  const Stepper = ({ value, onChange, min = 0 }) => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <Pressable onClick={() => onChange(Math.max(min, (Number(value) || 0) - 1))} scale={0.85}>
        <div style={{ width: 34, height: 34, borderRadius: 17, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon d="M5 12h14" color={t.text} size={15} sw={2.4}/>
        </div>
      </Pressable>
      <div style={{ minWidth: 30, textAlign: 'center', fontSize: 18, fontWeight: 700, color: t.text, fontVariantNumeric: 'tabular-nums' }}>{Number(value) || 0}</div>
      <Pressable onClick={() => onChange((Number(value) || 0) + 1)} scale={0.85}>
        <div style={{ width: 34, height: 34, borderRadius: 17, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon d="M12 5v14M5 12h14" color={t.solidFg} size={15} sw={2.4}/>
        </div>
      </Pressable>
    </div>
  );

  return (
    <Sheet open={open} onClose={onClose}>
      <div style={{ padding: '4px 24px 24px' }}>
        <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5, marginBottom: 4 }}>
          {initial ? 'Zubehör bearbeiten' : 'Neues Zubehör'}
        </div>

        {/* Icon — photo or emoji, editable like equipment */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 8, marginBottom: 4 }}>
          <div style={{ position: 'relative', flexShrink: 0 }}>
            <AccAvatar acc={form} size={64} radius={16}/>
            {form.photo && (
              <Pressable onClick={() => set('photo', '')} scale={0.85} style={{ position: 'absolute', top: -6, right: -6 }}>
                <div style={{ width: 22, height: 22, borderRadius: 11, background: t.red, display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 2px 6px rgba(0,0,0,0.2)' }}>
                  <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="#fff" strokeWidth="2.4" strokeLinecap="round"><path d="M3 3l6 6M9 3l-6 6"/></svg>
                </div>
              </Pressable>
            )}
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <label style={{ display: 'block' }}>
              <input type="file" accept="image/*" style={{ display: 'none' }}
                onChange={async (e) => {
                  const file = e.target.files && e.target.files[0];
                  if (!file) return;
                  setUploading(true);
                  try { const url = await compressImage(file); set('photo', url); }
                  catch { /* ignore */ }
                  setUploading(false);
                }}/>
              <div style={{ padding: '10px 14px', borderRadius: 12, background: t.accentSoft, color: t.accent, fontSize: 13.5, fontWeight: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, cursor: 'pointer' }}>
                <Icon d={icons.camera} color={t.accent} size={16} sw={1.8}/>
                {uploading ? 'Lädt…' : (form.photo ? 'Foto ändern' : 'Foto hochladen')}
              </div>
            </label>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
              <input value={form.emoji || ''}
                onChange={(e) => { set('emoji', e.target.value); if (e.target.value && form.photo) set('photo', ''); }}
                placeholder="oder Emoji / Buchstabe …" maxLength={8}
                style={{ ...inp, flex: 1, fontFamily: 'inherit' }}/>
              {form.emoji && (
                <Pressable onClick={() => set('emoji', '')} scale={0.85}>
                  <div style={{ padding: '9px 12px', borderRadius: 10, background: t.chip, fontSize: 12, fontWeight: 600, color: t.text }}>Zurück</div>
                </Pressable>
              )}
            </div>
          </div>
        </div>

        <FormGroup label="Name" required>
          <input value={form.name} onChange={e => set('name', e.target.value)} placeholder="z.B. XLR-Kabel 5m" style={inp} autoFocus/>
        </FormGroup>

        <FormGroup label="Kategorie">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center' }}>
            {accCats.map(c => {
              const on = form.cat === c;
              return (
                <Pressable key={c} onClick={() => set('cat', c)} scale={0.95}>
                  <div style={{ padding: '8px 13px', borderRadius: 100, fontSize: 13, fontWeight: 600, background: on ? t.solidBg : t.chip, color: on ? t.solidFg : t.text }}>{c}</div>
                </Pressable>
              );
            })}
            {addingCat ? (
              <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <input value={newCat} onChange={e => setNewCat(e.target.value)} autoFocus
                  onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); commitNewCat(); } }}
                  placeholder="Neue Kategorie" style={{ ...inp, width: 150, padding: '7px 11px', fontSize: 13 }}/>
                <Pressable onClick={commitNewCat} scale={0.9}>
                  <div style={{ width: 32, height: 32, borderRadius: 16, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <Icon d="M5 12l5 5L20 7" color={t.solidFg} size={15} sw={2.6}/>
                  </div>
                </Pressable>
              </div>
            ) : (
              <Pressable onClick={() => { setAddingCat(true); setNewCat(''); }} scale={0.9}>
                <div style={{ padding: '8px 12px', borderRadius: 100, fontSize: 13, fontWeight: 600, background: t.chip, color: t.textSec, display: 'flex', alignItems: 'center', gap: 5, border: `1px dashed ${t.sep}` }}>
                  <Icon d={icons.edit} color={t.textSec} size={13} sw={2}/> Kategorie
                </div>
              </Pressable>
            )}
          </div>
          {accCats.length === 0 && !addingCat &&
            <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 6 }}>Noch keine Kategorien — mit „✎ Kategorie“ eine anlegen.</div>}
        </FormGroup>

        <div style={{ display: 'flex', gap: 12, marginTop: 14 }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>Anzahl Bestand</div>
            <Stepper value={form.qty} onChange={v => set('qty', v)} min={0}/>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>Davon defekt</div>
            <Stepper value={form.defectQty} onChange={v => set('defectQty', v)} min={0}/>
          </div>
        </div>

        <FormGroup label="Tagespreis € (leer = nur zugehörig)">
          <input value={form.price} onChange={e => set('price', e.target.value)} inputMode="decimal"
            placeholder="leer lassen → nicht einzeln verleihbar" style={inp}/>
          <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 6 }}>
            {String(form.price).trim() === ''
              ? 'Ohne Preis: gehört als Zubehör zu Geräten, wird nicht einzeln berechnet.'
              : 'Mit Preis: kann auch eigenständig verliehen werden.'}
          </div>
        </FormGroup>

        <FormGroup label="Passt zu (Gerät)">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            <Pressable onClick={() => set('forEquipmentId', '')} scale={0.95}>
              <div style={{ padding: '8px 13px', borderRadius: 100, fontSize: 13, fontWeight: 600, background: !form.forEquipmentId ? t.solidBg : t.chip, color: !form.forEquipmentId ? t.solidFg : t.text }}>— keins —</div>
            </Pressable>
            {equipment.map(eq => {
              const on = form.forEquipmentId === eq.id;
              return (
                <Pressable key={eq.id} onClick={() => set('forEquipmentId', eq.id)} scale={0.95}>
                  <div style={{ padding: '8px 13px', borderRadius: 100, fontSize: 13, fontWeight: 600, background: on ? t.solidBg : t.chip, color: on ? t.solidFg : t.text }}>{eq.name}</div>
                </Pressable>
              );
            })}
          </div>
        </FormGroup>

        <FormGroup label="Notiz">
          <textarea value={form.note} onChange={e => set('note', e.target.value)} rows={2}
            placeholder="z.B. Zustand, Besonderheiten…" style={{ ...inp, resize: 'none', lineHeight: 1.4 }}/>
        </FormGroup>

        <Pressable onClick={valid ? save : null} scale={valid ? 0.97 : 1} style={{ marginTop: 20 }}>
          <div style={{ padding: '15px', textAlign: 'center', borderRadius: 14, background: valid ? t.solidBg : t.chip, color: valid ? t.solidFg : t.textTer, fontSize: 15, fontWeight: 700 }}>
            {initial ? 'Speichern' : 'Zubehör anlegen'}
          </div>
        </Pressable>
      </div>
    </Sheet>
  );
}

// ─── One accessory row in the overview ────────────────────────
function AccRow({ acc, t, rentals, equipment, onEdit, onDelete, view = 'card', showIcons = true }) {
  const { total, out, available, defect } = accStock(acc, rentals);
  const low = available === 0 || (total > 0 && available <= Math.max(1, Math.floor(total * 0.2)));
  const eq = acc.forEquipmentId ? equipment.find(e => e.id === acc.forEquipmentId) : null;
  const standalone = acc.price != null && Number(acc.price) > 0;
  const compact = view === 'compact' || view === 'table';

  const [menu, setMenu] = useStateZ(false);

  if (compact) {
    return (
      <div style={{ position: 'relative' }}>
        <Pressable onClick={onEdit} scale={0.99}>
          <div style={{ background: t.card, borderRadius: 12, padding: '10px 12px', border: `0.5px solid ${t.sep}`, display: 'flex', alignItems: 'center', gap: 10 }}>
            {showIcons && <AccAvatar acc={acc} size={30} radius={8}/>}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 13.5, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{acc.name}</div>
              <div style={{ fontSize: 11, color: t.textSec, marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{acc.cat}{standalone ? ` · ${acc.price} €/Tag` : ' · zugehörig'}</div>
            </div>
            <div style={{ textAlign: 'right', flexShrink: 0, fontVariantNumeric: 'tabular-nums' }}>
              <div style={{ fontSize: 13.5, fontWeight: 700, color: low ? t.orange : t.text }}>{available}/{total}</div>
              <div style={{ fontSize: 10, color: t.textSec }}>frei</div>
            </div>
          </div>
        </Pressable>
      </div>
    );
  }

  return (
    <div style={{ position: 'relative' }}>
      <Pressable onClick={onEdit} scale={0.99}>
        <div style={{ background: t.card, borderRadius: 14, padding: '12px 14px', boxShadow: t.shadowCard, display: 'flex', alignItems: 'center', gap: 12 }}>
          {showIcons && <AccAvatar acc={acc} size={42} radius={11}/>}
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 14.5, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{acc.name}</div>
            <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 2, display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
              <span>{acc.cat}</span>
              {standalone
                ? <span style={{ color: t.accent, fontWeight: 600 }}>· {acc.price} €/Tag</span>
                : <span style={{ fontWeight: 600 }}>· zugehörig</span>}
              {eq && <span style={{ padding: '1px 7px', borderRadius: 100, background: t.chip, fontWeight: 600 }}>zu {eq.name}</span>}
            </div>
          </div>
          <div style={{ textAlign: 'right', flexShrink: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 700, color: low ? t.orange : t.text, fontVariantNumeric: 'tabular-nums' }}>
              {available}<span style={{ color: t.textSec, fontWeight: 600 }}>/{total}</span>
            </div>
            <div style={{ fontSize: 10, color: t.textSec, marginTop: 1 }}>verfügbar</div>
          </div>
          <Pressable onClick={(e) => { e.stopPropagation && e.stopPropagation(); setMenu(m => !m); }} scale={0.85}>
            <div style={{ width: 28, height: 28, borderRadius: 14, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <Icon d="M12 5h.01M12 12h.01M12 19h.01" color={t.textSec} size={18} sw={2.4}/>
            </div>
          </Pressable>
        </div>
      </Pressable>
      {(out > 0 || defect > 0) && (
        <div style={{ display: 'flex', gap: 6, padding: '6px 14px 0' }}>
          {out > 0 && <span style={{ fontSize: 10.5, fontWeight: 700, color: t.green, background: t.greenSoft, padding: '2px 8px', borderRadius: 100 }}>{out}× verliehen</span>}
          {defect > 0 && <span style={{ fontSize: 10.5, fontWeight: 700, color: t.orange, background: t.orangeSoft, padding: '2px 8px', borderRadius: 100 }}>{defect}× defekt</span>}
        </div>
      )}
      {menu && (
        <>
          <div onClick={() => setMenu(false)} style={{ position: 'fixed', inset: 0, zIndex: 40 }}/>
          <div style={{ position: 'absolute', right: 14, top: 44, zIndex: 41, background: t.sheetBg, borderRadius: 12, boxShadow: '0 8px 30px rgba(0,0,0,0.25)', overflow: 'hidden', minWidth: 140 }}>
            <Pressable onClick={() => { setMenu(false); onEdit(); }} scale={0.98}>
              <div style={{ padding: '11px 16px', fontSize: 14, color: t.text, fontWeight: 500 }}>Bearbeiten</div>
            </Pressable>
            <div style={{ height: 0.5, background: t.sep }}/>
            <Pressable onClick={() => { setMenu(false); onDelete(); }} scale={0.98}>
              <div style={{ padding: '11px 16px', fontSize: 14, color: t.red, fontWeight: 500 }}>Löschen</div>
            </Pressable>
          </div>
        </>
      )}
    </div>
  );
}

function accCatEmoji(cat) {
  return ACC_CAT_EMOJI[cat] || '📦';
}

// Accessory avatar — photo > custom emoji > category emoji, on a soft tile.
// Mirrors EqAvatar so accessories get the same editable icon as equipment.
function AccAvatar({ acc = {}, size = 42, radius = 11 }) {
  const t = useTheme();
  const tileFill = 'transparent';
  const tile = {
    width: size, height: size, borderRadius: radius, flexShrink: 0, background: tileFill,
    display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden'
  };
  if (acc.photo) {
    return <div style={tile}><img src={acc.photo} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}/></div>;
  }
  return <div style={tile}><span style={{ fontSize: Math.round(size * 0.46), lineHeight: 1 }}>{acc.emoji || accCatEmoji(acc.cat)}</span></div>;
}

// ─── Main Zubehör overview (embedded in Equipment screen) ─────
function ScreenZubehoer({ accessories, setAccessories, accCats = [], setAccCats, equipment = [], rentals = [], toast, newNonce, view = 'card', showIcons = true }) {
  const t = useTheme();
  const [sheetOpen, setSheetOpen] = useStateZ(false);
  const [editing, setEditing] = useStateZ(null);
  const [confirmId, setConfirmId] = useStateZ(null);
  const [filter, setFilter] = useStateZ('Alle');

  // Parent's "+" button bumps newNonce → open the add sheet.
  useEffectZ(() => { if (newNonce) { setEditing(null); setSheetOpen(true); } }, [newNonce]);

  const openNew = () => { setEditing(null); setSheetOpen(true); };
  const onSave = (acc) => {
    setAccessories(prev => {
      const exists = prev.find(p => p.id === acc.id);
      if (exists) return prev.map(p => p.id === acc.id ? acc : p);
      return [acc, ...prev];
    });
    toast && toast(editing ? 'Gespeichert' : `„${acc.name}“ hinzugefügt`);
  };
  const doDelete = () => {
    const a = accessories.find(x => x.id === confirmId);
    setAccessories(prev => prev.filter(p => p.id !== confirmId));
    toast && toast(`„${a ? a.name : 'Zubehör'}“ gelöscht`);
    setConfirmId(null);
  };

  // Summary numbers
  const totalUnits = accessories.reduce((s, a) => s + (Number(a.qty) || 0), 0);
  const outUnits = accessories.reduce((s, a) => s + accStock(a, rentals).out, 0);
  const lowCount = accessories.filter(a => { const s = accStock(a, rentals); return s.total > 0 && s.available <= Math.max(1, Math.floor(s.total * 0.2)); }).length;

  // Category order: managed list first, then any leftover categories found on items.
  const usedCats = [...new Set(accessories.map(a => a.cat).filter(Boolean))];
  const orderedCats = [...accCats, ...usedCats.filter(c => !accCats.includes(c))];
  const cats = ['Alle', ...orderedCats.filter(c => accessories.some(a => a.cat === c))];
  const shown = filter === 'Alle' ? accessories : accessories.filter(a => a.cat === filter);

  // Group by category for the "Alle" view
  const groups = {};
  for (const a of shown) { (groups[a.cat || 'Ohne Kategorie'] = groups[a.cat || 'Ohne Kategorie'] || []).push(a); }
  const groupOrder = [...orderedCats.filter(c => groups[c]), ...(groups['Ohne Kategorie'] ? ['Ohne Kategorie'] : [])];

  return (
    <div style={{ paddingBottom: 20 }}>
      {accessories.length > 0 && (
        <>
          {/* Summary card */}
          {/* Category filter */}
          <div style={{ padding: '14px 16px 0', display: 'flex', gap: 8, overflowX: 'auto' }}>
            {cats.map(c => (
              <Pressable key={c} onClick={() => setFilter(c)} scale={0.94}>
                <div style={{ padding: '7px 14px', borderRadius: 100, fontSize: 13, fontWeight: 600, whiteSpace: 'nowrap', background: filter === c ? t.solidBg : t.chip, color: filter === c ? t.solidFg : t.text }}>{c}</div>
              </Pressable>
            ))}
          </div>
        </>
      )}

      {/* List (grouped by category when showing all) */}
      <div style={{ padding: '14px 16px 0' }}>
        {accessories.length === 0 ? (
          <Pressable onClick={openNew}>
            <div style={{ textAlign: 'center', padding: '48px 20px', color: t.textSec, fontSize: 13.5, background: t.card, borderRadius: 16, border: `1px dashed ${t.sep}` }}>
              Noch kein Zubehör angelegt.<br/>
              <span style={{ color: t.accent, fontWeight: 600 }}>+ Erstes Zubehör anlegen</span>
            </div>
          </Pressable>
        ) : filter === 'Alle' ? (
          groupOrder.map(cat => (
            <div key={cat} style={{ marginBottom: 18 }}>
              <div style={{ fontSize: 11, color: t.textSec, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.6, marginBottom: 8, paddingLeft: 2 }}>{cat}</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {groups[cat].map(a => <AccRow key={a.id} acc={a} t={t} rentals={rentals} equipment={equipment} view={view} showIcons={showIcons} onEdit={() => { setEditing(a); setSheetOpen(true); }} onDelete={() => setConfirmId(a.id)}/>)}
              </div>
            </div>
          ))
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {shown.map(a => <AccRow key={a.id} acc={a} t={t} rentals={rentals} equipment={equipment} view={view} showIcons={showIcons} onEdit={() => { setEditing(a); setSheetOpen(true); }} onDelete={() => setConfirmId(a.id)}/>)}
          </div>
        )}
      </div>

      <AccessorySheet open={sheetOpen} onClose={() => setSheetOpen(false)} initial={editing} onSave={onSave} equipment={equipment} accCats={accCats} setAccCats={setAccCats}/>
      <Confirm open={!!confirmId} title="Zubehör löschen?" message="Das Zubehör wird dauerhaft entfernt."
        onCancel={() => setConfirmId(null)} onConfirm={doDelete}/>
    </div>
  );
}

Object.assign(window, { ScreenZubehoer, accStock, accCatEmoji });

// ─── Accessory editor used inside a rental (add/remove/qty + pricing + collisions) ───
// value = accessoryItems: [{ accessoryId, name, quantity, dailyRate }]
function AccessoryRentalEditor({ value = [], onChange, accessories = [], equipmentItems = [], rentals = [], excludeRentalId, rentalStart, rentalEnd, days = 1, showIcons = true }) {
  const t = useTheme();
  const [picking, setPicking] = useStateZ(false);
  const items = value || [];

  if (!accessories.length) return null; // nothing to manage yet

  const byId = (id) => accessories.find(a => a.id === id);
  const setQty = (id, q) => onChange(items.map(it => it.accessoryId === id ? { ...it, quantity: Math.max(1, q) } : it));
  const remove = (id) => onChange(items.filter(it => it.accessoryId !== id));

  // Auto-suggest: accessories whose forEquipmentId matches one of the rental's equipment items
  const eqIds = new Set((equipmentItems || []).map(e => e.equipmentId));
  const suggested = accessories.filter(a => a.forEquipmentId && eqIds.has(a.forEquipmentId) && !items.some(it => it.accessoryId === a.id));
  const mkItem = (a, quantity) => ({ accessoryId: a.id, name: a.name, quantity, dailyRate: (a.price != null && Number(a.price) > 0) ? Number(a.price) : 0 });
  const takeSuggested = () => onChange([...items, ...suggested.map(a => mkItem(a, 1))]);

  const addBulk = (picks) => {
    const existing = new Set(items.map(it => it.accessoryId));
    const additions = picks.filter(p => !existing.has(p.acc.id)).map(p => mkItem(p.acc, p.quantity));
    let next = items.map(it => { const hit = picks.find(p => p.acc.id === it.accessoryId); return hit ? { ...it, quantity: it.quantity + hit.quantity } : it; });
    onChange([...next, ...additions]);
    setPicking(false);
  };

  const billDays = Math.max(1, Number(days) || 1);
  const accTotal = items.reduce((s, it) => s + billDays * (Number(it.dailyRate) || 0) * Math.max(1, Number(it.quantity) || 1), 0);

  return (
    <div>
      {suggested.length > 0 && (
        <Pressable onClick={takeSuggested} scale={0.98} style={{ marginBottom: 8 }}>
          <div style={{ padding: '10px 12px', borderRadius: 12, background: t.accentSoft, display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ fontSize: 15 }}>💡</span>
            <div style={{ flex: 1, fontSize: 12.5, color: t.accent, fontWeight: 600 }}>
              Zubehör der Geräte übernehmen ({suggested.map(s => s.name).join(', ')})
            </div>
            <Icon d="M12 5v14M5 12h14" color={t.accent} size={15} sw={2.4}/>
          </div>
        </Pressable>
      )}

      {items.length > 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 8 }}>
          {items.map(it => {
            const acc = byId(it.accessoryId);
            const clash = (acc && rentalStart && rentalEnd && window.accessoryConflicts)
              ? window.accessoryConflicts(it.accessoryId, it.quantity, rentalStart, rentalEnd, accessories, rentals, excludeRentalId) : null;
            const paid = (Number(it.dailyRate) || 0) > 0;
            const lineCost = billDays * (Number(it.dailyRate) || 0) * Math.max(1, Number(it.quantity) || 1);
            return (
              <div key={it.accessoryId} style={{ background: t.card, borderRadius: 12, padding: '10px 12px', boxShadow: t.shadowCard, border: clash ? `1px solid ${t.orange}` : 'none' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  {showIcons && <span style={{ fontSize: 16 }}>{accCatEmoji(acc ? acc.cat : '')}</span>}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{it.name}</div>
                    <div style={{ fontSize: 10.5, color: clash ? t.orange : t.textSec, marginTop: 1 }}>
                      {clash ? `⚠ nur ${clash.total} verfügbar`
                        : paid ? `${it.dailyRate} €/Tag · ${lineCost} €` : 'zugehörig · kostenlos'}
                    </div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <Pressable onClick={() => setQty(it.accessoryId, it.quantity - 1)} scale={0.85}>
                      <div style={{ width: 28, height: 28, borderRadius: 14, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon d="M5 12h14" color={t.text} size={13} sw={2.4}/></div>
                    </Pressable>
                    <div style={{ minWidth: 20, textAlign: 'center', fontSize: 14, fontWeight: 700, color: t.text, fontVariantNumeric: 'tabular-nums' }}>{it.quantity}</div>
                    <Pressable onClick={() => setQty(it.accessoryId, it.quantity + 1)} scale={0.85}>
                      <div style={{ width: 28, height: 28, borderRadius: 14, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon d="M12 5v14M5 12h14" color={t.solidFg} size={13} sw={2.4}/></div>
                    </Pressable>
                    <Pressable onClick={() => remove(it.accessoryId)} scale={0.85}>
                      <div style={{ width: 28, height: 28, borderRadius: 14, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon d="M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14" color={t.textSec} size={14} sw={1.8}/></div>
                    </Pressable>
                  </div>
                </div>
              </div>
            );
          })}
          {accTotal > 0 && (
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '2px 4px', fontSize: 12.5 }}>
              <span style={{ color: t.textSec, fontWeight: 600 }}>Zubehör-Anteil ({billDays} {billDays > 1 ? 'Tage' : 'Tag'})</span>
              <span style={{ color: t.text, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{accTotal} €</span>
            </div>
          )}
        </div>
      )}

      {picking ? (
        <AccessoryPicker accessories={accessories} rentals={rentals} excludeRentalId={excludeRentalId}
          rentalStart={rentalStart} rentalEnd={rentalEnd}
          showIcons={showIcons}
          onCancel={() => setPicking(false)} onCommit={addBulk}/>
      ) : (
        <Pressable onClick={() => setPicking(true)} scale={0.98}>
          <div style={{ padding: '8px 14px', textAlign: 'center', borderRadius: 10, background: 'transparent', color: t.text, fontSize: 12.5, fontWeight: 600, border: `1px dashed ${t.textTer}`, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 5 }}>
            <Icon d="M12 5v14M5 12h14" color={t.text} size={13} sw={2.4}/> Zubehör hinzufügen
          </div>
        </Pressable>
      )}
    </div>
  );
}

// Multi-select accessory picker (bulk add with quantities + availability)
function AccessoryPicker({ accessories, rentals = [], excludeRentalId, rentalStart, rentalEnd, onCommit, onCancel, showIcons = true }) {
  const t = useTheme();
  const [qty, setQty] = useStateZ({});
  const [query, setQuery] = useStateZ('');
  const bump = (id, d) => setQty(p => ({ ...p, [id]: Math.max(0, (p[id] || 0) + d) }));
  const q = query.trim().toLowerCase();
  const filtered = q ? accessories.filter(a => (a.name + ' ' + a.cat).toLowerCase().includes(q)) : accessories;
  const distinct = accessories.filter(a => (qty[a.id] || 0) > 0);
  const totalUnits = distinct.reduce((s, a) => s + qty[a.id], 0);
  const commit = () => { if (distinct.length) onCommit(distinct.map(a => ({ acc: a, quantity: qty[a.id] }))); };

  return (
    <div style={{ background: t.card, borderRadius: 16, padding: 12, border: `0.5px solid ${t.sep}`, boxShadow: t.shadowCard }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 2px 10px' }}>
        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.8 }}>Zubehör auswählen</div>
        <Pressable onClick={onCancel} scale={0.9}><div style={{ height: 26, padding: '0 12px', borderRadius: 999, background: t.chip, display: 'flex', alignItems: 'center', fontSize: 12, color: t.textSec, fontWeight: 600 }}>Abbrechen</div></Pressable>
      </div>
      {accessories.length > 6 && (
        <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Suchen …"
          style={{ width: '100%', boxSizing: 'border-box', padding: '10px 14px', marginBottom: 10, borderRadius: 999, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, color: t.text, fontSize: 13, outline: 'none', fontFamily: 'inherit' }}/>
      )}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxHeight: 320, overflowY: 'auto' }}>
        {filtered.length === 0 && <div style={{ textAlign: 'center', padding: 16, fontSize: 12.5, color: t.textSec }}>Nichts gefunden.</div>}
        {filtered.map(a => {
          const n = qty[a.id] || 0;
          const active = n > 0;
          const stock = accStock(a, rentals, excludeRentalId);
          const over = n > stock.available;
          return (
            <div key={a.id} style={{ padding: '10px 12px', background: active ? t.accentSoft : t.card, borderRadius: 14, display: 'flex', alignItems: 'center', gap: 12, border: `0.5px solid ${active ? t.accent : t.sep}`, boxShadow: active ? 'none' : t.shadowCard, transition: 'background 0.15s, border-color 0.15s' }}>
              {showIcons && <AccAvatar acc={a} size={38} radius={10}/>}
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13.5, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{a.name}</div>
                <div style={{ fontSize: 11.5, color: over ? t.orange : t.textSec, marginTop: 2 }}>{over ? `nur ${stock.available} frei` : `${stock.available} frei${a.price != null && a.price > 0 ? ` · ${a.price} €/Tag` : ''}`}</div>
              </div>
              {active ? (
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
                  <Pressable onClick={() => bump(a.id, -1)} scale={0.85}><div style={{ width: 30, height: 30, borderRadius: 15, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon d="M5 12h14" color={t.text} size={13} sw={2.4}/></div></Pressable>
                  <div style={{ minWidth: 20, textAlign: 'center', fontSize: 15, fontWeight: 700, color: t.text, fontVariantNumeric: 'tabular-nums' }}>{n}</div>
                  <Pressable onClick={() => bump(a.id, 1)} scale={0.85}><div style={{ width: 30, height: 30, borderRadius: 15, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon d="M12 5v14M5 12h14" color={t.solidFg} size={13} sw={2.4}/></div></Pressable>
                </div>
              ) : (
                <Pressable onClick={() => bump(a.id, 1)} scale={0.85}><div style={{ width: 30, height: 30, borderRadius: 15, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon d="M12 5v14M5 12h14" color={t.solidFg} size={14} sw={2.4}/></div></Pressable>
              )}
            </div>
          );
        })}
      </div>
      <Pressable onClick={commit} scale={totalUnits ? 0.97 : 1}>
        <div style={{ marginTop: 12, padding: '13px 14px', textAlign: 'center', borderRadius: 999, background: totalUnits ? t.solidBg : t.chip, color: totalUnits ? t.solidFg : t.textTer, fontSize: 14, fontWeight: 700 }}>
          {totalUnits ? `${totalUnits} hinzufügen` : 'Menge wählen …'}
        </div>
      </Pressable>
    </div>
  );
}

Object.assign(window, { AccessoryRentalEditor });
