// ui.jsx — Shared corporate-engineering UI primitives for Enginuity
// Calm, photographic, professional. Like Hatch/DRA/EPCM.

const { useState, useEffect, useRef } = React;

// ── Logo ────────────────────────────────────────────────────────────────────
function Logo({ size = 32, variant = 'dark' }) {
  // Official Enginuity brand lockup (three bars + wordmark + tagline).
  // 'light' = white wordmark for dark backgrounds; 'dark' = steel-blue for light backgrounds;
  // 'black' = near-black wordmark for maximum contrast on light surfaces.
  const src = variant === 'light'
    ? 'assets/enginuity-logo-light.png'
    : variant === 'black'
      ? 'assets/enginuity-logo-black.png'
      : 'assets/enginuity-logo-dark.png';
  return (
    <img src={src}
         alt="Enginuity — Empowering innovation, engineering success"
         style={{ height: size, width: 'auto', display: 'block' }} />
  );
}

// ── Eyebrow — small label above titles ─────────────────────────────────────
function Eyebrow({ children, color, style = {} }) {
  return (
    <div style={{
      fontFamily: 'var(--ff-eyebrow)',
      fontSize: 13,
      fontWeight: 600,
      letterSpacing: '0.14em',
      textTransform: 'uppercase',
      color: color || 'var(--accent)',
      display: 'inline-flex',
      alignItems: 'center',
      gap: 10,
      whiteSpace: 'nowrap',
      ...style,
    }}>
      <span style={{ display: 'inline-block', width: 24, height: 1, background: 'currentColor', flexShrink: 0 }} />
      {children}
    </div>
  );
}

// ── Headline ───────────────────────────────────────────────────────────────
function Headline({ children, size = 'lg', as = 'h2', style = {}, balance = true }) {
  const Tag = as;
  const sizes = {
    sm:   'clamp(22px, 2vw, 30px)',
    md:   'clamp(28px, 3vw, 42px)',
    lg:   'clamp(36px, 4.5vw, 58px)',
    xl:   'clamp(44px, 6vw, 80px)',
    xxl:  'clamp(54px, 8vw, 110px)',
  };
  const lh = {
    sm: 1.2, md: 1.15, lg: 1.08, xl: 1.04, xxl: 1.0,
  };
  return (
    <Tag style={{
      fontFamily: 'var(--ff-display)',
      fontWeight: 'var(--display-w)',
      letterSpacing: 'var(--display-track)',
      fontSize: sizes[size],
      lineHeight: lh[size],
      color: 'var(--fg)',
      margin: 0,
      textWrap: balance ? 'balance' : 'pretty',
      ...style,
    }}>{children}</Tag>
  );
}

// ── Photo placeholder — clean, no HUD chrome ───────────────────────────────
// Diagonal-stripe placeholder with a small mono caption corner that says what
// image goes here. Photo is the star — we don't decorate it.
function Photo({ caption, src, objectPosition = 'center', aspect = '4/3', tone = 'industrial', kind = 'plant', style = {}, parallax = 0, overlay, className = '' }) {
  const ref = useRef(null);
  const [offset, setOffset] = useState(0);
  useEffect(() => {
    if (!parallax) return;
    const onScroll = () => {
      const el = ref.current; if (!el) return;
      const r = el.getBoundingClientRect();
      const center = r.top + r.height / 2;
      const vh = window.innerHeight;
      const dist = (center - vh / 2) / vh;
      setOffset(dist * parallax);
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, [parallax]);

  // Tone-driven gradient for the placeholder; once real photos drop in this whole
  // backdrop disappears behind <img>.
  const tones = {
    industrial: ['#2c2823', '#0e0c08'],
    sky:        ['#3d5b75', '#1d2e3f'],
    earth:      ['#5a4a35', '#2a2218'],
    plant:      ['#3a4538', '#1a201a'],
    studio:     ['#5a5650', '#2a2722'],
  };
  const [c1, c2] = tones[tone] || tones.industrial;
  const stripe = 'rgba(255,255,255,0.025)';
  const ink = 'rgba(255,255,255,0.5)';

  return (
    <div ref={ref} className={`enq-photo ${className}`} style={{
      position: 'relative',
      aspectRatio: aspect === 'auto' ? undefined : aspect,
      width: '100%',
      background: `linear-gradient(135deg, ${c1} 0%, ${c2} 100%)`,
      overflow: 'hidden',
      ...style,
    }}>
      {src ? (
        <img src={src} alt={caption || ''} loading="lazy" style={{
          position: 'absolute', inset: 0, width: '100%', height: '100%',
          objectFit: 'cover', objectPosition,
          transform: parallax ? `translateY(${offset}px) scale(1.06)` : 'none',
        }} />
      ) : (
        <>
          <div style={{
            position: 'absolute', inset: 0,
            backgroundImage: `repeating-linear-gradient(135deg, ${stripe} 0 1px, transparent 1px 18px)`,
            transform: `translateY(${offset}px)`,
            transition: 'none',
          }} />
          {/* Subtle silhouette suggestion — industrial */}
          <svg viewBox="0 0 200 150" preserveAspectRatio="xMidYMax slice"
               width="100%" height="100%"
               style={{ position: 'absolute', inset: 0, opacity: 0.22 }}>
            <path d="M0 140 L25 100 L40 110 L55 80 L70 95 L90 70 L105 88 L125 65 L140 85 L160 75 L200 95 L200 150 L0 150 Z"
                  fill={ink} />
            <path d="M0 145 L40 120 L80 135 L130 110 L180 130 L200 122 L200 150 L0 150 Z"
                  fill={ink} opacity="0.5" />
          </svg>
          <div style={{
            position: 'absolute', bottom: 10, left: 14,
            fontFamily: '"Source Sans 3", sans-serif',
            fontSize: 10, fontWeight: 500,
            letterSpacing: '0.1em', textTransform: 'uppercase',
            color: 'rgba(255,255,255,0.45)',
          }}>
            Photograph · {caption}
          </div>
        </>
      )}
      {overlay}
    </div>
  );
}

// ── Header ─────────────────────────────────────────────────────────────────
function Header({ route, onNav }) {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 24);
    on();
    window.addEventListener('scroll', on, { passive: true });
    return () => window.removeEventListener('scroll', on);
  }, []);

  const items = [
    { id: 'about',        label: 'About' },
    { id: 'capabilities', label: 'Services' },
    { id: 'careers',      label: 'Careers' },
  ];

  const onHeroPage = route === 'home' || route === '';
  const transparent = onHeroPage && !scrolled;

  return (
    <header style={{
      position: 'fixed', top: 0, left: 0, right: 0, zIndex: 50,
      background: transparent ? 'color-mix(in oklch, var(--bg) 0%, transparent)' : 'color-mix(in oklch, var(--bg) 92%, transparent)',
      backdropFilter: transparent ? 'blur(0px) saturate(100%)' : 'blur(14px) saturate(150%)',
      WebkitBackdropFilter: transparent ? 'blur(0px) saturate(100%)' : 'blur(14px) saturate(150%)',
      borderBottom: `1px solid ${transparent ? 'transparent' : 'var(--hair)'}`,
      transition: 'border-color .25s',
      color: transparent ? '#ffffff' : 'var(--fg)',
    }}>
      <div style={{
        maxWidth: 1440, margin: '0 auto', padding: '18px 32px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24,
      }}>
        <button onClick={() => onNav('home')} style={{
          appearance: 'none', border: 0, background: 'transparent', padding: 0,
          color: 'inherit', cursor: 'pointer',
        }}>
          <Logo size={34} variant={transparent ? 'light' : 'dark'} />
        </button>
        <nav className="enq-desktop-nav" style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
          {items.map((it) => {
            const active = route.split('/')[0] === it.id;
            return (
              <button key={it.id} onClick={() => onNav(it.id)} style={{
                appearance: 'none', border: 0, background: 'transparent',
                padding: '8px 16px', cursor: 'pointer',
                fontFamily: '"Source Sans 3", sans-serif',
                fontSize: 15, fontWeight: 500,
                color: 'inherit',
                opacity: active ? 1 : 0.78,
                position: 'relative',
                whiteSpace: 'nowrap',
                transition: 'opacity .15s',
              }}
              onMouseEnter={(e) => { e.currentTarget.style.opacity = '1'; }}
              onMouseLeave={(e) => { e.currentTarget.style.opacity = active ? '1' : '0.78'; }}
              >
                {it.label}
                {active && <span style={{
                  position: 'absolute', left: 16, right: 16, bottom: 0, height: 2,
                  background: 'var(--accent)',
                }} />}
              </button>
            );
          })}
        </nav>
        <div className="enq-desktop-cta" style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <button onClick={() => onNav('contact')} style={{
            appearance: 'none', border: `1px solid ${transparent ? 'rgba(255,255,255,0.3)' : 'var(--hair-s)'}`,
            background: transparent ? 'rgba(255,255,255,0.08)' : 'transparent',
            color: 'inherit',
            padding: '10px 18px', cursor: 'pointer',
            fontFamily: '"Source Sans 3", sans-serif', fontSize: 14, fontWeight: 500,
            backdropFilter: transparent ? 'blur(8px)' : 'none',
            transition: 'background .2s',
          }}>
            Contact us →
          </button>
        </div>
        <button onClick={() => setMenuOpen((v) => !v)} className="enq-mobile-toggle" style={{
          appearance: 'none', border: '1px solid currentColor', background: 'transparent',
          color: 'inherit', padding: '8px 12px',
          fontFamily: '"Source Sans 3", sans-serif', fontSize: 13, fontWeight: 500,
          cursor: 'pointer', display: 'none',
        }}>
          {menuOpen ? 'Close' : 'Menu'}
        </button>
      </div>
      {menuOpen && (
        <div className="enq-mobile-menu" style={{
          background: 'var(--bg)', color: 'var(--fg)',
          borderTop: '1px solid var(--hair)',
          padding: '12px 32px 18px', display: 'none', flexDirection: 'column', gap: 0,
        }}>
          {[...items, { id: 'contact', label: 'Contact' }].map((it) => (
            <button key={it.id} onClick={() => { onNav(it.id); setMenuOpen(false); }} style={{
              appearance: 'none', border: 0, background: 'transparent', textAlign: 'left',
              padding: '14px 0', borderBottom: '1px solid var(--hair)',
              cursor: 'pointer', color: 'var(--fg)',
              fontFamily: '"Source Sans 3", sans-serif', fontSize: 18, fontWeight: 500,
            }}>{it.label}</button>
          ))}
        </div>
      )}
    </header>
  );
}

// ── Section wrapper ────────────────────────────────────────────────────────
function Section({ id, children, style = {}, contained = true, py = true }) {
  return (
    <section id={id} style={{
      position: 'relative',
      padding: py ? 'var(--section-y) 0' : 0,
      ...style,
    }}>
      <div style={{
        maxWidth: contained ? 1320 : 'none',
        margin: '0 auto',
        padding: contained ? '0 32px' : 0,
        position: 'relative',
      }}>
        {children}
      </div>
    </section>
  );
}

// ── Button ─────────────────────────────────────────────────────────────────
function Button({ children, onClick, variant = 'solid', size = 'md', style = {}, icon = '→' }) {
  const sizes = {
    sm: { padX: 16, padY: 9,  fs: 14 },
    md: { padX: 20, padY: 12, fs: 15 },
    lg: { padX: 26, padY: 15, fs: 16 },
  }[size];
  const variants = {
    solid:   { bg: 'var(--accent)', fg: 'var(--on-accent)', border: 'var(--accent)' },
    outline: { bg: 'transparent', fg: 'var(--fg)', border: 'var(--hair-s)' },
    ghost:   { bg: 'transparent', fg: 'var(--accent)', border: 'transparent' },
    invert:  { bg: 'var(--fg)', fg: 'var(--bg)', border: 'var(--fg)' },
    light:   { bg: '#ffffff', fg: '#15171a', border: '#ffffff' },
  }[variant];
  return (
    <button onClick={onClick} style={{
      appearance: 'none', border: `1px solid ${variants.border}`,
      background: variants.bg, color: variants.fg,
      padding: `${sizes.padY}px ${sizes.padX}px`,
      fontFamily: '"Source Sans 3", sans-serif',
      fontSize: sizes.fs, fontWeight: 600,
      cursor: 'pointer',
      display: 'inline-flex', alignItems: 'center', gap: 12,
      whiteSpace: 'nowrap',
      transition: 'transform .15s, background .15s, border-color .15s',
      ...style,
    }}
    onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-1px)'; }}
    onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; }}>
      {children}
      {icon && <span aria-hidden style={{ display: 'inline-block', transition: 'transform .2s', fontSize: sizes.fs * 0.9 }}>{icon}</span>}
    </button>
  );
}

// ── ReadMore — text link with arrow ────────────────────────────────────────
function ReadMore({ children = 'Read more', onClick, style = {}, color }) {
  const [h, setH] = useState(false);
  return (
    <button onClick={onClick}
            onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
            style={{
      appearance: 'none', border: 0, background: 'transparent', padding: 0,
      cursor: 'pointer',
      fontFamily: '"Source Sans 3", sans-serif', fontSize: 14, fontWeight: 600,
      letterSpacing: '0.02em',
      color: color || 'var(--fg)',
      display: 'inline-flex', alignItems: 'center', gap: 10,
      whiteSpace: 'nowrap',
      ...style,
    }}>
      <span style={{
        borderBottom: `1px solid ${h ? 'var(--accent)' : 'currentColor'}`,
        paddingBottom: 2,
        transition: 'border-color .2s',
        whiteSpace: 'nowrap',
      }}>{children}</span>
      <span style={{
        color: 'var(--accent)',
        transform: h ? 'translateX(4px)' : 'translateX(0)',
        transition: 'transform .2s',
      }}>→</span>
    </button>
  );
}

// ── Footer ─────────────────────────────────────────────────────────────────
function Footer({ onNav }) {
  return (
    <footer style={{
      background: 'var(--bg2)', color: 'var(--fg)',
      borderTop: '1px solid var(--hair)',
      padding: '80px 0 32px',
    }}>
      <div style={{ maxWidth: 1320, margin: '0 auto', padding: '0 32px' }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: 'minmax(0, 1.4fr) repeat(3, minmax(0, 1fr))',
          gap: 48, paddingBottom: 56,
        }} className="enq-footer-grid">
          <div>
            <Logo size={40} variant="black" />
            <p style={{
              marginTop: 22, fontSize: 15, lineHeight: 1.6,
              color: 'var(--fg2)', maxWidth: 340,
            }}>
              A multi-disciplinary engineering, project delivery and technology
              development partner for the mining, minerals and industrial sectors.
            </p>
            <div style={{ marginTop: 24 }}>
              <a href="https://www.linkedin.com/company/engnza" target="_blank" rel="noreferrer" style={{
                display: 'inline-flex', alignItems: 'center', gap: 8,
                color: 'var(--fg2)', textDecoration: 'none', fontSize: 14, fontWeight: 500,
              }}>
                <svg width="18" height="18" viewBox="0 0 18 18" fill="currentColor"><path d="M3.5 6.5h2.7v8.3H3.5zM4.85 2.5a1.55 1.55 0 110 3.1 1.55 1.55 0 010-3.1zM7.8 6.5h2.6v1.13c.37-.66 1.27-1.38 2.6-1.38 2.78 0 3.3 1.7 3.3 4.2v4.4h-2.7v-3.9c0-.93 0-2.1-1.36-2.1s-1.57.97-1.57 2.05v3.95h-2.7V6.5z"/></svg>
                LinkedIn
              </a>
            </div>
          </div>
          {[
            { title: 'Services', links: [
              ['EPCM delivery',    'capabilities/epcm'],
              ['R&D & innovation', 'capabilities/rd'],
              ['All services',     'capabilities'],
            ]},
            { title: 'Company', links: [
              ['About',     'about'],
              ['Contact',   'contact'],
            ]},
            { title: 'Offices', plain: [
              'Centurion · South Africa',
              'St Gallen · Switzerland',
            ]},
          ].map((col, i) => (
            <div key={i}>
              <div style={{
                fontFamily: '"Source Sans 3", sans-serif', fontSize: 12, fontWeight: 700,
                letterSpacing: '0.14em', textTransform: 'uppercase',
                color: 'var(--mid)',
              }}>{col.title}</div>
              <ul style={{ listStyle: 'none', padding: 0, margin: '18px 0 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
                {col.links?.map(([label, target]) => (
                  <li key={label + target}>
                    <button onClick={() => onNav(target)} style={{
                      appearance: 'none', border: 0, background: 'transparent', padding: 0,
                      cursor: 'pointer', color: 'var(--fg)', fontSize: 15, textAlign: 'left',
                      fontFamily: '"Source Sans 3", sans-serif', fontWeight: 400,
                    }}
                    onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--accent)'; }}
                    onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--fg)'; }}
                    >{label}</button>
                  </li>
                ))}
                {col.plain?.map((line, j) => (
                  <li key={j} style={{ color: 'var(--fg2)', fontSize: 14, lineHeight: 1.5 }}>{line}</li>
                ))}
              </ul>
            </div>
          ))}
        </div>
        <div style={{
          borderTop: '1px solid var(--hair)', paddingTop: 24,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          flexWrap: 'wrap', gap: 16,
          fontSize: 13, color: 'var(--mid)',
        }}>
          <span>© 2026 Enginuity (Pty) Ltd · All rights reserved</span>
          <div style={{ display: 'flex', gap: 24 }}>
            <span>Privacy</span>
            <span>Terms</span>
            <span>Sitemap</span>
          </div>
        </div>
      </div>
    </footer>
  );
}

// ── PageHero — inner-page hero with a photo band ───────────────────────────
function PageHero({ eyebrow, title, sub, tone = 'industrial', img, shift = false, children }) {
  return (
    <section style={{
      position: 'relative',
      paddingTop: 0,
      background: '#0f1114',
      color: '#ffffff',
      overflow: 'hidden',
    }}>
      <div style={{ position: 'absolute', inset: 0 }}>
        <Photo aspect="auto" tone={tone} src={img} parallax={-30} style={{ height: '100%' }} caption={title} />
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(15,17,20,0.6) 0%, rgba(15,17,20,0.4) 50%, rgba(15,17,20,0.85) 100%)' }} />
      </div>
      <div className={shift ? 'enq-hero-shift' : undefined} style={{
        position: 'relative',
        maxWidth: 1320, margin: '0 auto',
        padding: '180px 32px 88px',
      }}>
        {eyebrow && <Eyebrow color="#ffffff" style={{ opacity: 0.9 }}>{eyebrow}</Eyebrow>}
        <Headline size="xl" as="h1" style={{ color: '#ffffff', marginTop: 20, maxWidth: '18ch' }}>{title}</Headline>
        {sub && (
          <p style={{
            marginTop: 24, fontSize: 'clamp(17px, 1.3vw, 21px)', lineHeight: 1.5,
            color: 'rgba(255,255,255,0.85)', maxWidth: '54ch', margin: '24px 0 0',
          }}>{sub}</p>
        )}
        {children}
      </div>
    </section>
  );
}

// ── Form delivery ──────────────────────────────────────────────────────────
// Server-side email via Web3Forms (free, supports file attachments).
// Get a free access key at https://web3forms.com for karla.naude@engn.co.za,
// then paste it below. Until a real key is set, forms gracefully fall back to
// opening the visitor's mail app addressed to Karla, so nothing breaks.
const WEB3FORMS_ACCESS_KEY = '466cc269-b222-4986-81a1-b9630ca83cd9';

async function sendEnginuityForm({ subject, fields, file }) {
  const keyMissing = !WEB3FORMS_ACCESS_KEY || WEB3FORMS_ACCESS_KEY.indexOf('REPLACE') === 0;
  if (keyMissing) {
    const body = Object.entries(fields).map(([k, v]) => `${k}: ${v || ''}`).join('\n');
    window.location.href = `mailto:karla.naude@engn.co.za?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
    return { ok: true, fallback: true };
  }
  try {
    const fd = new FormData();
    fd.append('access_key', WEB3FORMS_ACCESS_KEY);
    fd.append('subject', subject);
    fd.append('from_name', fields.Name || 'Enginuity website');
    Object.entries(fields).forEach(([k, v]) => fd.append(k, v || ''));
    if (file) fd.append('attachment', file, file.name);
    const r = await fetch('https://api.web3forms.com/submit', { method: 'POST', body: fd });
    const data = await r.json().catch(() => ({}));
    return { ok: r.ok && data.success !== false };
  } catch (err) {
    return { ok: false, error: err.message };
  }
}

Object.assign(window, {
  Logo, Eyebrow, Headline, Photo, Header, Section,
  Button, ReadMore, Footer, PageHero, sendEnginuityForm,
});
