/* profile-ui.jsx — shared UI for the Profile feature (icons, Screen scaffold,
   Toggle, SettingsRow, Stat, reaction pills, SlideToConfirm). Exports to window. */

/* ============================================================
   Hand-drawn line icons (stroke = currentColor)
   ============================================================ */
function Ic({ d, size = 24, fill = 'none', sw = 2, vb = 24, children, style }) {
  return (
    <svg width={size} height={size} viewBox={`0 0 ${vb} ${vb}`} fill={fill} aria-hidden="true" style={style}
      stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
      {d ? <path d={d} /> : children}
    </svg>
  );
}
const IconGear = (p) => (
  <Ic {...p}><circle cx="12" cy="12" r="3.2" />
    <path d="M12 2.5c.5 0 .9.3 1 .8l.3 1.6c.6.2 1.1.5 1.6.8l1.5-.6c.5-.2 1 0 1.2.4l1 1.7c.2.4.1 1-.3 1.3l-1.3 1c.1.3.1.6.1 1s0 .7-.1 1l1.3 1c.4.3.5.9.3 1.3l-1 1.7c-.2.4-.7.6-1.2.4l-1.5-.6c-.5.3-1 .6-1.6.8l-.3 1.6c-.1.5-.5.8-1 .8h-2c-.5 0-.9-.3-1-.8l-.3-1.6a6 6 0 0 1-1.6-.8l-1.5.6c-.5.2-1 0-1.2-.4l-1-1.7c-.2-.4-.1-1 .3-1.3l1.3-1a6 6 0 0 1 0-2l-1.3-1c-.4-.3-.5-.9-.3-1.3l1-1.7c.2-.4.7-.6 1.2-.4l1.5.6c.5-.3 1-.6 1.6-.8l.3-1.6c.1-.5.5-.8 1-.8Z" /></Ic>
);
const IconBell = (p) => (
  <Ic {...p}><path d="M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6Z" /><path d="M10 20a2 2 0 0 0 4 0" /></Ic>
);
const IconShield = (p) => (
  <Ic {...p}><path d="M12 3l7 3v5c0 5-3 8-7 10-4-2-7-5-7-10V6l7-3Z" /><path d="M9 12l2 2 4-4" /></Ic>
);
const IconDoc = (p) => (
  <Ic {...p}><path d="M7 3h7l4 4v14H7V3Z" /><path d="M14 3v4h4M9 12h7M9 16h7M9 8h2" /></Ic>
);
const IconPencil = (p) => (
  <Ic {...p}><path d="M4 20l1-4L16 5l3 3L8 19l-4 1Z" /><path d="M14 7l3 3" /></Ic>
);
const IconMoon = (p) => (
  <Ic {...p}><path d="M20 14a8 8 0 1 1-9-11 6.5 6.5 0 0 0 9 11Z" /></Ic>
);
const IconLogout = (p) => (
  <Ic {...p}><path d="M14 4H6v16h8M10 12h10M17 8l4 4-4 4" /></Ic>
);
const IconTrash = (p) => (
  <Ic {...p}><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13M10 11v6M14 11v6" /></Ic>
);
const IconShare = (p) => (
  <Ic {...p}><circle cx="6" cy="12" r="2.4" /><circle cx="17" cy="6" r="2.4" /><circle cx="17" cy="18" r="2.4" /><path d="M8 11l7-4M8 13l7 4" /></Ic>
);
const IconChevron = (p) => <Ic {...p}><path d="M9 5l7 7-7 7" /></Ic>;
const IconGrid = (p) => (
  <Ic {...p}><path d="M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z" /></Ic>
);
const IconHeart = (p) => (
  <Ic {...p}><path d="M12 20s-7-4.3-9-9C1.5 7 4 4 7 4c2 0 3.3 1.4 5 3 1.7-1.6 3-3 5-3 3 0 5.5 3 4 7-2 4.7-9 9-9 9Z" /></Ic>
);

/* reaction glyphs */
const IconSip = (p) => ( // coffee cup
  <Ic {...p}><path d="M5 9h11v5a4 4 0 0 1-4 4H9a4 4 0 0 1-4-4V9Z" /><path d="M16 10c3-.6 4 .8 3.3 2.4C18.6 14 17 14 16 13.6" /><path d="M8 4c-.6 1 .6 1.6 0 2.6M12 4c-.6 1 .6 1.6 0 2.6" /></Ic>
);
const IconSplash = (p) => ( // repost arrows
  <Ic {...p}><path d="M4 9l3-3 3 3" /><path d="M7 6v8a2 2 0 0 0 2 2h7" /><path d="M20 15l-3 3-3-3" /><path d="M17 18v-8a2 2 0 0 0-2-2H8" /></Ic>
);
const IconTake = (p) => ( // speech bubble
  <Ic {...p}><path d="M4 5h16v11H9l-4 4v-4H4V5Z" /><path d="M8 9h8M8 12h5" /></Ic>
);
const IconWhisper = (p) => ( // envelope
  <Ic {...p}><path d="M3 6h18v12H3V6Z" /><path d="M3 7l9 6 9-6" /></Ic>
);
const IconCamera = (p) => ( // camera
  <Ic {...p}><path d="M4 8h3l1.5-2.5h7L17 8h3v11H4V8Z" /><circle cx="12" cy="13" r="3.6" /></Ic>
);
const IconX = (p) => <Ic {...p}><path d="M5 5l14 14M19 5L5 19" /></Ic>;

/* ============================================================
   Screen scaffold (header / scroll body / footer)
   ============================================================ */
function Screen({ title, onBack, headerRight, children, footer, padX = 20, bodyRef, headerLeft }) {
  return (
    <div className="pscreen">
      <div style={{ flex: '0 0 auto', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, padding: `54px ${padX - 4}px 8px` }}>
        <div style={{ minWidth: 52, display: 'flex', justifyContent: 'flex-start' }}>
          {onBack ? <BackButton onClick={onBack} /> : (headerLeft || <span />)}
        </div>
        {title != null && <div className="font-head" style={{ fontWeight: 700, fontSize: 22, textAlign: 'center', flex: 1, ...tilt(-1) }}>{title}</div>}
        <div style={{ minWidth: 52, display: 'flex', justifyContent: 'flex-end' }}>{headerRight || <span />}</div>
      </div>
      <div ref={bodyRef} className="scroll-area page-in" style={{ flex: '1 1 auto', minHeight: 0, padding: `6px ${padX}px 22px` }}>
        {children}
      </div>
      {footer && <div style={{ flex: '0 0 auto', padding: `10px ${padX}px 30px` }}>{footer}</div>}
    </div>
  );
}

/* round icon button (header actions) */
function IconBtn({ onClick, label, children, tiltDeg = -3 }) {
  return (
    <button onClick={onClick} aria-label={label} className="font-body" style={{
      width: 46, height: 46, ...wobbly.sm, ...tilt(tiltDeg),
      border: '2px solid var(--ink)', background: 'var(--surface)', color: 'var(--ink)',
      boxShadow: 'var(--sh-soft)', display: 'flex', alignItems: 'center', justifyContent: 'center',
      cursor: 'pointer', WebkitTapHighlightColor: 'transparent',
    }}>{children}</button>
  );
}

/* ============================================================
   Toggle switch
   ============================================================ */
function Toggle({ checked, onChange, label }) {
  return (
    <button role="switch" aria-checked={checked} aria-label={label} className="sw"
      onClick={() => onChange(!checked)}>
      <span className="sw__knob" />
    </button>
  );
}

/* ============================================================
   Settings row
   ============================================================ */
function SettingsRow({ icon, iconBg, title, sub, detail, right, onClick, danger, last, chevron = true }) {
  const clickable = !!onClick && !right;
  return (
    <div className={`srow ${onClick ? '' : 'srow--static'}`} role={clickable ? 'button' : undefined}
      tabIndex={clickable ? 0 : undefined}
      onClick={onClick} onKeyDown={(e) => clickable && (e.key === 'Enter') && onClick()}
      style={last ? { borderBottom: 'none' } : undefined}>
      {icon && <span className="srow__ic" style={{ background: iconBg || 'var(--postit)', color: danger ? 'var(--accent)' : 'var(--ink)', ...tilt(-2) }}>{icon}</span>}
      <span className="srow__txt">
        <span style={{ color: danger ? 'var(--accent)' : 'var(--ink)' }}>{title}</span>
        {sub && <span className="srow__sub" style={{ display: 'block' }}>{sub}</span>}
      </span>
      {detail && <span className="srow__detail">{detail}</span>}
      {right}
      {!right && chevron && onClick && <IconChevron size={18} style={{ color: 'var(--ink-muted)', flex: '0 0 auto' }} />}
    </div>
  );
}

/* ============================================================
   Reaction pill + inline stat
   ============================================================ */
function ReactionPill({ icon, n, on, onClick }) {
  return (
    <button className={`rpill ${on ? 'rpill--on' : ''}`} onClick={onClick}>
      {icon}<span>{fmtN(n)}</span>
    </button>
  );
}

/* ============================================================
   Slide-to-confirm (delete)
   ============================================================ */
function SlideToConfirm({ label = 'slide to delete', onConfirm }) {
  const trackRef = React.useRef(null);
  const [x, setX] = React.useState(0);
  const xRef = React.useRef(0);
  const [done, setDone] = React.useState(false);
  const drag = React.useRef(false);
  const maxRef = React.useRef(0);

  const setPos = (v) => { xRef.current = v; setX(v); };
  const measure = () => {
    const t = trackRef.current; if (!t) return 0;
    maxRef.current = t.offsetWidth - 56 - 6; return maxRef.current;
  };
  const onDown = (e) => { if (done) return; drag.current = true; measure(); try { e.currentTarget.setPointerCapture(e.pointerId); } catch (err) {} };
  const onMove = (e) => {
    if (!drag.current) return;
    const t = trackRef.current; const rect = t.getBoundingClientRect();
    let nx = e.clientX - rect.left - 30;
    nx = Math.max(0, Math.min(maxRef.current, nx));
    setPos(nx);
  };
  const finish = () => {
    if (!drag.current) return; drag.current = false;
    if (xRef.current >= maxRef.current - 8) { setPos(maxRef.current); setDone(true); setTimeout(onConfirm, 240); }
    else setPos(0);
  };
  const pct = maxRef.current ? x / maxRef.current : 0;

  return (
    <div ref={trackRef} className={`s2c ${done ? 's2c--done' : ''}`}>
      <div className="s2c__fill" style={{ transform: `scaleX(${0.12 + pct * 0.88})` }} />
      <div className="s2c__label" style={{ opacity: 1 - pct * 0.9 }}>
        <IconChevron size={16} /><IconChevron size={16} style={{ marginLeft: -22, opacity: .6 }} />{label}
      </div>
      <div className="s2c__knob" onPointerDown={onDown} onPointerMove={onMove} onPointerUp={finish} onPointerCancel={finish}
        style={{ left: 4 + x, transition: drag.current ? 'none' : 'left .2s ease' }}>
        {done ? <Ic size={24} style={{ color: 'var(--on-accent)' }}><path d="M4 12l5 5 11-11" /></Ic>
              : <IconTrash size={24} style={{ color: 'var(--on-accent)' }} />}
      </div>
    </div>
  );
}

Object.assign(window, {
  Ic, IconGear, IconBell, IconShield, IconDoc, IconPencil, IconMoon, IconLogout, IconTrash,
  IconShare, IconChevron, IconGrid, IconHeart, IconSip, IconSplash, IconTake, IconWhisper, IconCamera, IconX,
  Screen, IconBtn, Toggle, SettingsRow, ReactionPill, SlideToConfirm,
});
