// ============================
// LELUSA — Mobile Kit (primitives)
// src/components/mobile-kit.jsx
// ============================
const { haptic } = window.LelusaGestures;

// ─── Skeleton (shimmer placeholder) ─────────────────────────────
function Skeleton({ width = '100%', height = 16, radius = 8, style = {} }) {
  return (
    <div className="lel-skeleton" style={{ width, height, borderRadius: radius, ...style }} />
  );
}

function SkeletonCard() {
  return (
    <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: 'var(--radius-card, 24px)', overflow: 'hidden' }}>
      <Skeleton height={180} radius={0} />
      <div style={{ padding: '16px' }}>
        <Skeleton height={18} width="70%" style={{ marginBottom: '10px' }} />
        <Skeleton height={13} width="90%" style={{ marginBottom: '8px' }} />
        <Skeleton height={13} width="50%" />
      </div>
    </div>
  );
}

// ─── PressableCard (tactile press feedback) ─────────────────────
function PressableCard({ children, onClick, hapticMs = 0, style = {}, className = '' }) {
  const [pressed, setPressed] = React.useState(false);
  const handle = () => { if (onClick) onClick(); };
  return (
    <div
      className={className}
      onClick={handle}
      onTouchStart={() => { setPressed(true); if (hapticMs) haptic(hapticMs); }}
      onTouchEnd={() => setPressed(false)}
      onTouchCancel={() => setPressed(false)}
      style={{
        cursor: onClick ? 'pointer' : 'default',
        transition: 'transform 0.12s ease, box-shadow 0.12s ease',
        transform: pressed ? 'scale(0.97)' : 'scale(1)',
        boxShadow: pressed ? '0 2px 10px rgba(58,42,32,0.10)' : 'none',
        ...style,
      }}
    >
      {children}
    </div>
  );
}

// ─── BottomSheet (drag-to-dismiss) ──────────────────────────────
function BottomSheet({ open, onClose, title, children }) {
  const { useBottomSheet } = window.LelusaGestures;
  const { sheetRef, dragY, dragging, handleProps } = useBottomSheet({ onClose });
  const [mounted, setMounted] = React.useState(open);

  React.useEffect(() => {
    if (open) setMounted(true);
    else { const t = setTimeout(() => setMounted(false), 280); return () => clearTimeout(t); }
  }, [open]);

  React.useEffect(() => {
    if (open) { document.body.style.overflow = 'hidden'; }
    else { document.body.style.overflow = ''; }
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  if (!mounted) return null;

  return (
    <div className="lel-sheet-root" style={{ position: 'fixed', inset: 0, zIndex: 1000 }}>
      <div
        onClick={onClose}
        style={{ position: 'absolute', inset: 0, background: 'rgba(58,42,32,0.45)',
          opacity: open ? 1 : 0, transition: 'opacity 0.28s ease' }}
      />
      <div
        ref={sheetRef}
        style={{
          position: 'absolute', left: 0, right: 0, bottom: 0,
          background: 'var(--card)', borderTopLeftRadius: '24px', borderTopRightRadius: '24px',
          maxHeight: '88vh', overflowY: 'auto', boxShadow: '0 -10px 40px rgba(58,42,32,0.18)',
          paddingBottom: 'calc(20px + env(safe-area-inset-bottom))',
          transform: open ? `translateY(${dragY}px)` : 'translateY(100%)',
          transition: dragging ? 'none' : 'transform 0.28s cubic-bezier(.22,.61,.36,1)',
        }}
      >
        <div {...handleProps} style={{ padding: '12px 0 4px', cursor: 'grab', touchAction: 'none' }}>
          <div style={{ width: '40px', height: '4px', borderRadius: '999px', background: 'var(--border)', margin: '0 auto' }} />
        </div>
        {title && (
          <div style={{ padding: '8px 22px 14px', fontFamily: "'Cormorant Garamond', serif", fontSize: '22px', fontWeight: 600, color: 'var(--text)' }}>{title}</div>
        )}
        <div style={{ padding: '0 22px 8px' }}>{children}</div>
      </div>
    </div>
  );
}

// ─── SwipeGallery (swipe between images with dots) ──────────────
function SwipeGallery({ images, renderSlide, aspect = '4/3' }) {
  const { useSwipe, useReducedMotion, haptic } = window.LelusaGestures;
  const [index, setIndex] = React.useState(0);
  const [drag, setDrag] = React.useState(0);
  const reduced = useReducedMotion();
  const count = images.length;

  const go = (next) => {
    const clamped = Math.max(0, Math.min(count - 1, next));
    if (clamped !== index) haptic(8);
    setIndex(clamped);
  };

  const ref = useSwipe({
    enabled: count > 1,
    onMove: (dx) => setDrag(dx),
    onSwipeLeft: () => { setDrag(0); go(index + 1); },
    onSwipeRight: () => { setDrag(0); go(index - 1); },
  });

  if (count === 0) return null;

  return (
    <div style={{ position: 'relative', borderRadius: '28px', overflow: 'hidden', border: '1px solid var(--border)', background: 'var(--card)' }}>
      <div
        ref={ref}
        style={{
          display: 'flex', aspectRatio: aspect, touchAction: 'pan-y',
          transform: `translateX(calc(${-index * 100}% + ${drag}px))`,
          transition: drag ? 'none' : (reduced ? 'none' : 'transform 0.32s cubic-bezier(.22,.61,.36,1)'),
        }}
      >
        {images.map((img, i) => (
          <div key={i} style={{ flex: '0 0 100%', width: '100%' }}>{renderSlide(img, i)}</div>
        ))}
      </div>
      {count > 1 && (
        <div style={{ position: 'absolute', bottom: '12px', left: 0, right: 0, display: 'flex', justifyContent: 'center', gap: '6px' }}>
          {images.map((_, i) => (
            <div key={i} onClick={() => go(i)} style={{
              width: i === index ? '20px' : '7px', height: '7px', borderRadius: '999px',
              background: i === index ? 'var(--primary)' : 'rgba(255,255,255,0.7)',
              transition: 'width 0.2s ease, background 0.2s ease', cursor: 'pointer',
            }} />
          ))}
        </div>
      )}
    </div>
  );
}
