/* shell.jsx — Phone chrome, status bar, shared utility components, icons */
/* global React */

const { useState, useEffect, useRef, useMemo } = React;

// ════════════════════════════════════════════
// Number formatting — Norwegian (thin space thousands, comma decimal)
// ════════════════════════════════════════════
function fmtKr(n) {
  return Math.round(n).toLocaleString('no-NO').replace(/,/g, ' ');
}
function fmtPoeng(n) {
  return Math.round(n).toLocaleString('no-NO').replace(/,/g, ' ');
}

// ════════════════════════════════════════════
// Icons (Bulder-style: stroke based, rounded terminals, 1.5px)
// ════════════════════════════════════════════
const Icon = {
  bulderMark: (sz = 18) => (
    <svg width={sz} viewBox="0 0 62.22 46.665" fill="currentColor" fillRule="evenodd">
      <path d="M 31.11 0 L 0 31.11 L 0 46.665 L 38.899 7.777 L 46.665 15.555 L 31.11 31.11 L 46.665 31.11 L 62.22 15.555 L 46.665 0 L 31.11 0 Z M 46.665 31.11 L 31.11 46.665 L 46.665 46.665 L 62.22 31.11 L 46.665 31.11 Z"/>
    </svg>
  ),
  chevronRight: (sz = 20) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="9 6 15 12 9 18" />
    </svg>
  ),
  chevronLeft: (sz = 20) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="15 6 9 12 15 18" />
    </svg>
  ),
  arrowLeft: (sz = 20) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <line x1="19" y1="12" x2="5" y2="12" />
      <polyline points="12 19 5 12 12 5" />
    </svg>
  ),
  search: (sz = 20) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="11" cy="11" r="7" /><line x1="20" y1="20" x2="16.5" y2="16.5" />
    </svg>
  ),
  bell: (sz = 20) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M6 8a6 6 0 0 1 12 0c0 5 2 7 2 7H4s2-2 2-7" /><path d="M10 19a2 2 0 0 0 4 0" />
    </svg>
  ),
  check: (sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="5 12 10 17 19 7" />
    </svg>
  ),
  checkCircle: (sz = 80) => (
    <svg width={sz} height={sz} viewBox="0 0 64 64" fill="none">
      <circle cx="32" cy="32" r="30" fill="currentColor" opacity="0.12"/>
      <circle cx="32" cy="32" r="22" fill="currentColor"/>
      <path d="M20 32 L28 40 L44 24" stroke="#0F1729" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
    </svg>
  ),
  flame: (sz = 18) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="currentColor">
      <path d="M12 3c2 4-3 4-3 8a3 3 0 0 0 6 0c2 1 3 4 0 7-1.5 1.5-4 2-6 1-3-1.5-4-5-2-9 1-2 3-4 5-7z"/>
    </svg>
  ),
  plane: (sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="currentColor">
      <path d="M21 12l-7 2-3 6h-2l1-5-4-1-2 2H3l3-4-3-4h1l2 2 4-1-1-5h2l3 6 7 2z"/>
    </svg>
  ),
  coin: (sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="12" cy="12" r="9"/>
      <path d="M9 9.5c0-1.5 1.5-2 3-2s3 .8 3 2-1 1.5-3 2-3 1-3 2.5 1.5 2 3 2 3-.6 3-2"/>
      <line x1="12" y1="5" x2="12" y2="7"/>
      <line x1="12" y1="17" x2="12" y2="19"/>
    </svg>
  ),
  heart: (sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="currentColor">
      <path d="M12 21s-7-4.5-9-9c-1.5-3.4 1-7 4.5-7 2 0 3.5 1 4.5 2.5C13 6 14.5 5 16.5 5 20 5 22.5 8.6 21 12c-2 4.5-9 9-9 9z"/>
    </svg>
  ),
  partner: (sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M9 18V8a3 3 0 0 1 3-3h0a3 3 0 0 1 3 3v10"/>
      <circle cx="6" cy="18" r="3" fill="currentColor"/>
      <circle cx="18" cy="14" r="3" fill="currentColor"/>
    </svg>
  ),
  home: (active, sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill={active ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round">
      <path d="M3 11 L12 3 L21 11 V20 a1 1 0 0 1 -1 1 H14 V14 H10 V21 H4 a1 1 0 0 1 -1 -1 Z"/>
    </svg>
  ),
  card: (active, sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill={active ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="6" width="18" height="13" rx="2"/>
      <line x1="3" y1="10" x2="21" y2="10" stroke={active ? '#0F1729' : 'currentColor'}/>
      <line x1="7" y1="15" x2="11" y2="15" stroke={active ? '#0F1729' : 'currentColor'}/>
    </svg>
  ),
  pay: (active, sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M16 6 L6 16"/><path d="M9 6 L16 6 L16 13"/>
    </svg>
  ),
  building: (active, sz = 22) => (
    <svg width={sz} height={sz} viewBox="0 0 24 24" fill={active ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round">
      <path d="M12 3 L3 10 L5 10 L5 21 L19 21 L19 10 L21 10 Z"/>
      <rect x="9" y="14" width="6" height="7" fill={active ? '#0F1729' : 'none'}/>
    </svg>
  ),
};

// ════════════════════════════════════════════
// Phone frame & status bar
// ════════════════════════════════════════════
function StatusBar() {
  return (
    <div className="statusbar">
      <span>9:41</span>
      <div className="statusbar-right">
        {/* signal */}
        <svg width="17" height="11" viewBox="0 0 17 11" fill="currentColor"><rect x="0" y="7" width="3" height="4" rx="0.5"/><rect x="4.5" y="5" width="3" height="6" rx="0.5"/><rect x="9" y="2.5" width="3" height="8.5" rx="0.5"/><rect x="13.5" y="0" width="3" height="11" rx="0.5"/></svg>
        {/* wifi */}
        <svg width="15" height="11" viewBox="0 0 15 11" fill="currentColor"><path d="M7.5 0a14 14 0 0 1 7.5 2.5L13.4 4.4a11 11 0 0 0-11.8 0L0 2.5A14 14 0 0 1 7.5 0zm0 4a8 8 0 0 1 4.5 1.5l-1.6 1.9a5 5 0 0 0-5.8 0L3 5.5A8 8 0 0 1 7.5 4zm0 4a2.5 2.5 0 0 1 1.7.6L7.5 11 5.8 8.6A2.5 2.5 0 0 1 7.5 8z"/></svg>
        {/* battery */}
        <svg width="25" height="12" viewBox="0 0 25 12" fill="none"><rect x="0.5" y="0.5" width="21" height="11" rx="2.5" stroke="currentColor" opacity="0.4"/><rect x="2" y="2" width="18" height="8" rx="1.5" fill="currentColor"/><rect x="22" y="4" width="1.5" height="4" rx="0.5" fill="currentColor" opacity="0.4"/></svg>
      </div>
    </div>
  );
}

function Phone({ children }) {
  return (
    <div className="phone">
      <div className="phone-notch" />
      <StatusBar />
      <div className="screen">
        {children}
      </div>
    </div>
  );
}

// ════════════════════════════════════════════
// Presenter rail (researcher's screen navigator)
// ════════════════════════════════════════════
function PresenterRail({ screens, current, onJump }) {
  const groupBreaks = [4]; // after screen 4 (onboarding end)
  return (
    <div className="presenter">
      <div className="presenter-brand">
        <span className="presenter-brand-mark">{Icon.bulderMark(28)}</span>
        <div>
          <div className="presenter-brand-name">Bulder <span>Bonus</span></div>
          <div className="presenter-brand-tag">Konsepttest · prototype v1</div>
        </div>
      </div>

      <div className="presenter-rail" role="tablist" aria-label="Skjermer">
        {screens.map((s, i) => (
          <React.Fragment key={s.id}>
            {groupBreaks.includes(i) && <div className="rail-sep" />}
            <button
              className={`rail-dot${current === i ? ' active' : ''}`}
              onClick={() => onJump(i)}
              title={s.title}
              aria-label={`Skjerm ${i + 1}: ${s.title}`}
            >
              {String(i + 1).padStart(2, '0')}
            </button>
          </React.Fragment>
        ))}
      </div>

      <div className="presenter-meta">
        <div className="presenter-meta-num">
          {String(current + 1).padStart(2, '0')}
          <span> / {String(screens.length).padStart(2, '0')}</span>
        </div>
        <div className="presenter-meta-name">{screens[current].title}</div>
      </div>
    </div>
  );
}

// ════════════════════════════════════════════
// Bottom nav (5 tabs, Bulder app pattern)
// ════════════════════════════════════════════
function BottomNav({ active = 'hjem', onChange = () => {} }) {
  const tabs = [
    { k: 'hjem', label: 'Hjem', icon: (a) => Icon.home(a) },
    { k: 'spare', label: 'Spare', icon: (a) => Icon.coin(20) },
    { k: 'betale', label: 'Betale', icon: (a) => Icon.pay(a) },
    { k: 'bolig', label: 'Bolig', icon: (a) => Icon.building(a) },
    { k: 'bulder', label: 'Bulder', icon: (a) => <span style={{ color: a ? '#FE4D5B' : '#FAFBFF' }}>{Icon.bulderMark(22)}</span> },
  ];
  return (
    <div className="bottom-nav">
      {tabs.map(t => {
        const isActive = active === t.k;
        return (
          <button
            key={t.k}
            className={`tab-btn${isActive ? ' active' : ''}`}
            onClick={() => onChange(t.k)}
          >
            {t.icon(isActive)}
            <span className="tab-btn-lbl">{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

Object.assign(window, {
  fmtKr, fmtPoeng, Icon, Phone, StatusBar, PresenterRail, BottomNav,
});
