// Polaris B — full-bleed prototype components.
// Self-contained: nav, pages, scroll-reveal hook, animated counters,
// grain texture, mobile-aware. Uses shared.jsx components.

const COLORS_B = {
  bg: '#FFFFFF',
  bgAlt: '#F5F3EE',
  bgDeep: '#EBE7DC',
  ink: '#0F1614',
  inkSoft: 'rgba(15,22,20,0.62)',
  inkFaint: 'rgba(15,22,20,0.10)',
  accent: '#1F3D36',
  accentLight: '#2C5249',
  accentBright: '#4FA86A',
  line: 'rgba(15,22,20,0.10)',
  lineSoft: 'rgba(15,22,20,0.06)',
};

// ─────────── Hooks ───────────
function useReveal() {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setShown(true); io.disconnect(); }
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, shown];
}

function Reveal({ children, delay = 0, as = 'div', style, ...rest }) {
  const [ref, shown] = useReveal();
  const Tag = as;
  return (
    <Tag ref={ref} style={{
      ...style,
      opacity: shown ? 1 : 0,
      transform: shown ? 'translateY(0)' : 'translateY(18px)',
      transition: `opacity .9s cubic-bezier(.2,.7,.3,1) ${delay}ms, transform .9s cubic-bezier(.2,.7,.3,1) ${delay}ms`,
    }} {...rest}>{children}</Tag>
  );
}

function LineDraw({ delay = 0, color = COLORS_B.accent, vertical = false, style }) {
  const [ref, shown] = useReveal();
  return (
    <div ref={ref} style={{
      ...style,
      [vertical ? 'height' : 'width']: shown ? (style?.[vertical ? 'height' : 'width'] || '100%') : 0,
      [vertical ? 'width' : 'height']: 1,
      background: color,
      transition: `${vertical ? 'height' : 'width'} 1.1s cubic-bezier(.4,.0,.2,1) ${delay}ms`,
    }} />
  );
}

function CountUp({ value, duration = 1600, suffix = '' }) {
  const ref = React.useRef(null);
  const [n, setN] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (!e.isIntersecting) return;
      io.disconnect();
      const start = performance.now();
      const tick = (t) => {
        const p = Math.min(1, (t - start) / duration);
        const eased = 1 - Math.pow(1 - p, 3);
        setN(Math.round(value * eased));
        if (p < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [value, duration]);
  return <span ref={ref}>{n.toLocaleString()}{suffix}</span>;
}

// Render a stat value, animating numeric portion
function AnimatedStat({ raw }) {
  // Parse "240+", "18", "96%", "24/7"
  const match = raw.match(/^(\d+)(.*)$/);
  if (!match) return <>{raw}</>;
  const num = parseInt(match[1], 10);
  const suffix = match[2] || '';
  return <CountUp value={num} suffix={suffix} />;
}

// ─────────── Grain texture (CSS-only) ───────────
const GRAIN_CSS = `
  .b-grain { position: relative; }
  .b-grain::before {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .12 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
    background-size: 240px 240px;
    opacity: 0.55;
    mix-blend-mode: multiply;
    z-index: 0;
  }
  .b-grain > * { position: relative; z-index: 1; }
`;

// ─────────── Nav ───────────
function NavB2({ page, setPage, setContactOpen, isMobile }) {
  const [scrolled, setScrolled] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const links = [
    { id: 'home', label: 'Home' },
    { id: 'services', label: 'Services' },
    { id: 'projects', label: 'Projects' },
    { id: 'areas', label: 'Service Areas' },
    { id: 'about', label: 'About' },
    { id: 'contact', label: 'Contact' },
  ];

  if (isMobile) {
    return (
      <>
        <header style={{
          position: 'sticky', top: 0, zIndex: 50,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          padding: '14px 20px',
          background: scrolled ? 'rgba(255,255,255,0.92)' : '#fff',
          backdropFilter: scrolled ? 'blur(14px)' : 'none',
          borderBottom: `1px solid ${scrolled ? COLORS_B.line : 'transparent'}`,
          transition: 'all .25s',
        }}>
          <div onClick={() => { setPage('home'); setMenuOpen(false); }} style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }}>
            <PolarisLogo markColor={COLORS_B.accent} textColor={COLORS_B.ink} size={32} />
          </div>
          <button onClick={() => setMenuOpen(o => !o)} style={{
            width: 40, height: 40, background: 'transparent', border: `1px solid ${COLORS_B.line}`,
            borderRadius: 999, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0,
          }}>
            <Icon name={menuOpen ? 'close' : 'menu'} size={18} stroke={COLORS_B.ink} />
          </button>
        </header>
        {menuOpen && (
          <div style={{
            position: 'fixed', top: 68, left: 0, right: 0, bottom: 0, zIndex: 49,
            background: COLORS_B.bg, padding: '24px 20px',
            animation: 'bMenuFade .25s ease',
          }}>
            <style>{`@keyframes bMenuFade { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }`}</style>
            {links.map(l => (
              <button key={l.id} onClick={() => { setPage(l.id); setMenuOpen(false); }} style={{
                display: 'block', width: '100%', textAlign: 'left',
                padding: '20px 0', borderBottom: `1px solid ${COLORS_B.line}`,
                background: 'transparent', border: 'none', borderBottom: `1px solid ${COLORS_B.line}`,
                fontFamily: 'inherit', fontSize: 28, fontWeight: 500, letterSpacing: '-0.02em',
                color: page === l.id ? COLORS_B.accent : COLORS_B.ink,
                cursor: 'pointer',
              }}>{l.label}</button>
            ))}
            <button onClick={() => { setContactOpen(true); setMenuOpen(false); }} style={{
              marginTop: 32, width: '100%', padding: '18px 24px',
              background: COLORS_B.accent, color: '#fff',
              border: 'none', borderRadius: 999, cursor: 'pointer',
              fontFamily: 'inherit', fontSize: 13, fontWeight: 600, letterSpacing: '0.05em', textTransform: 'uppercase',
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
            }}>
              Request a proposal <Icon name="arrow-right" size={14} stroke="currentColor" strokeWidth={2} />
            </button>
            <div style={{ marginTop: 32, fontSize: 13, color: COLORS_B.inkSoft, lineHeight: 1.7 }}>
              <div>(630) 296-4277</div>
              <div>hello@polarislandscape.com</div>
              <div>670 Vandustrial Dr., Westmont</div>
            </div>
          </div>
        )}
      </>
    );
  }

  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 50,
      display: 'grid', gridTemplateColumns: '1fr auto 1fr', alignItems: 'center', gap: 32,
      padding: scrolled ? '14px 40px' : '20px 40px',
      borderBottom: `1px solid ${scrolled ? COLORS_B.line : 'transparent'}`,
      background: scrolled ? 'rgba(255,255,255,0.88)' : '#fff',
      backdropFilter: scrolled ? 'blur(16px)' : 'none',
      transition: 'all .3s cubic-bezier(.2,.7,.3,1)',
    }}>
      <div onClick={() => setPage('home')} style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }}>
        <PolarisLogo markColor={COLORS_B.accent} textColor={COLORS_B.ink} size={38} />
      </div>
      <nav style={{ display: 'flex', gap: 0, alignItems: 'center', justifyContent: 'center' }}>
        {links.map(l => (
          <button key={l.id} onClick={() => setPage(l.id)} style={{
            background: 'transparent', border: 'none', cursor: 'pointer',
            padding: '12px 18px', fontFamily: 'inherit',
            fontSize: 13, fontWeight: 500, letterSpacing: '0.02em', textTransform: 'uppercase',
            color: page === l.id ? COLORS_B.accent : COLORS_B.inkSoft,
            position: 'relative',
            borderBottom: page === l.id ? `2px solid ${COLORS_B.accent}` : '2px solid transparent',
            marginBottom: -1, transition: 'color .2s',
          }}>{l.label}</button>
        ))}
      </nav>
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 16, alignItems: 'center' }}>
        <button onClick={() => setContactOpen(true)} style={{
          padding: '11px 20px',
          background: COLORS_B.accent, color: '#fff',
          border: 'none', borderRadius: 999, cursor: 'pointer',
          fontFamily: 'inherit', fontSize: 12, fontWeight: 600, letterSpacing: '0.05em', textTransform: 'uppercase',
        }}>
          Request Proposal
        </button>
      </div>
    </header>
  );
}

window.NavB2 = NavB2;
window.COLORS_B = COLORS_B;
window.GRAIN_CSS = GRAIN_CSS;
window.Reveal = Reveal;
window.LineDraw = LineDraw;
window.CountUp = CountUp;
window.AnimatedStat = AnimatedStat;
