// katalog-parts.jsx — Bausteine für den Mietkatalog-Flow:
// QtyStepper, ItemRow, ItemModal, Panel (Deine Liste), ServicesStep, FormStep.

// ---------- Preis-Helfer ----------
// Preise sind Tagesmiet-Richtwerte als String ("30€", "0,50€", "" = auf Anfrage).
function parsePrice(p) {
  if (!p) return 0;
  const m = String(p).match(/(\d+(?:[.,]\d+)?)/);
  return m ? parseFloat(m[1].replace(',', '.')) : 0;
}
function formatEuro(n) {
  return n.toLocaleString('de-DE', {
    minimumFractionDigits: n % 1 === 0 ? 0 : 2,
    maximumFractionDigits: 2,
  }) + '\u00a0€';
}

// --- Mehrtages-Preismodell ---
// Technik/Boxen: 1. Tag voll (1×), jeder weitere Tag +0,5× → 1 + 0,5·(Tage−1)
// Transport/Hänger: linear, Faktor 1 pro Tag → Tage
function isLinearItem(item) {
  return (item.category || item.subCategory || '').toLowerCase().includes('transport');
}
function dayFactor(days, linear) {
  const d = Math.max(1, days || 1);
  return linear ? d : 1 + 0.5 * (d - 1);
}
// Endpreis einer Position über die gesamte Mietdauer
function itemTotal(item, qty, days) {
  return parsePrice(item.price) * qty * dayFactor(days, isLinearItem(item));
}
// Summen über alle Gruppen für eine Mietdauer
function priceStats(groups, days) {
  let total = 0, perDay = 0, unpriced = 0;
  for (const g of groups) for (const { item, qty } of g.items) {
    const v = parsePrice(item.price);
    if (v > 0) { perDay += v * qty; total += itemTotal(item, qty, days); }
    else unpriced += qty;
  }
  return { total, perDay, unpriced };
}

const SERVICES = [
  { id: 'ton',       icon: 'sliders-horizontal', name: 'Tontechniker',          desc: 'Mischt dein Event — vom Soundcheck bis zur letzten Zugabe.' },
  { id: 'licht',     icon: 'lightbulb',          name: 'Lichttechniker',        desc: 'Fährt die Show live — Stimmung statt Standbild.' },
  { id: 'aufbau',    icon: 'hammer',             name: 'Auf- & Abbau',          desc: 'Wir bauen auf, du feierst, wir bauen wieder ab.' },
  { id: 'transport', icon: 'truck',              name: 'Lieferung & Transport', desc: 'Wir bringen die Technik zur Location — und holen sie wieder ab.' },
  { id: 'dj',        icon: 'disc-3',             name: 'DJ',                    desc: 'Auf Wunsch inklusive Abstimmung deiner Musikwünsche.' },
  { id: 'planung',   icon: 'pencil-ruler',       name: 'Planung & Beratung',    desc: 'Wir denken dein Event vorab technisch durch — du bekommst ein Konzept.' },
];

// ---------- Einmalige Intro-Tour ----------
const INTRO_KEY = 'nf_katalog_intro_seen';
const INTRO_STEPS = [
  {
    num: '01',
    title: 'Technik wählen',
    text: 'Klick dich durch die Kategorien und leg per Klick auf deine Liste, was du brauchst. Mengen passt du direkt in der Zeile an.',
  },
  {
    num: '02',
    title: 'Services dazu',
    text: 'Brauchst du Hände dazu? Techniker, Auf- & Abbau, Lieferung oder DJ — einfach ankreuzen, oder überspringen.',
  },
  {
    num: '03',
    title: 'Anfrage senden',
    text: 'Kurz Name, Datum und Ort eintragen — deine Liste geht als E-Mail an uns. Du bekommst ein Angebot, meistens innerhalb von 48 h.',
  },
];

function IntroTour({ onDone }) {
  const [idx, setIdx] = React.useState(0);
  const last = idx === INTRO_STEPS.length - 1;
  const s = INTRO_STEPS[idx];
  const finish = () => {
    try { localStorage.setItem(INTRO_KEY, '1'); } catch (e) {}
    onDone();
  };
  React.useEffect(() => {
    const onKey = e => { if (e.key === 'Escape') finish(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);
  return (
    <div className="intro-bg" data-screen-label="Katalog Intro-Tour">
      <div className="intro-card" key={idx}>
        <button type="button" className="intro-skip mono" onClick={finish}>Überspringen</button>
        <div className="mono intro-kicker">// SO FUNKTIONIERT'S · {s.num} / 0{INTRO_STEPS.length}</div>
        <div className="display intro-num" aria-hidden="true">{s.num}</div>
        <h2 className="display intro-title">{s.title}</h2>
        <p className="intro-text">{s.text}</p>
        <div className="intro-foot">
          <div className="intro-dots" aria-hidden="true">
            {INTRO_STEPS.map((_, i) => (
              <button type="button" key={i} className={'dot' + (i === idx ? ' on' : '')} onClick={() => setIdx(i)} aria-label={'Schritt ' + (i + 1)}></button>
            ))}
          </div>
          <button type="button" className="btn btn-fill" onClick={() => last ? finish() : setIdx(idx + 1)}>
            <span>{last ? "Los geht's" : 'Weiter'}</span><span className="arrow">→</span>
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------- Mengen-Stepper ----------
function QtyStepper({ qty, onMinus, onPlus }) {
  return (
    <span className="qty" onClick={e => e.stopPropagation()}>
      <button type="button" onClick={onMinus} aria-label="Weniger">−</button>
      <span className="mono q bump" key={qty}>{qty}</span>
      <button type="button" onClick={onPlus} aria-label="Mehr">+</button>
    </span>
  );
}

// ---------- Artikel-Bild / Platzhalter ----------
function ItemThumb({ item, big }) {
  if (item.image) {
    return (
      <span className={'thumb' + (big ? ' thumb-big' : '')}>
        <img src={item.image} alt={item.name} loading="lazy" />
      </span>
    );
  }
  return (
    <span className={'thumb thumb-empty' + (big ? ' thumb-big' : '')} aria-hidden="true">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
        <rect x="3" y="3" width="18" height="18"></rect>
        <circle cx="8.5" cy="8.5" r="1.5"></circle>
        <path d="M21 15.5l-4.5-4.5L6 21"></path>
      </svg>
      {big ? <span className="mono thumb-note">FOTO FOLGT</span> : null}
    </span>
  );
}

// ---------- Artikel-Zeile ----------
function ItemRow({ item, qty, onAdd, onQty, onInfo, showCat }) {
  const added = qty > 0;
  return (
    <div className={'row' + (added ? ' added' : '')} onClick={() => { if (!added) onAdd(item); }}>
      <div className="row-add">
        {added
          ? <QtyStepper qty={qty} onMinus={() => onQty(item, qty - 1)} onPlus={() => onQty(item, qty + 1)} />
          : <span className="plus" aria-hidden="true">+</span>}
      </div>
      <ItemThumb item={item} />
      <div className="row-main">
        <div className="row-top">
          <span className="row-name">{item.name}</span>
          {item.type && item.type !== item.name && <span className="chip">{item.type}</span>}
        </div>
        {showCat
          ? <div className="row-sub">{item.category}{item.subCategory && item.subCategory !== item.category ? ' · ' + item.subCategory : ''}</div>
          : (item.specs ? <div className="row-sub">{item.specs}</div> : null)}
      </div>
      <div className="row-side">
        {parsePrice(item.price) > 0 ? <span className="mono row-price" style={{ color: 'var(--neon)', fontWeight: 600 }}>{formatEuro(parsePrice(item.price))}</span> : null}
        {item.artNr ? <span className="mono row-art">{item.artNr}</span> : null}
        <button type="button" className="info" onClick={e => { e.stopPropagation(); onInfo(item); }} aria-label="Details ansehen">i</button>
      </div>
    </div>
  );
}

// ---------- Detail-Modal ----------
function ItemModal({ item, qty, onClose, onAdd, onQty }) {
  if (!item) return null;
  const added = qty > 0;
  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <button type="button" className="close-x" onClick={onClose} aria-label="Schließen">×</button>
        <ItemThumb item={item} big />
        <div className="modal-pad">
          {item.type && item.type !== item.name && <span className="chip">{item.type}</span>}
          <h2 className="display" style={{ marginTop: 12 }}>{item.name}</h2>
          {parsePrice(item.price) > 0 ? (
            <div className="mono" style={{ color: 'var(--neon)', fontWeight: 600, fontSize: 15, margin: '4px 0 12px' }}>
              {formatEuro(parsePrice(item.price))} <span style={{ color: 'var(--ink-soft)', fontWeight: 400 }}>/ Tag · Richtwert</span>
            </div>
          ) : null}
          {item.description ? <p style={{ fontSize: 15, lineHeight: 1.6, color: 'var(--paper)' }}>{item.description}</p> : null}
          {item.specs ? (
            <React.Fragment>
              <h4>Technische Daten</h4>
              <div className="specs">{item.specs}</div>
            </React.Fragment>
          ) : null}
        </div>
        <div className="modal-foot">
          <span className="mono" style={{ fontSize: 11, color: 'var(--ink-soft)', letterSpacing: '0.12em' }}>
            {item.artNr ? 'ART. ' + item.artNr + ' · ' : ''}{(item.category || '').toUpperCase()}
          </span>
          {added
            ? <QtyStepper qty={qty} onMinus={() => onQty(item, qty - 1)} onPlus={() => onQty(item, qty + 1)} />
            : <button type="button" className="btn btn-fill" style={{ padding: '12px 18px' }} onClick={() => onAdd(item)}>
                <span>Auf die Liste</span><span className="arrow">+</span>
              </button>}
        </div>
      </div>
    </div>
  );
}

// ---------- Mietdauer-Stepper (Tage) ----------
function DurationStepper({ days, setDays, light }) {
  const col = light ? 'rgba(10,10,10,0.55)' : 'var(--ink-soft)';
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, paddingBottom: 12, marginBottom: 12, borderBottom: '1px solid var(--hair)' }}>
      <div>
        <div className="mono" style={{ fontSize: 11, letterSpacing: '0.12em', color: col }}>MIETDAUER</div>
        <div className="mono" style={{ fontSize: 10, letterSpacing: '0.05em', color: col, opacity: 0.75, marginTop: 2 }}>
          {days === 1 ? '1 Tag' : days + ' Tage'}
        </div>
      </div>
      <span className="qty" onClick={e => e.stopPropagation()}>
        <button type="button" onClick={() => setDays(Math.max(1, days - 1))} aria-label="Weniger Tage">−</button>
        <span className="mono q bump" key={days}>{days}</span>
        <button type="button" onClick={() => setDays(Math.min(60, days + 1))} aria-label="Mehr Tage">+</button>
      </span>
    </div>
  );
}

// ---------- "Deine Liste" (Auswahl-Panel) ----------
function Panel({ groups, total, days, setDays, onQty, onRemove, onClear, onNext, onClose }) {
  return (
    <React.Fragment>
      <button type="button" className="panel-close" onClick={onClose} aria-label="Liste schließen">×</button>
      <div className="panel-head">
        <span className="display t">Deine Liste</span>
        <span className="mono n bump" key={total}>{total} {total === 1 ? 'POSITION' : 'POSITIONEN'}</span>
      </div>
      <div className="panel-body">
        {groups.length === 0 ? (
          <div className="panel-empty">
            <span className="mono">NOCH LEER</span>
            Klick dich rechts durch die Kategorien und leg per Klick auf deine Liste, was du brauchst. Mengen kannst du danach anpassen.
          </div>
        ) : groups.map(g => (
          <div key={g.category} className="sel-group">
            <div className="mono sel-cat">{g.category}</div>
            {g.items.map(({ item, qty }) => (
              <div key={item._key} className="sel-row">
                <QtyStepper qty={qty} onMinus={() => onQty(item, qty - 1)} onPlus={() => onQty(item, qty + 1)} />
                <div className="sel-name">
                  {item.name}
                  {parsePrice(item.price) > 0
                    ? <span className="mono sel-art" style={{ color: 'var(--neon)' }}> · {formatEuro(parsePrice(item.price) * qty)}</span>
                    : (item.artNr ? <span className="mono sel-art"> · {item.artNr}</span> : null)}
                </div>
                <button type="button" className="sel-x" onClick={() => onRemove(item)} aria-label="Entfernen">×</button>
              </div>
            ))}
          </div>
        ))}
      </div>
      <div className="panel-foot">
        {groups.length > 0 && (() => {
          const { total: sum, perDay, unpriced } = priceStats(groups, days);
          return (
            <div>
              <DurationStepper days={days} setDays={setDays} />
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', paddingBottom: 10, marginBottom: 10, borderBottom: '1px solid var(--hair)' }}>
                <span className="mono" style={{ fontSize: 11, letterSpacing: '0.12em', color: 'var(--ink-soft)' }}>
                  RICHTWERT{days > 1 ? ' · ' + days + ' TAGE' : ''}
                </span>
                <span className="display" style={{ fontSize: 26, color: 'var(--paper)', lineHeight: 1 }}>{formatEuro(sum)}</span>
              </div>
              <p className="note">
                {days > 1
                  ? <React.Fragment>1. Tag voll, jeder weitere Tag zum halben Preis (Transport pro Tag). Tagespreis ab {formatEuro(perDay)}.</React.Fragment>
                  : 'Unverbindlicher Richtwert (Tagesmiete).'}
                {unpriced > 0 ? ' — ' + unpriced + ' Position' + (unpriced === 1 ? '' : 'en') + ' noch auf Anfrage.' : ''}
                {' '}Finales Angebot nach Verfügbarkeit &amp; Services.
              </p>
            </div>
          );
        })()}
        <button type="button" className="btn btn-fill" disabled={total === 0} onClick={onNext}>
          <span>Weiter</span><span className="arrow">→</span>
        </button>
        {total > 0 && (
          <button type="button" className="panel-clear" onClick={onClear}>
            Liste leeren
          </button>
        )}
      </div>
    </React.Fragment>
  );
}

// ---------- Schritt 2: Services ----------
function ServicesStep({ services, toggle, onBack, onNext }) {
  React.useEffect(() => { if (window.lucide) lucide.createIcons(); });
  return (
    <div className="services-wrap" data-screen-label="Katalog Schritt 2 — Services">
      <h1 className="display">Brauchst du<br/>Hände dazu?</h1>
      <p className="lead">
        Material ist die halbe Miete. Wähl aus, wobei wir dich unterstützen sollen — oder geh einfach weiter, wenn du alles selbst machst.
      </p>
      <div className="svc-grid">
        {SERVICES.map(s => {
          const on = services.includes(s.id);
          return (
            <button type="button" key={s.id} className={'svc' + (on ? ' on' : '')} onClick={() => toggle(s.id)}>
              <span className="tick" aria-hidden="true">✓</span>
              <i data-lucide={s.icon}></i>
              <span className="display svc-name">{s.name}</span>
              <p className="svc-desc">{s.desc}</p>
            </button>
          );
        })}
      </div>
      <div className="step-nav">
        <button type="button" className="btn btn-ghost" onClick={onBack}><span>←</span><span>Zurück zur Technik</span></button>
        <button type="button" className="btn btn-fill" onClick={onNext}>
          <span>{services.length > 0 ? 'Weiter zur Anfrage' : 'Ohne Services weiter'}</span><span className="arrow">→</span>
        </button>
      </div>
    </div>
  );
}

// ---------- Anfrage-Text (für Mail + Zwischenablage) ----------
function buildRequestText(groups, services, form, days) {
  const d = Math.max(1, days || 1);
  const lines = ['Hallo NF-Audio,', '', 'ich möchte folgendes Material anfragen:'];
  lines.push('', 'Mietdauer: ' + d + (d === 1 ? ' Tag' : ' Tage'));
  for (const g of groups) {
    lines.push('', '— ' + g.category.toUpperCase() + ' —');
    for (const { item, qty } of g.items) {
      const v = parsePrice(item.price);
      const priceStr = v > 0 ? '  — ' + formatEuro(itemTotal(item, qty, d)) : '';
      lines.push(qty + '× ' + item.name + (item.artNr ? ' (Art. ' + item.artNr + ')' : '') + priceStr);
    }
  }
  const svcNames = SERVICES.filter(s => services.includes(s.id)).map(s => s.name);
  if (svcNames.length) {
    lines.push('', '— DAZU GEWÜNSCHT —');
    svcNames.forEach(n => lines.push('· ' + n));
  }
  if (form.date || form.location) {
    lines.push('', '— EVENT —');
    if (form.date) lines.push('Datum / Zeitraum: ' + form.date);
    if (form.location) lines.push('Ort / Location: ' + form.location);
  }
  if (form.message) lines.push('', 'Nachricht:', form.message);
  const { total: sum, perDay, unpriced } = priceStats(groups, d);
  if (sum > 0) {
    lines.push('', 'Richtwert für ' + d + (d === 1 ? ' Tag' : ' Tage') + ' (unverbindlich): ca. ' + formatEuro(sum)
      + (d > 1 ? ' (1. Tag voll, Folgetage halber Preis; Transport pro Tag — Tagespreis ' + formatEuro(perDay) + ')' : '')
      + (unpriced > 0 ? ' — zzgl. ' + unpriced + ' Position(en) auf Anfrage' : ''));
  }
  lines.push('', 'Kontakt:', form.name, form.email);
  if (form.phone) lines.push(form.phone);
  return lines.join('\n');
}

// ---------- Schritt 3: Formular + Zusammenfassung ----------
function FormStep({ groups, services, total, days, setDays, form, setForm, goStep, onSend, sent, copied, onCopy, onReset }) {
  const svcNames = SERVICES.filter(s => services.includes(s.id)).map(s => s.name);
  const fields = [
    { name: 'name',     label: 'Dein Name',          type: 'text',  span: 1, required: true },
    { name: 'email',    label: 'E-Mail',             type: 'email', span: 1, required: true },
    { name: 'phone',    label: 'Telefon',            type: 'tel',   span: 1 },
    { name: 'date',     label: 'Datum / Zeitraum',   type: 'text',  span: 1, placeholder: 'z. B. 14.–16. Aug. 2026' },
    { name: 'location', label: 'Ort / Location',     type: 'text',  span: 2, placeholder: 'z. B. Festhalle Ockenheim' },
    { name: 'message',  label: 'Noch was Wichtiges?', type: 'textarea', span: 2, placeholder: 'Anlass, Gäste, Fragen …' },
  ];
  return (
    <div className="form-stage" data-screen-label="Katalog Schritt 3 — Anfrage">
      <div className="form-grid">
        <div>
          <button type="button" className="btn btn-noir form-back" onClick={() => goStep(2)} style={{ padding: '11px 16px' }}>
            <span>←</span><span>Zurück</span>
          </button>
          <h1 className="display">Fast<br/>geschafft.</h1>
          <div className="summary">
            <div className="summary-head">
              <span className="display t">Deine Anfrage</span>
              <button type="button" className="mono edit" onClick={() => goStep(1)}>Ändern</button>
            </div>
            <div className="summary-body">
              {groups.map(g => (
                <div key={g.category}>
                  <div className="mono summary-cat">{g.category}</div>
                  {g.items.map(({ item, qty }) => (
                    <div key={item._key} className="summary-row">
                      <span className="q">{qty}×</span>
                      <span style={{ flex: 1 }}>{item.name}{item.artNr ? ' · ' + item.artNr : ''}</span>
                      {parsePrice(item.price) > 0 ? <span className="mono" style={{ color: 'var(--neon)' }}>{formatEuro(itemTotal(item, qty, days))}</span> : null}
                    </div>
                  ))}
                </div>
              ))}
              {svcNames.length > 0 && (
                <div>
                  <div className="mono summary-cat">Services</div>
                  {svcNames.map(n => <div key={n} className="summary-svc">· {n}</div>)}
                </div>
              )}
            </div>
            {(() => {
              const { total: sum, perDay, unpriced } = priceStats(groups, days);
              return (
                <div className="summary-foot">
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10, paddingBottom: 10, borderBottom: '1px solid rgba(10,10,10,0.12)' }}>
                    <span className="mono" style={{ fontSize: 11, letterSpacing: '0.12em', color: 'rgba(10,10,10,0.55)' }}>MIETDAUER</span>
                    <span className="qty qty-light">
                      <button type="button" onClick={() => setDays(Math.max(1, days - 1))} aria-label="Weniger Tage">−</button>
                      <span className="mono q bump" key={days}>{days}</span>
                      <button type="button" onClick={() => setDays(Math.min(60, days + 1))} aria-label="Mehr Tage">+</button>
                    </span>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 6 }}>
                    <span className="mono" style={{ fontSize: 11, letterSpacing: '0.12em', color: 'rgba(10,10,10,0.55)' }}>RICHTWERT · {days === 1 ? '1 TAG' : days + ' TAGE'}</span>
                    <span className="display" style={{ fontSize: 24, color: 'var(--noir)' }}>{formatEuro(sum)}</span>
                  </div>
                  <div className="mono" style={{ fontSize: 10.5, letterSpacing: '0.06em', color: 'rgba(10,10,10,0.5)', lineHeight: 1.5 }}>
                    {total} {total === 1 ? 'POSITION' : 'POSITIONEN'}{unpriced > 0 ? ' · ' + unpriced + ' AUF ANFRAGE' : ''}
                    {days > 1 ? ' · 1. TAG VOLL, FOLGETAGE ½ (TRANSPORT PRO TAG) · TAGESPREIS ' + formatEuro(perDay) : ''} · UNVERBINDLICH, OHNE SERVICES
                  </div>
                </div>
              );
            })()}
          </div>
        </div>

        <div>
          {sent ? (
            <div className="sent-box">
              <div className="display big">Danke!</div>
              <p>
                Dein E-Mail-Programm sollte sich geöffnet haben — einfach absenden, fertig.
                Wir prüfen deine Liste und melden uns innerhalb von 48 h mit einem Angebot.
              </p>
              <p style={{ fontSize: 14, color: 'rgba(10,10,10,0.6)' }}>
                Kein Mail-Programm aufgegangen? Kopier dir die Anfrage und schick sie an info@nf-audio.de.
              </p>
              <div className="sent-actions">
                <button type="button" className="btn btn-noir" onClick={onCopy}>
                  <span>{copied ? 'Kopiert ✓' : 'Anfrage kopieren'}</span>
                </button>
                <a className="btn btn-noir" href="index.html"><span>Zur Website</span><span className="arrow">→</span></a>
                <button type="button" className="btn btn-noir" onClick={onReset}><span>Neue Liste starten</span></button>
              </div>
            </div>
          ) : (
            <form className="f-form" onSubmit={onSend}>
              {fields.map(f => (
                <label key={f.name} className={'f-cell' + (f.span === 2 ? ' f-span2' : '')}>
                  <span className="lbl">{f.label}{f.required && <span className="req"> *</span>}</span>
                  {f.type === 'textarea' ? (
                    <textarea
                      rows={3}
                      value={form[f.name]}
                      placeholder={f.placeholder}
                      onChange={e => setForm({ ...form, [f.name]: e.target.value })}
                    ></textarea>
                  ) : (
                    <input
                      type={f.type}
                      required={f.required}
                      value={form[f.name]}
                      placeholder={f.placeholder}
                      onChange={e => setForm({ ...form, [f.name]: e.target.value })}
                    />
                  )}
                </label>
              ))}
              <div className="f-submit">
                <p>Deine Liste geht als E-Mail an <strong>info@nf-audio.de</strong> — wir prüfen alles und melden uns mit einem Angebot. Kein Spam.</p>
                <button type="submit" className="btn btn-fill">
                  <span>Anfrage senden</span><span className="arrow">→</span>
                </button>
              </div>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { SERVICES, QtyStepper, ItemThumb, ItemRow, ItemModal, Panel, ServicesStep, FormStep, IntroTour, buildRequestText });
