/* global React */
// Shared sendvo brand atoms — Wordmark, Buttons, Eyebrow, Mono, Mark.
// Consumed by v2-interactive.jsx via window.* globals.

const SVEyebrow = ({ children, color, style }) => (
  <div style={{
    fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: 'var(--sv-text-micro)',
    letterSpacing: '0.16em', textTransform: 'uppercase',
    color: color || 'var(--sv-stone)', lineHeight: 1, ...style,
  }}>{children}</div>
);

const SVMono = ({ children, size = 13, color, weight = 400, style, ...rest }) => (
  <span {...rest} style={{
    fontFamily: 'var(--sv-font-mono)', fontWeight: weight, fontSize: size,
    color: color || 'var(--sv-pitch)', fontFeatureSettings: '"tnum" 1',
    letterSpacing: '-0.005em', ...style,
  }}>{children}</span>
);

const SVBtn = ({ variant = 'primary', children, onClick, size = 'md', style, href, target, rel }) => {
  const sizes = {
    sm: { h: 32, p: '0 14px', f: 13 },
    md: { h: 40, p: '0 18px', f: 14 },
    lg: { h: 52, p: '0 26px', f: 15 },
  };
  const s = sizes[size];
  const v = {
    primary:   { bg: 'var(--sv-volt)',  fg: 'var(--sv-pitch)',   border: 'transparent', hover: 'color-mix(in srgb, var(--sv-volt) 85%, #000)' },
    dark:      { bg: 'var(--sv-pitch)', fg: 'var(--sv-paper)',   border: 'transparent', hover: 'color-mix(in srgb, var(--sv-pitch) 92%, #fff)' },
    ghost:     { bg: 'transparent',     fg: 'var(--sv-pitch)',   border: 'var(--sv-border-strong)', hover: 'var(--sv-pitch-06)' },
    onDark:    { bg: 'transparent',     fg: 'var(--sv-paper)',   border: 'rgba(247,245,240,0.24)', hover: 'rgba(247,245,240,0.06)' },
    light:     { bg: 'var(--sv-paper)', fg: 'var(--sv-pitch)',   border: 'transparent', hover: 'var(--sv-bg-elevated)' },
  }[variant];
  const [hover, setHover] = React.useState(false);
  // `min-height: s.h` instead of `height` so CSS can lift small buttons to
  // 44 CSS px on touch viewports (see colors_and_type.css → @media (pointer:
  // coarse), (max-width: 720px)) without overriding the desktop look.
  // `data-size` exposes the size so the CSS can target sm/md only — `lg`
  // already clears 44.
  // When `href` is passed, render as <a> so we don't nest <button> inside
  // <a> (HTML5 content-model violation; doubles tab stops; flagged by a11y).
  const sharedStyle = {
    fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: s.f,
    minHeight: s.h, padding: s.p, borderRadius: 'var(--sv-radius-sm)',
    border: `1px solid ${v.border}`, background: hover ? v.hover : v.bg, color: v.fg,
    cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 10,
    letterSpacing: '-0.005em',
    transition: 'background 150ms var(--sv-ease), transform 120ms var(--sv-ease)',
    whiteSpace: 'nowrap', textDecoration: 'none',
    ...style,
  };
  const sharedHandlers = {
    onMouseEnter: () => setHover(true),
    onMouseLeave: (e) => { setHover(false); e.currentTarget.style.transform = 'scale(1)'; },
    onMouseDown: e => e.currentTarget.style.transform = 'scale(0.99)',
    onMouseUp:   e => e.currentTarget.style.transform = 'scale(1)',
    onTouchStart: e => e.currentTarget.style.transform = 'scale(0.99)',
    onTouchEnd:   e => e.currentTarget.style.transform = 'scale(1)',
  };
  if (href) {
    const isExternal = /^https?:\/\//.test(href);
    return (
      <a
        href={href}
        className="sv-btn"
        data-size={size}
        target={target || (isExternal ? '_blank' : undefined)}
        rel={rel || (isExternal ? 'noopener' : undefined)}
        style={sharedStyle}
        {...sharedHandlers}
      >{children}</a>
    );
  }
  return (
    <button className="sv-btn" data-size={size} onClick={onClick} style={sharedStyle} {...sharedHandlers}>{children}</button>
  );
};

const SVWordmark = ({ light, size = 22, style }) => (
  <div style={{
    fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: size,
    letterSpacing: '-0.04em', color: light ? 'var(--sv-paper)' : 'var(--sv-pitch)',
    lineHeight: 1, display: 'inline-flex', ...style,
  }}>sendvo<span style={{ color: 'var(--sv-volt)' }}>.</span></div>
);

// The chevron mark, drawn directly (so we can scale and recolor).
const SVMark = ({ size = 40 }) => (
  <svg width={size} height={size} viewBox="0 0 100 100" fill="none"
       strokeLinejoin="miter" strokeLinecap="butt" strokeMiterlimit="10"
       style={{ display: 'block' }}>
    <polyline points="20,22 44,50 20,78" stroke="var(--sv-pitch)" strokeWidth="11"/>
    <polyline points="56,22 80,50 56,78" stroke="#FF5722" strokeWidth="11"/>
  </svg>
);

// Big oversized mark used as a background graphic device on dark pages.
const SVMarkXL = ({ width = 800, color = '#FF5722', strokeWidth = 11 }) => (
  <svg width={width} height={width} viewBox="0 0 100 100" fill="none"
       strokeLinejoin="miter" strokeLinecap="butt" strokeMiterlimit="10"
       style={{ display: 'block' }}>
    <polyline points="20,22 44,50 20,78" stroke="var(--sv-paper)" strokeWidth={strokeWidth}/>
    <polyline points="56,22 80,50 56,78" stroke={color} strokeWidth={strokeWidth}/>
  </svg>
);

// Inline status pill — used in eyebrows, badges, table rows.
const SVPill = ({ children, color = 'var(--sv-delivered)', bg, style }) => (
  <span style={{
    display: 'inline-flex', alignItems: 'center', gap: 6,
    padding: '4px 10px', borderRadius: 'var(--sv-radius-pill)',
    background: bg || 'var(--sv-pitch-06)',
    fontFamily: 'var(--sv-font-mono)', fontWeight: 500, fontSize: 11,
    letterSpacing: '0.04em', textTransform: 'uppercase',
    color: 'var(--sv-pitch)', ...style,
  }}>
    <span style={{ width: 6, height: 6, borderRadius: 'var(--sv-radius-pill)', background: color }}/>
    {children}
  </span>
);

// A tiny "→" used as a flow connector, matching the brand chevron's miter joins.
const SVArrow = ({ size = 16, color = 'currentColor' }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       strokeLinejoin="miter" strokeLinecap="butt" strokeMiterlimit="10">
    <polyline points="5,6 11,12 5,18" stroke={color} strokeWidth="2.4"/>
    <polyline points="13,6 19,12 13,18" stroke={color} strokeWidth="2.4"/>
  </svg>
);

// Unified section h2 — 48px display, -0.035em letter-spacing, line-height
// 1.02, pitch color. `maxWidth` varies per section content. Section heads
// are the page's primary hierarchy marker — see CLAUDE.md § Brand tokens.
const SVSectionH2 = ({ children, maxWidth, color, style }) => (
  <h2 className="sv-section-h2" style={{
    margin: '14px 0 0',
    fontFamily: 'var(--sv-font-display)',
    fontWeight: 500,
    fontSize: 'var(--sv-text-display)',
    letterSpacing: '-0.035em',
    lineHeight: 1.02,
    color: color || 'var(--sv-pitch)',
    maxWidth,
    ...style,
  }}>{children}</h2>
);

// Micro label — mono 11px with wide letter-spacing. The canonical
// row-header / section sub-tag pattern. Default stone; pass `color`
// for accent variants (e.g. volt for SAVE in the quote calculator).
const SVMicroLabel = ({ children, color, style }) => (
  <SVMono size={11} color={color || 'var(--sv-stone)'} style={{ letterSpacing: '0.08em', ...style }}>{children}</SVMono>
);

// useWindowWidth — bucketed to a small set of breakpoints rather than
// pixel-precise. Two consumers (HeroDemo postcard, V2UseCases postcard)
// re-render when this changes, so flipping per-pixel during rubber-band
// scroll or rotation triggered an SVG re-render on every frame. Snapping
// to a bucket means re-renders only fire when crossing a threshold.
// Returned value is a representative width inside each bucket so callers
// can keep doing `Math.min(N, w - inset)` math.
const WIDTH_BUCKETS = [320, 480, 640, 768, 960, 1200, 1600];
const bucketFor = (w) => {
  for (const b of WIDTH_BUCKETS) if (w <= b) return b;
  return WIDTH_BUCKETS[WIDTH_BUCKETS.length - 1];
};
const useWindowWidth = () => {
  const [w, setW] = React.useState(() =>
    typeof window !== 'undefined' ? bucketFor(window.innerWidth) : 1200
  );
  React.useEffect(() => {
    const onResize = () => {
      const next = bucketFor(window.innerWidth);
      setW(prev => prev === next ? prev : next);
    };
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return w;
};

// Tweaks plumbing — a global React context so every section can read live
// tweak values without prop-drilling. Defaults match the in-page TWEAK_DEFAULTS.
const TweaksContext = React.createContext({
  accent: '#FF5722',
  surface: 'paper',
  displayWeight: 600,
  headline: 'send-like-email',
  heroCard: 'cash-offer',
  heroFlourish: true,
  pipelineSpeed: 1400,
  showPipeline: true,
  showCompare: true,
  showIntegrations: true,
});
const useT = () => React.useContext(TweaksContext);

// A simulated postcard render — used in the hero designer tab and the use-cases section.
// front = 'cash-offer' | 'probate' | 'winback' | 'thanks'
const SVPostcard = ({ variant = 'cash-offer', side = 'front', width = 360, dark = false, scale }) => {
  const aspect = 6 / 4; // 6x4 landscape
  const h = width / aspect;
  const bg = dark ? 'var(--sv-bg-dark-elevated)' : 'var(--sv-bg-elevated)';
  const ink = dark ? 'var(--sv-paper)' : 'var(--sv-pitch)';
  const muted = dark ? 'var(--sv-paper-70)' : 'var(--sv-stone)';
  const accent = '#FF5722';

  const fronts = {
    'cash-offer': (
      <div style={{ padding: '28px 30px', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase', color: muted }}>To the owner of</div>
        <div>
          <div style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: width * 0.085, letterSpacing: '-0.035em', lineHeight: 0.95, color: ink }}>
            We'd like to<br/>buy your house.
          </div>
          <div style={{ marginTop: 14, display: 'flex', alignItems: 'baseline', gap: 6 }}>
            <span style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 11, color: muted, letterSpacing: '0.04em' }}>Cash offer · 14-day close</span>
          </div>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end' }}>
          <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 10, color: muted }}>247 W 28TH ST · APT 3B</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <span style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: 13, color: ink, letterSpacing: '-0.02em' }}>summit homes</span>
            <span style={{ color: accent, fontSize: 13 }}>.</span>
          </div>
        </div>
      </div>
    ),
    'probate': (
      <div style={{ padding: '28px 30px', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase', color: muted }}>For the estate of</div>
        <div style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: width * 0.072, letterSpacing: '-0.03em', lineHeight: 1.0, color: ink }}>
          Selling a property<br/>you didn't ask for?
        </div>
        <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 10, color: muted }}>WE BUY AS-IS · NO REPAIRS · NO FEES</div>
      </div>
    ),
    'winback': (
      <div style={{ padding: '28px 30px', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase', color: accent }}>→ One last thing</div>
        <div style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: width * 0.09, letterSpacing: '-0.035em', lineHeight: 0.96, color: ink }}>
          Your cart<br/>misses you.
        </div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 14, color: ink, fontWeight: 500 }}>FRIDGE20</span>
          <span style={{ fontFamily: 'var(--sv-font-body)', fontSize: 11, color: muted }}>— 20% off, expires 14 days from today</span>
        </div>
      </div>
    ),
    'thanks': (
      <div style={{ padding: '28px 30px', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase', color: muted }}>Order #4128</div>
        <div style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: width * 0.13, letterSpacing: '-0.04em', lineHeight: 0.94, color: ink }}>
          thank you<span style={{ color: accent }}>.</span>
        </div>
        <div style={{ fontFamily: 'var(--sv-font-body)', fontSize: 11, color: muted, lineHeight: 1.5, maxWidth: '70%' }}>
          For ordering twice in one month. We notice. — Mara, founder, Loom & Ledger
        </div>
      </div>
    ),
  };

  const back = (
    <div style={{ padding: '24px 28px', height: '100%', display: 'flex' }}>
      <div style={{ flex: 1, paddingRight: 18, borderRight: `1px dashed ${dark ? 'rgba(247,245,240,0.18)' : 'var(--sv-ash)'}`, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--sv-font-body)', fontSize: 11, color: ink, lineHeight: 1.5 }}>
          Hey neighbor — we're a small team buying houses in Pine County. No agent, no commissions, no listings. If timing's right, text us. If not, toss this and we won't be in your mailbox again.
        </div>
        <div>
          <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 10, color: muted, letterSpacing: '0.04em' }}>TEXT · CALL</div>
          <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 13, color: ink, fontWeight: 500, marginTop: 2 }}>(206) 555 · 0148</div>
        </div>
      </div>
      <div style={{ flex: 1, paddingLeft: 18, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
          <div style={{ width: 50, height: 36, border: `1px solid ${dark ? 'rgba(247,245,240,0.3)' : 'var(--sv-ash)'}`, fontFamily: 'var(--sv-font-mono)', fontSize: 8, color: muted, display: 'flex', alignItems: 'center', justifyContent: 'center', textAlign: 'center', lineHeight: 1.1 }}>
            FIRST-CLASS<br/>POSTAGE PAID<br/>SENDVO
          </div>
        </div>
        <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 11, color: ink, lineHeight: 1.6 }}>
          MARIA RODRIGUEZ<br/>
          247 W 28TH ST APT 3B<br/>
          NEW YORK, NY 10001
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
            {[...Array(11)].map((_, i) => (
              <div key={i} style={{ width: 80, height: 1, background: ink }}/>
            ))}
          </div>
          <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 8, color: muted }}>IMb · 9712401</div>
        </div>
      </div>
    </div>
  );

  return (
    <div style={{
      width, height: h, background: bg, color: ink,
      borderRadius: 'var(--sv-radius-sm)', border: `1px solid ${dark ? 'rgba(247,245,240,0.10)' : 'var(--sv-ash)'}`,
      overflow: 'hidden', position: 'relative',
      transform: scale ? `scale(${scale})` : undefined,
      transformOrigin: 'top left',
      boxShadow: dark ? 'none' : 'var(--sv-shadow-1)',
    }}>
      {side === 'front' ? fronts[variant] : back}
    </div>
  );
};

Object.assign(window, {
  SVEyebrow, SVMono, SVBtn, SVWordmark, SVMark, SVMarkXL, SVPill, SVArrow, SVPostcard,
  SVSectionH2, SVMicroLabel,
  TweaksContext, useT, useWindowWidth,
});
