// Shared small components for FSA Credit
const { useState, useEffect, useRef, useCallback, useMemo } = React;

// USD formatter
const fmt = (n, opts = {}) => {
  if (n === null || n === undefined || isNaN(n)) return '—';
  const rounded = Math.round(n);
  return rounded.toLocaleString('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
    ...opts,
  });
};
const fmtPct = (n) => `${Math.round(n * 100)}%`;

// Segmented control
function Segmented({ value, onChange, options }) {
  return (
    <div className="seg" role="radiogroup">
      {options.map((o) => (
        <button
          key={o.value}
          type="button"
          role="radio"
          aria-checked={value === o.value}
          className={value === o.value ? 'active' : ''}
          onClick={() => onChange(o.value)}
        >
          {o.label}
        </button>
      ))}
    </div>
  );
}

function MoneyInput({ value, onChange, placeholder, id, ariaLabel }) {
  const [raw, setRaw] = useState(value == null ? '' : String(value));
  useEffect(() => {
    // sync from outside changes
    setRaw(value == null ? '' : String(value));
  }, [value]);
  return (
    <div className="money-input">
      <input
        id={id}
        type="text"
        inputMode="numeric"
        aria-label={ariaLabel}
        value={raw}
        placeholder={placeholder}
        onChange={(e) => {
          const cleaned = e.target.value.replace(/[^0-9]/g, '');
          setRaw(cleaned);
          const n = parseInt(cleaned, 10);
          onChange(Number.isFinite(n) ? n : 0);
        }}
      />
    </div>
  );
}

function Stepper({ value, onChange, min = 0, max = 10 }) {
  return (
    <div className="stepper" role="group" aria-label="adjust count">
      <button type="button" onClick={() => onChange(Math.max(min, value - 1))} aria-label="decrease">−</button>
      <span className="stepper-value" aria-live="polite">{value}</span>
      <button type="button" onClick={() => onChange(Math.min(max, value + 1))} aria-label="increase">+</button>
    </div>
  );
}

// Privacy badge — inline near sensitive income inputs
function PrivacyBadge({ onOpenModal }) {
  return (
    <span className="privacy-badge" title="All math runs on this device. Nothing is sent to a server.">
      Stays in your browser
      <button type="button" onClick={onOpenModal} aria-label="Read privacy details">why</button>
    </span>
  );
}

// Ad slot — renders the canonical AdSense pattern. `demo` is a design-preview-only
// opt-in that draws a striped placeholder; production always uses `demo={false}`.
function AdSlot({ id, demo = false, label = 'Advertisement' }) {
  const cfg = (window.adSlots && window.adSlots[id]) || {};
  useEffect(() => {
    if (demo || !cfg.slot || cfg.slot === 'XXXXX') return;
    try {
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (e) {}
  }, [demo, cfg.slot]);
  return (
    <div className={`ad-slot ad-slot--${id} ${demo ? 'ad-slot--demo' : ''}`}>
      <span className="ad-slot-label">{label}</span>
      {demo ? (
        <div className="ad-fill" aria-hidden="true">
          AD · {id}
        </div>
      ) : (
        <ins
          className="adsbygoogle"
          data-ad-client={cfg.client}
          data-ad-slot={cfg.slot}
          style={{ display: 'block' }}
        />
      )}
    </div>
  );
}

function MobileStickyAd({ demo = false }) {
  const [dismissed, setDismissed] = useState(() => {
    try { return sessionStorage.getItem('mss_dismissed') === '1'; } catch { return false; }
  });
  const cfg = (window.adSlots && window.adSlots['mobile-sticky']) || {};
  useEffect(() => {
    if (dismissed || demo || !cfg.slot || cfg.slot === 'XXXXX') return;
    try {
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (e) {}
  }, [dismissed, demo, cfg.slot]);
  if (dismissed) return null;
  return (
    <div className={`ad-slot ad-slot--mobile-sticky ${demo ? 'ad-slot--demo' : ''}`}>
      <span className="ad-slot-label">Advertisement</span>
      <button
        className="close-sticky"
        type="button"
        aria-label="Dismiss mobile ad"
        onClick={() => {
          try { sessionStorage.setItem('mss_dismissed', '1'); } catch {}
          setDismissed(true);
        }}
      >×</button>
      {demo ? (
        <div className="ad-fill" aria-hidden="true">AD · mobile-sticky 320×50</div>
      ) : (
        <ins
          className="adsbygoogle"
          data-ad-client={cfg.client}
          data-ad-slot={cfg.slot}
          style={{ display: 'block', width: 320, height: 50 }}
        />
      )}
    </div>
  );
}

Object.assign(window, {
  fmt, fmtPct,
  Segmented, MoneyInput, Stepper, PrivacyBadge,
  AdSlot, MobileStickyAd,
});
