// ---------- Behandlung carousel ----------
// 1:1 Pendant zu course-carousel.jsx, aber für Behandlungen (1:1-Angebote).
// - Oben: Kategorie-Karten mit Hintergrundbild + Farbschema (drag-snap)
// - Unten: Pills für einzelne Behandlungen — klick öffnet WBBehandlungDetail
// Datenquellen: WB_BEHANDLUNG_CATEGORIES + WB_BEHANDLUNGEN (aus behandlung-data.jsx).

function bhHexToRgba(hex, a) {
  const h = String(hex).replace('#', '');
  const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
  return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${a})`;
}

const useBehandlungCarouselData = () => {
  const [version, setVersion] = React.useState(0);
  React.useEffect(() => {
    const onUpdate = () => setVersion((v) => v + 1);
    window.addEventListener('wb-behandlungen-updated', onUpdate);
    return () => window.removeEventListener('wb-behandlungen-updated', onUpdate);
  }, []);
  return React.useMemo(() => {
    const cats = window.WB_BEHANDLUNG_CATEGORIES || [];
    const items = window.WB_BEHANDLUNGEN || [];
    // Behandlungen können zu mehreren Kategorien gehören (cats: [id, id, ...]).
    // Für die Pill-Liste verwenden wir die primäre Kategorie (= cats[0]).
    const matchesCat = (b, catId) => Array.isArray(b.cats) ? b.cats.includes(catId) : b.cat === catId;
    const buckets = cats.map((cat) => ({ cat, list: items.filter((b) => matchesCat(b, cat.id)) }));
    const max = buckets.length ? Math.max(...buckets.map((b) => b.list.length)) : 0;
    const directItems = [];
    for (let i = 0; i < max; i++) {
      buckets.forEach(({ cat, list }) => {
        if (list[i]) directItems.push({ label: list[i].title, cat, item: list[i] });
      });
    }
    return { cats, items, directItems };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [version]);
};

const BehandlungCarousel = ({ onOpenInquiry }) => {
  const stageRef = React.useRef(null);
  const trackRef = React.useRef(null);
  const pillsRef = React.useRef(null);
  const [activeBubble, setActiveBubble] = React.useState(null);
  const [openItem, setOpenItem] = React.useState(null);
  const headRef = useReveal();
  const { cats: behandlungCategories, directItems } = useBehandlungCarouselData();

  const [geom, setGeom] = React.useState({ cardW: 240, gap: 18, stageW: 1200 });

  const N = behandlungCategories.length;
  const [index, setIndex] = React.useState(0);
  const [drag, setDrag] = React.useState(0);

  const dragRef = React.useRef({ active: false, startX: 0, startIndex: 0, moved: false });

  React.useEffect(() => {
    const measure = () => {
      const stage = stageRef.current;
      if (!stage) return;
      const card = stage.querySelector('.bhcrs-card');
      const cardW = card ? card.offsetWidth : 240;
      setGeom({ cardW, gap: 18, stageW: stage.clientWidth });
    };
    measure();
    window.addEventListener('resize', measure);
    return () => window.removeEventListener('resize', measure);
  }, []);

  // Externe Trigger zum Öffnen einer Behandlung (z.B. Weib-Detail-Modal):
  // hört auf 'wb-open-behandlung-by-id' und sucht die Behandlung global.
  React.useEffect(() => {
    const onOpenById = (e) => {
      const id = e?.detail?.id;
      if (!id) return;
      const b = (window.WB_BEHANDLUNGEN || []).find((x) => x.id === id);
      if (b) setOpenItem(b);
    };
    window.addEventListener('wb-open-behandlung-by-id', onOpenById);
    return () => window.removeEventListener('wb-open-behandlung-by-id', onOpenById);
  }, []);

  const step = geom.cardW + geom.gap;
  const SIDE_GUTTER = 56;
  const visibleW = geom.stageW;
  const visibleCount = Math.max(1, Math.floor((visibleW + geom.gap) / step));
  const maxIndex = Math.max(0, N - visibleCount);
  const clampIndex = (i) => Math.max(0, Math.min(maxIndex, i));
  const baseOffset = -index * step;

  const RUBBER = 0.35;
  const rubberize = (dx) => {
    if (dx > 0 && index <= 0) return dx * RUBBER;
    if (dx < 0 && index >= maxIndex) return dx * RUBBER;
    return dx;
  };

  const onPointerDown = (e) => {
    if (e.button !== undefined && e.button !== 0) return;
    const t = e.target;
    if (t && t.closest && t.closest('[data-side-arrow]')) return;
    dragRef.current = {
      active: true, startX: e.clientX, startIndex: index, moved: false,
      pointerId: e.pointerId, captured: false,
    };
  };
  const onPointerMove = (e) => {
    if (!dragRef.current.active) return;
    const dx = e.clientX - dragRef.current.startX;
    if (!dragRef.current.moved && Math.abs(dx) > 5) {
      dragRef.current.moved = true;
      if (!dragRef.current.captured) {
        try {
          e.currentTarget.setPointerCapture(e.pointerId);
          dragRef.current.captured = true;
        } catch (_) {}
      }
    }
    if (dragRef.current.moved) setDrag(rubberize(dx));
  };
  const onPointerUp = (e) => {
    if (!dragRef.current.active) return;
    const dx = e.clientX - dragRef.current.startX;
    dragRef.current.active = false;
    setDrag(0);
    const delta = Math.round(-dx / step);
    if (delta !== 0) setIndex(i => clampIndex(i + delta));
    if (dragRef.current.captured) {
      try { e.currentTarget.releasePointerCapture(e.pointerId); } catch (_) {}
    }
    if (dragRef.current.moved) {
      const swallow = (ev) => { ev.stopPropagation(); ev.preventDefault(); };
      e.currentTarget.addEventListener('click', swallow, { capture: true, once: true });
      setTimeout(() => { dragRef.current.moved = false; }, 0);
    }
  };

  React.useEffect(() => {
    setIndex(i => clampIndex(i));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [maxIndex]);

  const slots = behandlungCategories.map((cat, i) => ({ slot: i, cat }));
  const atStart = index <= 0;
  const atEnd = index >= maxIndex;

  const scrollPillsBy = (dir) => {
    const p = pillsRef.current;
    if (!p) return;
    p.scrollBy({ left: dir * Math.max(220, p.clientWidth * 0.6), behavior: 'smooth' });
  };

  const [pillBounds, setPillBounds] = React.useState({ atStart: true, atEnd: false });
  React.useEffect(() => {
    const p = pillsRef.current;
    if (!p) return;
    const update = () => {
      const max = p.scrollWidth - p.clientWidth;
      setPillBounds({
        atStart: p.scrollLeft <= 1,
        atEnd: p.scrollLeft >= max - 1,
      });
    };
    update();
    p.addEventListener('scroll', update, { passive: true });
    window.addEventListener('resize', update);
    return () => {
      p.removeEventListener('scroll', update);
      window.removeEventListener('resize', update);
    };
  }, []);

  return (
    <section id="behandlungen" style={{ padding: 'clamp(56px, 8vw, 96px) 0 clamp(40px, 6vw, 64px)' }}>
      <div className="container">
        <div ref={headRef} className="reveal" style={{
          marginBottom: 48, display: 'flex', alignItems: 'flex-end',
          justifyContent: 'space-between', gap: 24, flexWrap: 'wrap',
        }}>
          <div style={{ maxWidth: 720 }}>
            <div className="eyebrow" style={{ marginBottom: 16 }}>{window.wbText('behandlungen.eyebrow', 'Behandlungen')}</div>
            <h2 style={{
              fontSize: 'clamp(36px, 5vw, 56px)', lineHeight: 1.1, letterSpacing: '-0.015em',
              marginBottom: 20,
              fontVariationSettings: '"opsz" 96, "SOFT" 50, "WONK" 1',
            }}>
              {window.wbT('behandlungen.headline', 'Individuelle Behandlungen, ganz nach [deinen Bedürfnissen].')}
            </h2>
            <p className="lead" style={{ maxWidth: 600 }}>
              {window.wbText('behandlungen.lead', 'Persönliche Begleitung in unseren Räumen — von Osteopathie bis Eltern-Coaching. Termine direkt mit der jeweiligen Frau, ganz in deinem Tempo.')}
            </p>
          </div>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            <a href="Alle Behandlungen.html" className="btn btn-secondary" style={{
              textDecoration: 'none', whiteSpace: 'nowrap',
            }}>
              Alle Behandlungen <span style={{ fontSize: 17, marginLeft: 2 }}>→</span>
            </a>
            <button type="button" className="btn btn-secondary"
              onClick={() => onOpenInquiry && onOpenInquiry({ kind: 'general' })}
              style={{ whiteSpace: 'nowrap' }}>
              Allgemeine Anfrage <span style={{ fontSize: 17, marginLeft: 2 }}>→</span>
            </button>
          </div>
        </div>
      </div>

      {/* Subheading: Kategorien */}
      <div className="container" style={{ marginBottom: 18 }}>
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 12, flexWrap: 'wrap',
          color: 'var(--ink-70)',
        }}>
          <span className="eyebrow" style={{ color: 'var(--heather-plum)' }}>● Kategorien</span>
          <span style={{ fontSize: 14, color: 'var(--ink-50)' }}>
            Bereiche im Überblick — wisch durch oder klick eine Karte
          </span>
        </div>
      </div>

      {behandlungCategories.length === 0 ? (
        <div className="container">
          <div style={{
            background: 'var(--offwhite)',
            border: '1px dashed var(--sandstone-border)',
            borderRadius: 14,
            padding: 'clamp(28px, 4vw, 40px)',
            textAlign: 'center',
            color: 'var(--ink-70)',
            fontSize: 15, lineHeight: 1.6,
          }}>
            Aktuell sind keine Behandlungs-Kategorien angelegt. Sobald wir hier
            Behandlungen ausschreiben, tauchen sie als Karten auf.
          </div>
        </div>
      ) : (
      <>
      <div className="container" style={{ position: 'relative' }}>
        <BhArrow dir={-1} onClick={() => setIndex(i => clampIndex(i - 1))} gutter={SIDE_GUTTER} disabled={atStart} />
        <BhArrow dir={1} onClick={() => setIndex(i => clampIndex(i + 1))} gutter={SIDE_GUTTER} disabled={atEnd} />

        <div
          ref={stageRef}
          onPointerDown={onPointerDown}
          onPointerMove={onPointerMove}
          onPointerUp={onPointerUp}
          onPointerCancel={onPointerUp}
          style={{
            position: 'relative',
            overflow: 'hidden',
            padding: '4px 0 24px',
            touchAction: 'pan-y',
            cursor: dragRef.current.active ? 'grabbing' : 'grab',
            userSelect: 'none',
            WebkitUserSelect: 'none',
          }}
        >
          <div
            ref={trackRef}
            style={{
              display: 'flex', gap: geom.gap,
              paddingLeft: 0,
              paddingRight: 0,
              transform: `translate3d(${baseOffset + drag}px, 0, 0)`,
              transition: dragRef.current.active ? 'none' : 'transform 480ms cubic-bezier(0.2, 0.8, 0.2, 1)',
              willChange: 'transform',
            }}
          >
            {slots.map(({ slot, cat: c }) => (
              <a key={slot} className="bhcrs-card"
                href={`Alle Behandlungen.html#cat=${c.id}`}
                style={{
                  flex: '0 0 clamp(200px, 22vw, 260px)',
                  aspectRatio: '3/4',
                  borderRadius: 20,
                  background: c.tone.bg,
                  color: c.tone.text,
                  textDecoration: 'none',
                  position: 'relative',
                  overflow: 'hidden',
                  cursor: 'pointer',
                  boxShadow: '0 4px 14px rgba(42,34,29,0.08)',
                  transition: 'transform 240ms var(--ease)',
                  padding: '22px 22px 26px',
                  WebkitTapHighlightColor: 'transparent',
                }}
                onMouseEnter={(e) => e.currentTarget.style.transform = 'translateY(-4px)'}
                onMouseLeave={(e) => e.currentTarget.style.transform = 'translateY(0)'}
                onClick={(e) => {
                  if (dragRef.current.moved) {
                    e.preventDefault();
                    e.stopPropagation();
                  }
                }}
                onDragStart={(e) => e.preventDefault()}
              >
                <div aria-hidden="true" style={{
                  position: 'absolute', top: 0, left: 0, right: 0, height: '62%',
                  overflow: 'hidden',
                  pointerEvents: 'none',
                }}>
                  {c.imageUrl && (
                    <img
                      src={c.imageUrl}
                      alt=""
                      loading="lazy"
                      draggable={false}
                      style={{
                        width: '100%', height: '100%', objectFit: 'cover',
                        mixBlendMode: 'multiply',
                        opacity: 0.78,
                        filter: 'saturate(0.85)',
                      }}
                    />
                  )}
                  <div style={{
                    position: 'absolute', inset: 0,
                    background: c.tone.solid,
                    mixBlendMode: c.imageUrl ? 'color' : 'normal',
                    opacity: c.imageUrl ? 0.55 : 1,
                  }} />
                  <div style={{
                    position: 'absolute', left: 0, right: 0, bottom: -1, height: '60%',
                    background: `linear-gradient(180deg, ${bhHexToRgba(c.tone.solid, 0)} 0%, ${c.tone.solid} 92%)`,
                  }} />
                </div>

                {/* Eyebrow absolut → untere Block-Position fix → Headlines
                    aller Karten oben bündig, unabhängig von Beschreibungslänge. */}
                <div style={{
                  position: 'absolute', top: 22, left: 22, right: 22, zIndex: 2,
                  display: 'flex', justifyContent: 'space-between',
                  fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase',
                  opacity: 0.85, fontWeight: 600,
                }}>
                  <span>{c.eyebrow}</span>
                  <span>↗</span>
                </div>

                <div style={{
                  position: 'absolute', top: '62%', left: 22, right: 22, zIndex: 2,
                }}>
                  <h3 style={{
                    fontFamily: 'Fraunces, serif',
                    fontSize: 'clamp(20px, 2.1vw, 26px)',
                    lineHeight: 1.1, marginBottom: 10,
                    fontVariationSettings: '"opsz" 96, "SOFT" 40',
                    color: c.tone.text,
                  }}>{c.title}</h3>
                  <p style={{
                    fontSize: 13, lineHeight: 1.5,
                    opacity: 0.88, maxWidth: 220,
                    // Sicherheitsnetz: Altbestand mit zu langem Text → 3 Zeilen.
                    display: '-webkit-box',
                    WebkitLineClamp: 3,
                    WebkitBoxOrient: 'vertical',
                    overflow: 'hidden',
                  }}>{c.body}</p>
                </div>
              </a>
            ))}
          </div>
        </div>
      </div>

      {/* Subheading: Einzelne Behandlungen */}
      <div className="container" style={{ marginTop: 40, marginBottom: 14 }}>
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 12, flexWrap: 'wrap',
          color: 'var(--ink-70)',
        }}>
          <span className="eyebrow" style={{ color: 'var(--heather-plum)' }}>● Einzelne Behandlungen</span>
          <span style={{ fontSize: 14, color: 'var(--ink-50)' }}>
            Direkt zur Behandlung — tippe einen Eintrag für Details
          </span>
        </div>
      </div>

      {directItems.length === 0 ? (
        <div className="container">
          <div style={{
            background: 'var(--offwhite)',
            border: '1px dashed var(--sandstone-border)',
            borderRadius: 14,
            padding: 'clamp(20px, 3vw, 28px)',
            textAlign: 'center',
            color: 'var(--ink-70)',
            fontSize: 14, lineHeight: 1.6,
          }}>
            Aktuell sind keine einzelnen Behandlungen ausgeschrieben. Schau bald
            wieder vorbei — oder schreib uns direkt.
          </div>
        </div>
      ) : (
      <>
      <div className="container" style={{ position: 'relative' }}>
        <BhArrow dir={-1} onClick={() => scrollPillsBy(-1)} gutter={SIDE_GUTTER} small disabled={pillBounds.atStart} />
        <BhArrow dir={1} onClick={() => scrollPillsBy(1)} gutter={SIDE_GUTTER} small disabled={pillBounds.atEnd} />

        <div ref={pillsRef} className="bhcrs-pills" style={{
          display: 'flex', gap: 8,
          overflowX: 'auto', overflowY: 'hidden',
          padding: `8px ${SIDE_GUTTER}px`,
          scrollbarWidth: 'none',
          WebkitOverflowScrolling: 'touch',
          scrollSnapType: 'x proximity',
        }}>
          <style>{`.bhcrs-pills::-webkit-scrollbar{display:none}`}</style>
          {directItems.map(({ label, cat, item }, i) => {
            const active = activeBubble === label;
            return (
              <button key={`${cat.id}-${label}-${i}`} type="button"
                title={cat.title}
                onClick={() => { setActiveBubble(label); setOpenItem(item); }}
                style={{
                  fontSize: 12, fontWeight: 500,
                  padding: '7px 14px', borderRadius: 999,
                  background: active ? cat.tone.bg : cat.pill.bg,
                  color: active ? cat.tone.text : cat.pill.text,
                  border: '1px solid ' + (active ? 'transparent' : cat.pill.border),
                  cursor: 'pointer',
                  transition: 'all 160ms var(--ease)',
                  whiteSpace: 'nowrap',
                  flex: '0 0 auto',
                  fontFamily: 'inherit',
                  scrollSnapAlign: 'start',
                  display: 'inline-flex', alignItems: 'center', gap: 6,
                }}
              >
                <span style={{
                  width: 6, height: 6, borderRadius: 999,
                  background: cat.pill.text,
                  opacity: active ? 0.85 : 0.7,
                  flexShrink: 0,
                }} />
                {label}
              </button>
            );
          })}
        </div>
      </div>
      </>
      )}
      </>
      )}
      {(() => {
        const Detail = window.WBBehandlungDetail;
        return openItem && Detail ? (
          <Detail item={openItem} onClose={() => { setOpenItem(null); setActiveBubble(null); }} />
        ) : null;
      })()}
    </section>
  );
};

const BhArrow = ({ dir, onClick, gutter = 56, small, disabled }) => {
  const size = small ? 32 : 40;
  const offset = Math.max(8, (gutter - size) / 2);
  return (
    <button type="button" onClick={disabled ? undefined : onClick}
      data-side-arrow="true"
      disabled={disabled}
      aria-label={dir < 0 ? 'Vorherige' : 'Nächste'}
      aria-disabled={disabled || undefined}
      style={{
        position: 'absolute',
        top: '50%',
        [dir < 0 ? 'left' : 'right']: offset,
        transform: 'translateY(-50%)',
        zIndex: 5,
        width: size, height: size, borderRadius: 999,
        background: 'rgba(250, 246, 241, 0.9)',
        backdropFilter: 'blur(8px)',
        WebkitBackdropFilter: 'blur(8px)',
        border: '1px solid rgba(196, 169, 143, 0.5)',
        color: 'var(--ink)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        cursor: disabled ? 'not-allowed' : 'pointer',
        fontSize: small ? 13 : 15,
        boxShadow: disabled ? 'none' : '0 4px 12px rgba(42,34,29,0.10)',
        opacity: disabled ? 0.35 : 1,
        transition: 'all 160ms var(--ease)',
      }}
    >{dir < 0 ? '←' : '→'}</button>
  );
};

window.BehandlungCarousel = BehandlungCarousel;
