/* Reusable scrapbook components (Polaroid, Tape, PhotoPlaceholder, etc).
   These render the same in both directions — direction differs in layout. */

const { useEffect, useRef, useState } = React;

// ── PhotoPlaceholder ────────────────────────────────────────
// Striped placeholder with monospace label. Pass `src` (image url) to swap in a real photo.
function PhotoPlaceholder({ label, w, h, src, video, banner, style }) {
  const baseStyle = { width: w, height: h, ...(style || {}) };
  const isVideo = video || (typeof src === 'string' && /\.(mp4|mov|webm)(\?|$)/i.test(src));
  const videoRef = useRef(null);
  const [muted, setMuted] = useState(true);
  if (src) {
    return (
      <div style={{ ...baseStyle, position: 'relative', overflow: 'hidden', background: '#cdbca0' }}>
        {isVideo ? (
          <>
            <video
              ref={videoRef}
              src={src}
              autoPlay
              loop
              muted={muted}
              playsInline
              preload="metadata"
              style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
            />
            {banner && (
              <div style={{
                position: 'absolute', left: 0, right: 0, top: 14,
                textAlign: 'center', pointerEvents: 'none',
                fontFamily: 'var(--hand)', fontSize: 26, lineHeight: 1.1,
                color: '#faf6ee',
                textShadow: '0 2px 10px rgba(0,0,0,0.55), 0 0 2px rgba(0,0,0,0.7)',
                letterSpacing: '0.01em',
                padding: '0 12px',
              }}>{banner}</div>
            )}
            <button
              type="button"
              onClick={(e) => {
                e.stopPropagation();
                const v = videoRef.current;
                if (muted) {
                  if (v) {
                    v.muted = false;
                    v.volume = 1;
                    const p = v.play();
                    if (p && p.catch) p.catch(() => {});
                  }
                  setMuted(false);
                  window.dispatchEvent(new CustomEvent('chapter-audio-pause'));
                } else {
                  if (v) v.muted = true;
                  setMuted(true);
                  window.dispatchEvent(new CustomEvent('chapter-audio-resume'));
                }
              }}
              aria-label={muted ? 'Unmute' : 'Mute'}
              style={{
                position: 'absolute', bottom: 8, right: 8,
                width: 32, height: 32, borderRadius: '50%',
                background: 'rgba(20,16,12,0.6)',
                border: 'none',
                color: '#faf6ee',
                fontSize: 14, lineHeight: 1,
                display: 'grid', placeItems: 'center',
                cursor: 'pointer',
              }}
            >{muted ? '🔇' : '🔊'}</button>
          </>
        ) : (
          <img src={src} alt={label || ''} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
        )}
      </div>
    );
  }
  return (
    <div className={`photo-ph${video ? ' video' : ''}`} style={baseStyle}>
      <span className="ph-label">[ {label} ]</span>
    </div>
  );
}

// ── Polaroid ────────────────────────────────────────────────
function Polaroid({ children, caption, rotate = 0, size, style, tape, tapeAt = 'tl' }) {
  const cls = `polaroid${size ? ' ' + size : ''}`;
  const tr = `rotate(${rotate}deg)`;
  return (
    <div className={cls} style={{ transform: tr, ...(style || {}) }}>
      {tape && <Tape at={tapeAt} />}
      {children}
      {caption && <div className="caption">{caption}</div>}
    </div>
  );
}

// ── Tape ────────────────────────────────────────────────────
// at: 'tl' | 'tr' | 'tc' | 'bl' | 'br' | 'bc' (corner placement)
function Tape({ at = 'tc', rotate, color, size = 'normal', style }) {
  const positions = {
    tl: { top: -10, left: 18, rotate: -28 },
    tc: { top: -10, left: '50%', translateX: '-50%', rotate: -3 },
    tr: { top: -10, right: 18, rotate: 30 },
    bl: { bottom: -10, left: 18, rotate: 28 },
    bc: { bottom: -10, left: '50%', translateX: '-50%', rotate: 4 },
    br: { bottom: -10, right: 18, rotate: -28 },
  };
  const p = positions[at] || positions.tc;
  const finalRotate = rotate ?? p.rotate;
  const tr = [
    p.translateX ? `translateX(${p.translateX})` : '',
    `rotate(${finalRotate}deg)`,
  ].filter(Boolean).join(' ');
  const cls = `tape${color === 'yellow' ? ' yellow' : ''}${size === 'thin' ? ' thin' : ''}${size === 'long' ? ' long' : ''}`;
  return (
    <div className={cls} style={{
      top:    p.top,
      left:   p.left,
      right:  p.right,
      bottom: p.bottom,
      transform: tr,
      ...(style || {}),
    }} />
  );
}

// ── Handwritten note ────────────────────────────────────────
function Note({ children, style, size = 22, color, rotate = 0, alt }) {
  return (
    <div
      className={`handwritten${alt ? ' alt' : ''}`}
      style={{
        fontSize: size,
        color: color || 'var(--ink)',
        transform: `rotate(${rotate}deg)`,
        ...(style || {}),
      }}
    >
      {children}
    </div>
  );
}

// ── Eyebrow / kicker ────────────────────────────────────────
function Eyebrow({ children, style }) {
  return <div className="eyebrow" style={style}>{children}</div>;
}

// ── Sticker (small handwritten doodle) ──────────────────────
function Sticker({ children, style, rotate = 0 }) {
  return (
    <div className="sticker" style={{ transform: `rotate(${rotate}deg)`, ...(style || {}) }}>
      {children}
    </div>
  );
}

// ── Hand-drawn arrow (svg) ──────────────────────────────────
function Arrow({ d = "M 6 30 C 30 6, 70 4, 110 28", color = 'var(--ink-soft)', width = 120, height = 60, style }) {
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={style}>
      <path d={d} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round"/>
      {/* arrowhead */}
      <path d={`M ${width-14} ${height/2 - 6} L ${width-4} ${height/2} L ${width-14} ${height/2 + 6}`}
            fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

// ── Reveal on scroll ────────────────────────────────────────
function Reveal({ children, delay = 0, rootRef, style, ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const root = (rootRef && rootRef.current) || null;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          setTimeout(() => setShown(true), delay);
          io.disconnect();
        }
      });
    }, { root, threshold: 0, rootMargin: '0px 0px -10% 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, [delay]);
  return (
    <div ref={ref} className={`reveal${shown ? ' in' : ''}`} style={style} {...rest}>
      {children}
    </div>
  );
}

// ── Stitched divider ────────────────────────────────────────
function Stitch({ style }) { return <div className="divider-stitch" style={style} />; }

// ── Ticket stub ─────────────────────────────────────────────
function Ticket({ children, rotate = -2, style }) {
  return (
    <div className="ticket" style={{ transform: `rotate(${rotate}deg)`, ...(style || {}) }}>
      {children}
    </div>
  );
}

// ── Audio chip (toggles a single shared <audio>) ────────────
function AudioChip({ src, label = 'play soundtrack' }) {
  const audioRef = useRef(null);
  const [playing, setPlaying] = useState(false);
  const [hasSrc] = useState(!!src);

  const toggle = () => {
    const a = audioRef.current;
    if (!a) return;
    if (playing) { a.pause(); setPlaying(false); }
    else {
      const p = a.play();
      if (p && p.then) p.then(() => setPlaying(true)).catch(() => setPlaying(false));
      else setPlaying(true);
    }
  };
  return (
    <div className={`audio-chip${playing ? ' playing' : ''}`} onClick={toggle} role="button" tabIndex={0}
         onKeyDown={(e) => (e.key === 'Enter' || e.key === ' ') && toggle()}>
      <span className="dot" />
      <span style={{ fontStyle: 'italic' }}>
        {hasSrc ? (playing ? 'now playing — our soundtrack' : label)
                : 'drop an .mp3 in /audio to enable'}
      </span>
      {hasSrc && <audio ref={audioRef} src={src} loop />}
    </div>
  );
}

Object.assign(window, {
  PhotoPlaceholder, Polaroid, Tape, Note, Eyebrow, Sticker, Arrow,
  Reveal, Stitch, Ticket, AudioChip,
});
