// shared.jsx — Bulder mortgage app shared components & tokens

const BB = {
  bg: '#0F1729',        // dark-blue-800
  surface: '#1A2037',   // dark-blue-700
  surface2: '#262F47',  // dark-blue-600
  surface3: '#333E5C',  // dark-blue-500
  line: 'rgba(255,255,255,0.08)',
  divider: 'rgba(255,255,255,0.06)',
  fg: '#FAFBFF',
  fg2: '#D1D7E5',
  fg3: '#9298A7',
  fg4: '#707C9E',
  pink: '#FE4D5B',      // brand red
  pinkSoft: '#FFA8AF',
  pinkDeep: '#BD2A37',
  royal: '#0926D6',
  green: '#85FF86',
  greenDeep: '#3AA53A',
  amber: '#FFAD33',
};

// ── Norwegian number formatting ──────────────────────────────
const nbsp = '\u00A0';
const fmtKr = (n) => {
  if (n == null || isNaN(n)) return '0';
  const s = Math.round(n).toString();
  let out = '';
  for (let i = 0; i < s.length; i++) {
    if (i > 0 && (s.length - i) % 3 === 0) out += nbsp;
    out += s[i];
  }
  return out;
};
const fmtPct = (n, d = 2) => n.toFixed(d).replace('.', ',');
// Annuity: monthly payment for principal P, annual nominal rate r (fraction), months m
const annuity = (P, r, months) => {
  if (!P || !months) return 0;
  const i = r / 12;
  if (i === 0) return P / months;
  return P * (i * Math.pow(1 + i, months)) / (Math.pow(1 + i, months) - 1);
};

// ── Small atoms ──────────────────────────────────────────────
function GlyphBack({ onClick, label = 'Tilbake' }) {
  return (
    <button onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      background: 'none', border: 'none', color: BB.fg2,
      fontSize: 15, cursor: 'pointer', padding: '8px 4px',
      fontFamily: 'Aeonik, Inter, system-ui',
    }}>
      <svg width="9" height="15" viewBox="0 0 9 15" fill="none">
        <path d="M7.5 1.5L1.5 7.5L7.5 13.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
      {label}
    </button>
  );
}

// Bulder staircase logo-mark (simplified from the Figma geometry)
function BulderMark({ size = 22, color = BB.pink }) {
  return (
    <svg width={size} height={size} viewBox="0 0 64 64" fill="none">
      <path fillRule="evenodd" clipRule="evenodd"
        d="M32.11 9L1 40.11V55.66L39.90 16.78L47.66 24.55L32.11 40.11H47.66L63.22 24.55L47.66 9H32.11ZM47.66 40.11L32.11 55.66H47.66L63.22 40.11H47.66Z"
        fill={color}/>
    </svg>
  );
}

// Progress rail across top (8 steps)
function ProgressRail({ current, total, labels }) {
  return (
    <div style={{ padding: '0 20px', marginTop: 4 }}>
      <div style={{ display: 'flex', gap: 4 }}>
        {Array.from({ length: total }).map((_, i) => {
          const done = i < current;
          const active = i === current;
          return (
            <div key={i} style={{
              flex: 1, height: 3, borderRadius: 999,
              background: done || active ? BB.pink : 'rgba(255,255,255,0.1)',
              opacity: done ? 0.5 : 1,
              transition: 'all 0.3s ease',
            }}/>
          );
        })}
      </div>
      <div style={{
        marginTop: 10, fontSize: 12, color: BB.fg3,
        letterSpacing: '0.02em', display: 'flex', justifyContent: 'space-between',
      }}>
        <span style={{ textTransform: 'uppercase', fontWeight: 700 }}>
          Steg {current + 1} av {total}
        </span>
        <span>{labels[current]}</span>
      </div>
    </div>
  );
}

// Input with label above, dark surface
function TextField({ label, value, onChange, suffix, prefix, hint, placeholder, inputMode = 'text', big = false, autoFocus, readOnly, success }) {
  const [focus, setFocus] = React.useState(false);
  return (
    <label style={{ display: 'block' }}>
      <div style={{
        fontSize: 13, color: BB.fg3, marginBottom: 6,
        textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 700,
      }}>{label}</div>
      <div style={{
        display: 'flex', alignItems: 'baseline', gap: 6,
        background: BB.surface, borderRadius: 10,
        padding: big ? '14px 16px' : '12px 14px',
        border: `1.5px solid ${focus ? BB.pink : 'transparent'}`,
        transition: 'border-color 0.15s ease',
      }}>
        {prefix && <span style={{ color: BB.fg3, fontSize: big ? 22 : 16 }}>{prefix}</span>}
        <input
          type="text"
          inputMode={inputMode}
          value={value}
          onChange={onChange}
          placeholder={placeholder}
          autoFocus={autoFocus}
          readOnly={readOnly}
          onFocus={() => setFocus(true)}
          onBlur={() => setFocus(false)}
          style={{
            flex: 1, background: 'transparent', border: 'none', outline: 'none',
            color: BB.fg, fontSize: big ? 26 : 17,
            fontWeight: big ? 500 : 500,
            fontFamily: 'Aeonik, Inter, system-ui',
            fontVariantNumeric: 'tabular-nums',
            minWidth: 0, padding: 0,
          }}
        />
        {suffix && <span style={{ color: BB.fg2, fontSize: big ? 20 : 15 }}>{suffix}</span>}
        {success && (
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" style={{ flexShrink: 0 }}>
            <circle cx="12" cy="12" r="10" fill={BB.green}/>
            <path d="M8 12l3 3 5-6" stroke="#0F1729" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        )}
      </div>
      {hint && <div style={{ fontSize: 12, color: BB.fg3, marginTop: 6, lineHeight: 1.4 }}>{hint}</div>}
    </label>
  );
}

// Slider with embedded value
function RangeSlider({ min, max, step = 1, value, onChange, suffix }) {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <div>
      <div style={{ position: 'relative', height: 32, display: 'flex', alignItems: 'center' }}>
        <div style={{ position: 'absolute', left: 0, right: 0, height: 4, borderRadius: 999, background: BB.surface2 }}/>
        <div style={{ position: 'absolute', left: 0, width: `${pct}%`, height: 4, borderRadius: 999, background: BB.pink }}/>
        <input
          type="range" min={min} max={max} step={step} value={value}
          onChange={e => onChange(Number(e.target.value))}
          style={{
            position: 'absolute', inset: 0, width: '100%', opacity: 0,
            cursor: 'pointer', margin: 0,
          }}
        />
        <div style={{
          position: 'absolute', left: `calc(${pct}% - 14px)`, top: 2,
          width: 28, height: 28, borderRadius: 999, background: '#fff',
          boxShadow: '0 2px 8px rgba(0,0,0,0.4), 0 0 0 3px rgba(254,77,91,0.2)',
          pointerEvents: 'none',
        }}/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 12, color: BB.fg3 }}>
        <span>{fmtKr(min)}{suffix}</span>
        <span>{fmtKr(max)}{suffix}</span>
      </div>
    </div>
  );
}

// Primary CTA
function PrimaryButton({ children, onClick, disabled, full = true, pending }) {
  return (
    <button onClick={onClick} disabled={disabled || pending} style={{
      display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      width: full ? '100%' : 'auto',
      padding: '16px 22px', borderRadius: 10,
      background: disabled ? BB.surface2 : BB.pink,
      color: disabled ? BB.fg3 : '#fff',
      border: 'none', fontSize: 18, fontWeight: 500,
      fontFamily: 'Aeonik, Inter, system-ui',
      cursor: disabled ? 'not-allowed' : 'pointer',
      transition: 'transform 0.12s ease, background 0.15s ease',
    }}
    onMouseDown={e => !disabled && (e.currentTarget.style.transform = 'scale(0.98)')}
    onMouseUp={e => (e.currentTarget.style.transform = 'scale(1)')}
    onMouseLeave={e => (e.currentTarget.style.transform = 'scale(1)')}
    >
      {pending && <Spinner/>}
      {children}
    </button>
  );
}

function SecondaryButton({ children, onClick, full = true }) {
  return (
    <button onClick={onClick} style={{
      width: full ? '100%' : 'auto',
      padding: '16px 22px', borderRadius: 10,
      background: 'transparent',
      color: BB.fg, border: `1.5px solid ${BB.surface3}`,
      fontSize: 17, fontWeight: 500,
      fontFamily: 'Aeonik, Inter, system-ui',
      cursor: 'pointer',
    }}>{children}</button>
  );
}

function Toggle({ on, onChange }) {
  return (
    <button
      onClick={() => onChange(!on)}
      style={{
        width: 46, height: 28, borderRadius: 999,
        background: on ? BB.pink : '#3A4050',
        border: 'none', padding: 0, cursor: 'pointer',
        position: 'relative', transition: 'background 0.18s ease',
        flexShrink: 0,
      }}
      aria-pressed={on}
    >
      <span style={{
        position: 'absolute', top: 3, left: on ? 21 : 3,
        width: 22, height: 22, borderRadius: 999, background: '#fff',
        transition: 'left 0.18s ease',
        boxShadow: '0 1px 2px rgba(0,0,0,0.2)',
      }}/>
    </button>
  );
}

function Spinner({ size = 18, color = '#fff' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ animation: 'bulderSpin 1s linear infinite' }}>
      <circle cx="12" cy="12" r="9" stroke={color} strokeOpacity="0.25" strokeWidth="3" fill="none"/>
      <path d="M21 12a9 9 0 0 0-9-9" stroke={color} strokeWidth="3" strokeLinecap="round" fill="none"/>
    </svg>
  );
}

// Card surface
function Card({ children, style = {}, padding = 18 }) {
  return (
    <div style={{
      background: BB.surface, borderRadius: 10,
      padding, ...style,
    }}>{children}</div>
  );
}

// Inline KV row
function KVRow({ label, value, strong, accent, border = true }) {
  return (
    <div style={{
      display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
      padding: '14px 0',
      borderBottom: border ? `1px solid ${BB.divider}` : 'none',
      gap: 12,
    }}>
      <span style={{ fontSize: 15, color: BB.fg2 }}>{label}</span>
      <span style={{
        fontSize: strong ? 17 : 15,
        fontWeight: strong ? 600 : 500,
        color: accent || BB.fg,
        fontVariantNumeric: 'tabular-nums',
        textAlign: 'right',
      }}>{value}</span>
    </div>
  );
}

// Chip
function Chip({ selected, children, onClick }) {
  return (
    <button onClick={onClick} style={{
      padding: '10px 14px', borderRadius: 10,
      background: selected ? BB.pink : BB.surface,
      color: selected ? '#fff' : BB.fg,
      border: `1.5px solid ${selected ? BB.pink : 'transparent'}`,
      fontSize: 15, fontWeight: 500,
      fontFamily: 'Aeonik, Inter, system-ui',
      cursor: 'pointer', transition: 'all 0.15s ease',
      whiteSpace: 'nowrap',
    }}>{children}</button>
  );
}

// Large rate display pill that sits under nav on most steps
function RateSummary({ amount, term, rate, monthly, compact = false, accent = BB.pink }) {
  return (
    <div style={{
      margin: '0 16px', borderRadius: 10, padding: compact ? 12 : 14,
      background: BB.surface, border: `1px solid ${BB.line}`,
      display: 'flex', alignItems: 'center', gap: 14,
    }}>
      <div style={{
        width: 38, height: 38, borderRadius: 999,
        background: 'rgba(254,77,91,0.12)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}>
        <BulderMark size={18} color={accent}/>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 11, color: BB.fg3, textTransform: 'uppercase', fontWeight: 700, letterSpacing: '0.05em' }}>Din estimerte rente</div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 2 }}>
          <span style={{ fontSize: 22, fontWeight: 500, color: BB.fg, fontVariantNumeric: 'tabular-nums' }}>{fmtPct(rate)} %</span>
          <span style={{ fontSize: 13, color: BB.fg3 }}>nom.</span>
        </div>
      </div>
      <div style={{ textAlign: 'right' }}>
        <div style={{ fontSize: 11, color: BB.fg3, textTransform: 'uppercase', fontWeight: 700, letterSpacing: '0.05em' }}>Pr. mnd</div>
        <div style={{ fontSize: 17, fontWeight: 500, color: BB.fg, marginTop: 2, fontVariantNumeric: 'tabular-nums' }}>
          {fmtKr(monthly)} <span style={{ fontSize: 13, color: BB.fg3 }}>kr</span>
        </div>
      </div>
    </div>
  );
}

// Status bar container — ensures the iOS chrome looks right
const STATUS_PAD = 56; // iOS status bar reservation
const RAIL_PAD = 44;   // extra space when progress rail is present

// ── global styles injected once ──────────────────────────────
function GlobalStyles() {
  return (
    <style>{`
      @keyframes bulderSpin { to { transform: rotate(360deg); } }
      @keyframes bulderFadeUp {
        from { opacity: 0; transform: translateY(8px); }
        to   { opacity: 1; transform: translateY(0); }
      }
      @keyframes bulderPulse {
        0%, 100% { transform: scale(1); opacity: 1; }
        50%      { transform: scale(1.05); opacity: 0.85; }
      }
      @keyframes bulderCheckDraw {
        from { stroke-dashoffset: 60; }
        to   { stroke-dashoffset: 0; }
      }
      @keyframes bulderRingDraw {
        from { stroke-dashoffset: 283; }
        to   { stroke-dashoffset: 0; }
      }
      @keyframes bulderShimmer {
        0% { background-position: -200% 0; }
        100% { background-position: 200% 0; }
      }
      @keyframes bulderSlideIn {
        from { opacity: 0; transform: translateY(20px); }
        to   { opacity: 1; transform: translateY(0); }
      }
      .bb-screen-enter { animation: bulderFadeUp 0.32s cubic-bezier(0.2, 0.8, 0.2, 1); }
      .bb-number-flash { animation: bulderSlideIn 0.26s ease-out; }
      .bb-shimmer {
        background: linear-gradient(90deg, #1A2037 0%, #262F47 50%, #1A2037 100%);
        background-size: 200% 100%;
        animation: bulderShimmer 1.4s infinite;
      }
      input::placeholder { color: rgba(146,152,167,0.5); }
    `}</style>
  );
}

Object.assign(window, {
  BB, nbsp, fmtKr, fmtPct, annuity,
  GlyphBack, BulderMark, ProgressRail, TextField, RangeSlider,
  PrimaryButton, SecondaryButton, Spinner, Toggle, Card, KVRow, Chip,
  RateSummary, GlobalStyles, STATUS_PAD, RAIL_PAD,
});
