// Shared primitives — used across all pages
// Exposes: Logo, Brand, Topbar, MenuOverlay, FloatCta, Footer, Ph (placeholder), useReveal, useI18n, useTheme, Tweaks

const { useState, useEffect, useRef, useContext, createContext, useCallback, useMemo } = React;

/* ---------------- i18n ---------------- */
const I18nContext = createContext(null);

function I18nProvider({ children }) {
  const [lang, setLang] = useState(() => {
    try { return localStorage.getItem('kdc-lang') || 'en'; } catch { return 'en'; }
  });
  useEffect(() => {
    try { localStorage.setItem('kdc-lang', lang); } catch {}
    document.documentElement.lang = lang;
  }, [lang]);
  const value = useMemo(() => ({
    lang,
    setLang,
    t: window.KDC_I18N[lang],
  }), [lang]);
  return React.createElement(I18nContext.Provider, { value }, children);
}
function useI18n() { return useContext(I18nContext); }

/* ---------------- theme (tweaks) ---------------- */
const ThemeContext = createContext(null);
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState(() => {
    try { return localStorage.getItem('kdc-theme') || 'light'; } catch { return 'light'; }
  });
  const [typePair, setTypePair] = useState(() => {
    try { return localStorage.getItem('kdc-type') || 'poppins'; } catch { return 'poppins'; }
  });
  const [menuStyle, setMenuStyle] = useState(() => {
    try { return localStorage.getItem('kdc-menu') || 'carousel'; } catch { return 'carousel'; }
  });

  useEffect(() => {
    document.documentElement.dataset.theme = theme;
    try { localStorage.setItem('kdc-theme', theme); } catch {}
  }, [theme]);

  useEffect(() => {
    const pairs = {
      poppins: { display: '"Poppins", sans-serif', sans: '"Poppins", system-ui, sans-serif' },
      fraunces: { display: '"Fraunces", serif', sans: '"Inter", system-ui, sans-serif' },
      playfair: { display: '"Playfair Display", serif', sans: '"Manrope", system-ui, sans-serif' },
    };
    const p = pairs[typePair] || pairs.poppins;
    document.documentElement.style.setProperty('--font-display', p.display);
    document.documentElement.style.setProperty('--font-sans', p.sans);
    try { localStorage.setItem('kdc-type', typePair); } catch {}
  }, [typePair]);

  useEffect(() => {
    try { localStorage.setItem('kdc-menu', menuStyle); } catch {}
  }, [menuStyle]);

  const value = useMemo(() => ({
    theme, setTheme, typePair, setTypePair, menuStyle, setMenuStyle,
  }), [theme, typePair, menuStyle]);
  return React.createElement(ThemeContext.Provider, { value }, children);
}
function useTheme() { return useContext(ThemeContext); }

/* ---------------- reveal on scroll ---------------- */
function useReveal() {
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -60px 0px' });
    document.querySelectorAll('.reveal, .reveal-stagger').forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
}

/* ---------------- Logo mark ---------------- */
function Logo({ size = 36 }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: size, height: size,
      flexShrink: 0,
    }}>
      <img
        src="assets/kdc-logo.png"
        alt="KDC Construction logo"
        width={size}
        height={size}
        style={{ width: size, height: size, objectFit: 'contain', display: 'block' }}
      />
    </span>
  );
}

/* ---------------- Brand mark ---------------- */
function Brand({ to = 'index.html' }) {
  const { t } = useI18n();
  return (
    <a href={to} className="brand" aria-label="KDC Constructions FL">
      <span className="brand-mark"><Logo size={88}/></span>
      <span className="brand-text">
        <span className="brand-text-main">KDC Construction FL</span>
        <span className="brand-text-sub">{t.brand.tagline}</span>
      </span>
    </a>
  );
}

/* ---------------- Language Switch ---------------- */
function LangSwitch() {
  const { lang, setLang } = useI18n();
  return (
    <div className="lang-switch" role="group" aria-label="Language">
      <button className={lang === 'en' ? 'active' : ''} onClick={() => setLang('en')}><span>EN</span></button>
      <button className={lang === 'es' ? 'active' : ''} onClick={() => setLang('es')}><span>ES</span></button>
    </div>
  );
}

/* ---------------- Topbar ---------------- */
function Topbar({ onMenuOpen, transparentOnHero = false }) {
  const { t } = useI18n();
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 60);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  const cls = ['topbar'];
  if (transparentOnHero && !scrolled) cls.push('on-hero');
  if (scrolled) cls.push('scrolled');
  return (
    <header className={cls.join(' ')}>
      <Brand/>
      <div className="top-right">
        <a className="pill" href="quote.html"><span>{t.nav.quote}</span></a>
        <LangSwitch/>
        <button className="menu-btn" onClick={onMenuOpen} aria-label={t.nav.menuLabel}>
          <span className="bars"><i/><i/></span>
          <span>{t.nav.menuLabel}</span>
        </button>
      </div>
    </header>
  );
}

/* ---------------- Menu Overlay (Carousel / Grid / Index) ---------------- */
function MenuOverlay({ open, onClose }) {
  const { t, lang } = useI18n();
  const { menuStyle } = useTheme();
  const scrollerRef = useRef(null);

  useEffect(() => {
    document.documentElement.style.overflow = open ? 'hidden' : '';
    return () => { document.documentElement.style.overflow = ''; };
  }, [open]);

  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const items = t.menu.items;
  const hrefs = ['index.html', 'services.html', 'projects.html', 'about.html', 'contact.html', 'quote.html'];

  const scroll = (dir) => {
    const el = scrollerRef.current;
    if (!el) return;
    const cardW = el.querySelector('.menu-card')?.offsetWidth || 400;
    el.scrollBy({ left: dir * (cardW + 24), behavior: 'smooth' });
  };

  return (
    <div className={`menu-overlay ${open ? 'open' : ''}`} aria-hidden={!open}>
      <div className="menu-top">
        <Brand/>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <LangSwitch/>
          <button className="menu-close" onClick={onClose}>
            <span>{t.nav.closeLabel}</span>
            <span style={{ fontSize: 14 }}>×</span>
          </button>
        </div>
      </div>

      {menuStyle === 'carousel' && (
        <>
          <div className="menu-carousel" ref={scrollerRef}>
            {items.map((it, i) => (
              <a key={i} className="menu-card" href={hrefs[i]}>
                <div className="menu-card-img" style={{
                  background: `linear-gradient(135deg, var(--kdc-navy-900), var(--kdc-navy-700))`,
                }}>
                  <MenuCardArt idx={i}/>
                </div>
                <div className="menu-card-content">
                  <div className="menu-card-top">
                    <span className="menu-card-num">{it.n}</span>
                    <span className="menu-card-tag">{it.tag}</span>
                  </div>
                  <div>
                    <div className="menu-card-title">{it.t}</div>
                    <div className="menu-card-desc" style={{ marginTop: 16 }}>{it.d}</div>
                  </div>
                </div>
              </a>
            ))}
          </div>
          <div className="menu-carousel-nav">
            <button onClick={() => scroll(-1)} aria-label="prev">←</button>
            <button onClick={() => scroll(1)} aria-label="next">→</button>
          </div>
          <div className="menu-footer-hint">{lang === 'en' ? 'Drag · scroll · click' : 'Arrastra · desliza · haz clic'}</div>
        </>
      )}

      {menuStyle === 'grid' && (
        <div style={{
          flex: 1,
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          gridTemplateRows: 'repeat(2, 1fr)',
          gap: 1,
          background: 'var(--line)',
          margin: 'var(--gutter)',
          borderTop: '1px solid var(--line)',
          borderLeft: '1px solid var(--line)',
        }}>
          {items.map((it, i) => (
            <a key={i} href={hrefs[i]} style={{
              background: 'var(--bg)',
              padding: 40,
              display: 'flex',
              flexDirection: 'column',
              justifyContent: 'space-between',
              color: 'var(--ink)',
              transition: 'background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease)',
            }}
            onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--kdc-navy-900)'; e.currentTarget.style.color = 'var(--bone-50)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.background = 'var(--bg)'; e.currentTarget.style.color = 'var(--ink)'; }}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.18em', opacity: 0.6 }}>
                <span>{it.n}</span><span>{it.tag}</span>
              </div>
              <div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(36px, 5vw, 64px)', letterSpacing: '-0.02em', lineHeight: 0.95 }}>{it.t}</div>
                <div style={{ marginTop: 16, fontSize: 14, opacity: 0.7, maxWidth: '32ch' }}>{it.d}</div>
              </div>
            </a>
          ))}
        </div>
      )}

      {menuStyle === 'list' && (
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 'var(--gutter)' }}>
          {items.map((it, i) => (
            <a key={i} href={hrefs[i]} style={{
              display: 'grid',
              gridTemplateColumns: '80px 1fr auto',
              gap: 32,
              padding: 'clamp(14px, 1.5vw, 22px) 0',
              borderBottom: '1px solid var(--line)',
              alignItems: 'baseline',
              color: 'var(--ink)',
              transition: 'padding-left var(--dur-fast) var(--ease)',
            }}
            onMouseEnter={(e) => { e.currentTarget.style.paddingLeft = '24px'; }}
            onMouseLeave={(e) => { e.currentTarget.style.paddingLeft = '0'; }}
            >
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '0.2em', color: 'var(--ink-3)' }}>{it.n}</span>
              <span style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(36px, 6vw, 84px)', letterSpacing: '-0.02em', lineHeight: 1 }}>{it.t}</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-3)' }}>{it.tag} →</span>
            </a>
          ))}
        </div>
      )}
    </div>
  );
}

function MenuCardArt({ idx }) {
  // Abstract geometric art per card
  const palettes = [
    { a: '#17335F', b: '#E8E2D7' },
    { a: '#0F2341', b: '#F3EFE8' },
    { a: '#2A5691', b: '#FAF8F4' },
    { a: '#1F4178', b: '#E8E2D7' },
    { a: '#0F2341', b: '#D8D1C3' },
    { a: '#17335F', b: '#F3EFE8' },
  ];
  const p = palettes[idx % palettes.length];
  return (
    <svg viewBox="0 0 400 560" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
      <rect width="400" height="560" fill={p.a}/>
      {idx === 0 && <>
        <rect x="40" y="200" width="320" height="200" fill="none" stroke={p.b} strokeWidth="1" opacity="0.4"/>
        <rect x="80" y="240" width="240" height="120" fill="none" stroke={p.b} strokeWidth="1" opacity="0.6"/>
        <circle cx="200" cy="300" r="40" fill={p.b} opacity="0.15"/>
      </>}
      {idx === 1 && <>
        {[0,1,2,3,4,5,6].map(i => (
          <line key={i} x1="0" y1={60+i*70} x2="400" y2={60+i*70} stroke={p.b} strokeWidth="1" opacity={0.1+i*0.04}/>
        ))}
        <rect x="150" y="220" width="100" height="100" fill={p.b} opacity="0.2"/>
      </>}
      {idx === 2 && <>
        <path d="M0 400 L100 350 L200 380 L300 320 L400 360 L400 560 L0 560 Z" fill={p.b} opacity="0.15"/>
        <path d="M0 450 L80 420 L180 440 L280 400 L400 430 L400 560 L0 560 Z" fill={p.b} opacity="0.08"/>
      </>}
      {idx === 3 && <>
        <circle cx="200" cy="280" r="160" fill="none" stroke={p.b} strokeWidth="1" opacity="0.3"/>
        <circle cx="200" cy="280" r="100" fill="none" stroke={p.b} strokeWidth="1" opacity="0.5"/>
        <circle cx="200" cy="280" r="40" fill={p.b} opacity="0.3"/>
      </>}
      {idx === 4 && <>
        <polygon points="200,80 340,280 200,480 60,280" fill="none" stroke={p.b} strokeWidth="1" opacity="0.4"/>
        <polygon points="200,160 280,280 200,400 120,280" fill={p.b} opacity="0.15"/>
      </>}
      {idx === 5 && <>
        <path d="M40 80 L360 80 L360 480 L200 520 L40 480 Z" fill="none" stroke={p.b} strokeWidth="1" opacity="0.4"/>
        <text x="200" y="300" textAnchor="middle" style={{ font: '300 120px var(--font-display, serif)', fill: p.b, opacity: 0.25 }}>＋</text>
      </>}
    </svg>
  );
}

/* ---------------- Placeholder image ---------------- */
function Ph({ label, ratio = '16/10', tone = 'default', style }) {
  const bgs = {
    default: {},
    dark: { background: 'var(--kdc-navy-900)', color: 'var(--bone-300)' },
    navy: { background: 'var(--kdc-navy-700)', color: 'var(--bone-50)' },
  };
  return (
    <div className="ph" style={{ aspectRatio: ratio, ...bgs[tone], ...style }}>
      <span>{label}</span>
    </div>
  );
}

/* ---------------- Float CTA (mobile call) ---------------- */
function FloatCta() {
  const { t } = useI18n();
  const [show, setShow] = useState(false);
  useEffect(() => {
    const onScroll = () => setShow(window.scrollY > 600);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <a className={`float-cta ${show ? 'show' : ''}`} href="quote.html">
      {t.nav.quote} →
    </a>
  );
}

/* ---------------- Footer with embedded form ---------------- */
function Footer() {
  const { t, lang } = useI18n();
  const MAKE_WEBHOOK = 'https://hook.eu2.make.com/aknc2civ2ty87i55w5gep1gh6sr5y3sr';
  const [sent, setSent] = useState(false);
  const [sending, setSending] = useState(false);
  const [vals, setVals] = useState({ name: '', email: '', msg: '', privacy: false });
  const submit = (e) => {
    e.preventDefault();
    setSending(true);
    fetch(MAKE_WEBHOOK, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        formType: 'Quick Message',
        name: vals.name,
        email: vals.email,
        message: vals.msg,
      }),
    }).finally(() => {
      setSending(false);
      setSent(true);
      setTimeout(() => { setSent(false); setVals({ name: '', email: '', msg: '', privacy: false }); }, 3500);
    });
  };
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div>
            <div className="eyebrow" style={{ color: 'rgba(250,248,244,0.6)', marginBottom: 20 }}>
              — {lang === 'en' ? 'Get in touch' : 'Contáctanos'}
            </div>
            <div className="footer-title">{t.footer.cta}</div>
            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
              <a className="footer-cta" href="tel:+13059882293">
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.18em', opacity: 0.6 }}>CALL</span>
                <span>(305) 988-2293</span>
              </a>
              <a className="footer-cta" href="mailto:info@kdcconstructionfl.com" style={{ background: 'transparent', color: 'var(--bone-50)', border: '1px solid rgba(255,255,255,0.2)' }}>
                info@kdcconstructionfl.com
              </a>
            </div>
          </div>
          <form className="footer-form" onSubmit={submit}>
            <h4>{t.footer.formTitle}</h4>
            <p>{t.footer.formSub}</p>
            <label className="field">
              <input required value={vals.name} onChange={e => setVals(v => ({...v, name: e.target.value}))} placeholder={t.footer.formName}/>
            </label>
            <label className="field">
              <input required type="email" value={vals.email} onChange={e => setVals(v => ({...v, email: e.target.value}))} placeholder={t.footer.formEmail}/>
            </label>
            <label className="field">
              <textarea required value={vals.msg} onChange={e => setVals(v => ({...v, msg: e.target.value}))} placeholder={t.footer.formMsg} rows="2"/>
            </label>
            {typeof FormPrivacyNotice !== 'undefined' && (
              <FormPrivacyNotice dark checked={vals.privacy} onChange={v => setVals(s => ({...s, privacy: v}))}/>
            )}
            <button type="submit" disabled={!vals.privacy || sending}>{sending ? '...' : sent ? t.footer.formSent : (t.footer.formSend + ' →')}</button>
          </form>
        </div>

        <div className="footer-cols">
          <div className="footer-col">
            <h5>{t.footer.nav}</h5>
            <ul>
              <li><a href="index.html">{t.nav.home}</a></li>
              <li><a href="services.html">{t.nav.services}</a></li>
              <li><a href="projects.html">{t.nav.projects}</a></li>
              <li><a href="about.html">{t.nav.about}</a></li>
              <li><a href="contact.html">{t.nav.contact}</a></li>
              <li><a href="quote.html">{t.nav.quote}</a></li>
            </ul>
          </div>
          <div className="footer-col">
            <h5>{t.footer.services}</h5>
            <ul>
              {t.services.items.slice(0, 6).map((s, i) => (
                <li key={i}><a href="services.html">{s.t}</a></li>
              ))}
            </ul>
          </div>
          <div className="footer-col">
            <h5>{t.footer.contact}</h5>
            <ul>
              <li><a href="tel:+13059882293">(305) 988-2293</a></li>
              <li><a href="mailto:info@kdcconstructionfl.com">info@kdcconstructionfl.com</a></li>
              <li style={{ opacity: 0.7, fontSize: 13, lineHeight: 1.5 }}>9300 Conroy Windermere Rd<br/>Windermere, FL 34786</li>
            </ul>
          </div>
        </div>

        <div className="footer-bottom">
          <div>{t.footer.legal}</div>
          <div style={{ display: 'flex', gap: 16 }}>
            <a href="privacy.html" style={{ color: 'rgba(250,248,244,0.7)' }}>{lang === 'en' ? 'Privacy' : 'Privacidad'}</a>
            <button onClick={() => window.KDC_CONSENT?.open()} style={{ color: 'rgba(250,248,244,0.7)', fontFamily: 'inherit', fontSize: 'inherit', letterSpacing: 'inherit', textTransform: 'inherit' }}>
              {lang === 'en' ? 'Privacy choices' : 'Preferencias'}
            </button>
            <span>CGC · FL · EST. 2004</span>
          </div>
        </div>
      </div>
    </footer>
  );
}

/* ---------------- Tweaks Panel ---------------- */
function Tweaks() {
  const [active, setActive] = useState(false);
  const [visible, setVisible] = useState(false);
  const { theme, setTheme, typePair, setTypePair, menuStyle, setMenuStyle } = useTheme();

  useEffect(() => {
    const onMsg = (e) => {
      if (e.data?.type === '__activate_edit_mode') setVisible(true);
      if (e.data?.type === '__deactivate_edit_mode') setVisible(false);
    };
    window.addEventListener('message', onMsg);
    window.parent?.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  if (!visible) return null;

  return (
    <>
      <button
        onClick={() => setActive(!active)}
        style={{
          position: 'fixed', bottom: 20, left: 20, zIndex: 70,
          padding: '12px 18px', borderRadius: 999,
          background: 'var(--ink)', color: 'var(--bg)',
          fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
          boxShadow: '0 10px 30px rgba(0,0,0,0.15)',
        }}
      >
        Tweaks {active ? '−' : '+'}
      </button>
      <div className={`tweaks-panel ${active ? 'open' : ''}`} style={{ bottom: 70 }}>
        <h4>Tweaks</h4>
        <div className="tweak-row">
          <label>Menu style</label>
          <div className="tweak-opts">
            {['carousel', 'grid', 'list'].map(s => (
              <button key={s} className={menuStyle === s ? 'active' : ''} onClick={() => setMenuStyle(s)}>{s}</button>
            ))}
          </div>
        </div>
        <div className="tweak-row">
          <label>Type pairing</label>
          <div className="tweak-opts">
            {[['poppins','Poppins'],['fraunces','Fraunces'],['playfair','Playfair']].map(([k,l]) => (
              <button key={k} className={typePair === k ? 'active' : ''} onClick={() => setTypePair(k)}>{l}</button>
            ))}
          </div>
        </div>
        <div className="tweak-row">
          <label>Theme</label>
          <div className="tweak-opts">
            {['light', 'dark'].map(s => (
              <button key={s} className={theme === s ? 'active' : ''} onClick={() => setTheme(s)}>{s}</button>
            ))}
          </div>
        </div>
      </div>
    </>
  );
}

/* ---------------- App Shell ---------------- */
function ShellUI({ children, transparentTop = false }) {
  const [menuOpen, setMenuOpen] = useState(false);
  useReveal();
  return (
    <>
      <Topbar onMenuOpen={() => setMenuOpen(true)} transparentOnHero={transparentTop}/>
      <MenuOverlay open={menuOpen} onClose={() => setMenuOpen(false)}/>
      <main>{children}</main>
      <Footer/>
      <FloatCta/>
      <Tweaks/>
      {typeof ConsentUI !== 'undefined' && <ConsentUI/>}
    </>
  );
}

function Shell({ children, transparentTop = false }) {
  // Backwards-compatible: used by Home which doesn't wrap with AppRoot.
  // If providers are already present above, we don't add them twice.
  const existing = useContext(I18nContext);
  if (existing) return <ShellUI transparentTop={transparentTop}>{children}</ShellUI>;
  return (
    <I18nProvider>
      <ThemeProvider>
        <ShellUI transparentTop={transparentTop}>{children}</ShellUI>
      </ThemeProvider>
    </I18nProvider>
  );
}

function AppRoot({ children }) {
  return (
    <I18nProvider>
      <ThemeProvider>
        {children}
      </ThemeProvider>
    </I18nProvider>
  );
}

/* ---------------- Page Head (shared) ---------------- */
function PageHead({ eyebrow, title, sub }) {
  return (
    <section style={{ paddingTop: 160, paddingBottom: 80 }}>
      <div className="container">
        <div className="section-head" style={{ borderTop: 'none', paddingTop: 0 }}>
          <div className="eyebrow">— {eyebrow}</div>
          <div>
            <h1 className="display reveal" style={{ fontSize: 'clamp(48px, 8vw, 140px)', whiteSpace: 'pre-line', marginBottom: 32 }}>{title}</h1>
            {sub && <p className="body-lg reveal" style={{ maxWidth: '58ch' }}>{sub}</p>}
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  Logo, Brand, LangSwitch, Topbar, MenuOverlay, Ph, FloatCta, Footer,
  Tweaks, Shell, AppRoot, PageHead, I18nProvider, ThemeProvider, useI18n, useTheme, useReveal,
});
