// MSECM App — sections + scroll-driven bg wash + theme + tweaks
const { useState, useEffect, useMemo, useRef } = React;

// Per-mood palettes
const MOODS = {
  cobalt: {
    name: 'Cool Cobalt',
    accent: '#1e40af',
    accentOnDeep: '#60a5fa',
    bgHero: '#f7f9fc',
    bgLight: '#ffffff',
    bgMid: '#eef3fb',
    bgDeep: '#0a1f44',
    bgFooter: '#06142e',
    ink: '#0a1729',
    inkSub: 'rgba(10,23,41,.55)',
    inkOnDeep: '#f4f7fc',
    inkOnDeepSub: 'rgba(244,247,252,.6)',
    cardBg: '#ffffff',
    cardOnDeep: 'rgba(255,255,255,.04)',
    divLine: 'rgba(10,23,41,.08)',
    divOnDeep: 'rgba(255,255,255,.08)',
    chipBg: 'rgba(255,255,255,.7)',
    chipBorder: 'rgba(10,23,41,.08)',
    gridLine: 'rgba(10,23,41,.05)',
    glow: 'rgba(30,64,175,.25)',
    dotIdle: 'rgba(10,23,41,.15)',
    navBg: 'rgba(247,249,252,.7)',
    navInk: '#0a1729',
  },
  steel: {
    name: 'Steel Editorial',
    accent: '#475569',
    accentOnDeep: '#94a3b8',
    bgHero: '#fafafa',
    bgLight: '#ffffff',
    bgMid: '#f1f3f6',
    bgDeep: '#1f2937',
    bgFooter: '#111827',
    ink: '#0f172a',
    inkSub: 'rgba(15,23,42,.55)',
    inkOnDeep: '#f8fafc',
    inkOnDeepSub: 'rgba(248,250,252,.6)',
    cardBg: '#ffffff',
    cardOnDeep: 'rgba(255,255,255,.04)',
    divLine: 'rgba(15,23,42,.08)',
    divOnDeep: 'rgba(255,255,255,.08)',
    chipBg: 'rgba(255,255,255,.7)',
    chipBorder: 'rgba(15,23,42,.08)',
    gridLine: 'rgba(15,23,42,.05)',
    glow: 'rgba(71,85,105,.22)',
    dotIdle: 'rgba(15,23,42,.15)',
    navBg: 'rgba(250,250,250,.72)',
    navInk: '#0f172a',
  },
  midnight: {
    name: 'Midnight Tech',
    accent: '#60a5fa',
    accentOnDeep: '#60a5fa',
    bgHero: '#04060d',
    bgLight: '#0a0e1a',
    bgMid: '#0f1525',
    bgDeep: '#000308',
    bgFooter: '#000000',
    ink: '#e6edf5',
    inkSub: 'rgba(230,237,245,.55)',
    inkOnDeep: '#e6edf5',
    inkOnDeepSub: 'rgba(230,237,245,.5)',
    cardBg: 'rgba(255,255,255,.03)',
    cardOnDeep: 'rgba(255,255,255,.02)',
    divLine: 'rgba(255,255,255,.08)',
    divOnDeep: 'rgba(255,255,255,.06)',
    chipBg: 'rgba(255,255,255,.04)',
    chipBorder: 'rgba(255,255,255,.1)',
    gridLine: 'rgba(255,255,255,.04)',
    glow: 'rgba(96,165,250,.3)',
    dotIdle: 'rgba(255,255,255,.12)',
    navBg: 'rgba(4,6,13,.7)',
    navInk: '#e6edf5',
  },
};

// Resolve a section's background from theme + tone
function bgForTone(theme, tone) {
  switch (tone) {
    case 'hero': return theme.bgHero;
    case 'light': return theme.bgLight;
    case 'mid': return theme.bgMid;
    case 'deep': return theme.bgDeep;
    case 'footer': return theme.bgFooter;
    default: return theme.bgLight;
  }
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "mood": "cobalt",
  "accent": "#1e40af"
}/*EDITMODE-END*/;

function useScrollY() {
  const [y, setY] = useState(0);
  useEffect(() => {
    let raf = 0;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => { setY(window.scrollY); raf = 0; });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return y;
}

// 모바일 분기 — 768px 기준. window 리사이즈 추적.
// 컴포넌트들이 이 훅을 호출해 grid 열 수·padding·메뉴 표시 등을 조정.
function useIsMobile(breakpoint = 768) {
  const [isMobile, setIsMobile] = useState(false);
  useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < breakpoint);
    check();
    window.addEventListener('resize', check);
    return () => window.removeEventListener('resize', check);
  }, [breakpoint]);
  return isMobile;
}

window.useIsMobile = useIsMobile;

// ─────────────────────────────────────────────────────────────────────────────
// BgWash — fixed full-viewport layer that interpolates between section colors
// based on scroll position. Creates the "Apple-style" smooth bg transitions.
// ─────────────────────────────────────────────────────────────────────────────
function lerp(a, b, t) { return a + (b - a) * t; }
function hexToRgb(h) {
  const m = h.replace('#','');
  const v = m.length === 3 ? m.split('').map(c => c+c).join('') : m;
  return [parseInt(v.slice(0,2),16), parseInt(v.slice(2,4),16), parseInt(v.slice(4,6),16)];
}
function rgbStr([r,g,b]) { return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`; }
function lerpRgb(a, b, t) {
  const ca = hexToRgb(a), cb = hexToRgb(b);
  return rgbStr([lerp(ca[0],cb[0],t), lerp(ca[1],cb[1],t), lerp(ca[2],cb[2],t)]);
}

function BgWash({ theme, scrollY }) {
  const [currentTone, setCurrentTone] = useState('hero');

  useEffect(() => {
    const sections = [...document.querySelectorAll('[data-bg-id]')];
    if (!sections.length) return;
    const tones = window.MSECM_DATA.sectionsMeta;
    // Active tone = the section that occupies the largest visible area of the viewport.
    // This guarantees the bg always matches the section the user is reading, so
    // text contrast never breaks across the boundary between adjacent sections.
    const vh = window.innerHeight;
    let bestEl = null, bestOverlap = -1;
    for (const el of sections) {
      const r = el.getBoundingClientRect();
      const top = Math.max(0, r.top);
      const bottom = Math.min(vh, r.bottom);
      const overlap = Math.max(0, bottom - top);
      if (overlap > bestOverlap) { bestOverlap = overlap; bestEl = el; }
    }
    const activeTone = bestEl
      ? (tones.find(s => s.id === bestEl.dataset.bgId)?.tone || 'hero')
      : 'hero';
    setCurrentTone(activeTone);
    // Expose to CSS var for Clients marquee fade gradient
    const isLight = activeTone === 'light' || activeTone === 'hero' || activeTone === 'mid';
    document.documentElement.style.setProperty('--bg-wash', isLight ? bgForTone(theme, activeTone) : 'transparent');
  }, [scrollY, theme]);

  const bg = bgForTone(theme, currentTone);

  return (
    <>
      <div aria-hidden style={{
        position: 'fixed', inset: 0, zIndex: -2,
        background: bg,
        transition: 'background .75s cubic-bezier(.4,0,.2,1)',
      }}/>
      {/* subtle radial glow that travels with scroll */}
      <div aria-hidden style={{
        position: 'fixed', inset: 0, zIndex: -1, pointerEvents: 'none',
        background: `radial-gradient(80vmax 60vmax at 50% ${30 + (scrollY * 0.02 % 80)}%, ${theme.glow}, transparent 60%)`,
        opacity: .7,
        transition: 'background .75s cubic-bezier(.4,0,.2,1)',
      }}/>
    </>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const baseTheme = MOODS[t.mood] || MOODS.cobalt;
  const theme = useMemo(() => ({ ...baseTheme, accent: t.accent || baseTheme.accent }), [baseTheme, t.accent]);
  const scrollY = useScrollY();

  // When mood changes, propagate its default accent (unless explicitly overridden in defaults)
  const lastMood = useRef(t.mood);
  useEffect(() => {
    if (lastMood.current !== t.mood) {
      setTweak('accent', MOODS[t.mood].accent);
      lastMood.current = t.mood;
    }
  }, [t.mood]);

  // Reveal animations via IntersectionObserver
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting) e.target.classList.add('in');
      }
    }, { threshold: 0.15, rootMargin: '0px 0px -80px 0px' });
    const els = document.querySelectorAll('[data-anim]');
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  });

  return (
    <div style={{ fontFamily: '"Pretendard Variable", "Pretendard", -apple-system, BlinkMacSystemFont, system-ui, sans-serif', WebkitFontSmoothing: 'antialiased', MozOsxFontSmoothing: 'grayscale', position: 'relative' }}>
      <BgWash theme={theme} scrollY={scrollY} />
      <Nav theme={theme} scrollY={scrollY} />
      <Hero theme={theme} scrollY={scrollY} />
      <Capabilities theme={theme} />
      <News theme={theme} />
      <Blog theme={theme} />
      <Portfolio theme={theme} />
      <Materials theme={theme} />
      <Stats theme={theme} />
      <Clients theme={theme} />
      <Press theme={theme} />
      <Footer theme={theme} />
      <MsecmChatbot accent={theme.accent} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Mood / Tone" />
        <TweakSelect label="무드 / 톤" value={t.mood}
          options={[
            { value: 'cobalt', label: 'Cool Cobalt — 신뢰감 코발트 블루' },
            { value: 'steel', label: 'Steel Editorial — 차분한 스틸 톤' },
            { value: 'midnight', label: 'Midnight Tech — 다크 모드' },
          ]}
          onChange={(v) => setTweak('mood', v)} />
        <TweakSection label="Accent" />
        <TweakColor label="Accent 컬러" value={t.accent}
          options={[
            MOODS[t.mood].accent,
            '#0066ff', '#2563eb', '#0ea5e9', '#1e40af', '#1d4ed8',
          ]}
          onChange={(v) => setTweak('accent', v)} />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
