// App v3
const { useState, useEffect, useRef } = React;

const TWEAK_DEFAULTS_V3 = /*EDITMODE-BEGIN*/{
  "palette": "bone",
  "grain": 0.48,
  "spotlight": true
}/*EDITMODE-END*/;

const PALETTES_V3 = {
  bone: {
    label: 'bone & sumi', sub: 'default',
    swatch: ['#efe9dd', '#1a1812', '#c9462b'],
    vars: {
      '--paper': '#efe9dd', '--paper-2': '#e5dccb', '--paper-3': '#d8cdb8',
      '--ink': '#1a1812', '--ink-2': '#2e2a22', '--ash': '#6e6557', '--mist': '#aca395',
      '--vermilion': '#c9462b',
    },
  },
  mist: {
    label: 'morning mist', sub: 'cool grey · pale blue',
    swatch: ['#e8eaee', '#1d2230', '#a8c4d8'],
    vars: {
      '--paper': '#e8eaee', '--paper-2': '#dde0e6', '--paper-3': '#c8ccd4',
      '--ink': '#1d2230', '--ink-2': '#2c334a', '--ash': '#6a7081', '--mist': '#a8acb8',
      '--vermilion': '#7e94c0',
    },
  },
  ember: {
    label: 'ember', sub: 'peach · burgundy',
    swatch: ['#f5e3d0', '#2a1818', '#a83048'],
    vars: {
      '--paper': '#f5e3d0', '--paper-2': '#ecd4bc', '--paper-3': '#d8b89c',
      '--ink': '#2a1818', '--ink-2': '#3d2828', '--ash': '#7a5a52', '--mist': '#b89890',
      '--vermilion': '#a83048',
    },
  },
  noir: {
    label: 'noir', sub: 'inverted',
    swatch: ['#15130e', '#efe9dd', '#e85838'],
    vars: {
      '--paper': '#15130e', '--paper-2': '#1f1c15', '--paper-3': '#2a2620',
      '--ink': '#efe9dd', '--ink-2': '#d8cfbe', '--ash': '#a09588', '--mist': '#6e6557',
      '--vermilion': '#e85838',
    },
  },
  matcha: {
    label: 'matcha', sub: 'sage · cream',
    swatch: ['#e8e8d0', '#1c2418', '#7a8848'],
    vars: {
      '--paper': '#e8e8d0', '--paper-2': '#d8d8b8', '--paper-3': '#bcc098',
      '--ink': '#1c2418', '--ink-2': '#2e3424', '--ash': '#6a7058', '--mist': '#a8b098',
      '--vermilion': '#7a8848',
    },
  },
};
function applyPalette(name) {
  const p = PALETTES_V3[name] || PALETTES_V3.bone;
  Object.entries(p.vars).forEach(([k, v]) => document.documentElement.style.setProperty(k, v));
}

function GlobalAtmosphere() {
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: -1, pointerEvents: 'none', overflow: 'hidden' }}>
      {/* Very subtle warm haze — visible only in Hero/Them area */}
      <div style={{
        position: 'absolute',
        width: '60vw', height: '55vw',
        top: '8%', right: '-8%',
        background: 'radial-gradient(ellipse at 40% 44%, rgba(200,174,144,.10), transparent 70%)',
        filter: 'blur(120px)',
      }} />
      <div style={{
        position: 'absolute',
        width: '50vw', height: '44vw',
        top: '20%', left: '-10%',
        background: 'radial-gradient(ellipse 60% 46% at 58% 50%, rgba(208,178,148,.08), transparent 72%)',
        filter: 'blur(130px)',
      }} />
    </div>
  );
}

function CursorV3() {
  const [pos, setPos] = useState({ x: -200, y: -200 });
  const [hover, setHover] = useState(false);
  useEffect(() => {
    const move = (e) => setPos({ x: e.clientX, y: e.clientY });
    const over = (e) => setHover(!!e.target.closest?.('[data-hover]'));
    window.addEventListener('mousemove', move);
    window.addEventListener('mouseover', over);
    return () => {
      window.removeEventListener('mousemove', move);
      window.removeEventListener('mouseover', over);
    };
  }, []);
  return (
    <>
      <div className="cursor-spot" style={{ left: pos.x, top: pos.y }}></div>
      <div className={`cursor-dot ${hover ? 'hover' : ''}`} style={{ left: pos.x, top: pos.y }}></div>
    </>
  );
}

function LightboxV3({ data, onClose }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    if (data) window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [data, onClose]);
  return (
    <div className={`lightbox ${data ? 'open' : ''}`} onClick={onClose}>
      {data && <>
        <button className="lightbox-close" onClick={onClose} data-hover>close ⨯</button>
        <img src={data.src} alt={data.title} onClick={e => e.stopPropagation()} />
        <div className="lightbox-meta">
          <span>{data.title} · {data.label}</span>
          <span>petra voice</span>
        </div>
      </>}
    </div>
  );
}

function PaletteGridV3({ value, onChange }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
      {Object.entries(PALETTES_V3).map(([key, p]) => {
        const active = value === key;
        return (
          <button key={key} data-hover onClick={() => onChange(key)}
            style={{
              padding: '8px 10px', borderRadius: 8,
              border: active ? '1.5px solid rgba(41,38,27,.65)' : '.5px solid rgba(0,0,0,.1)',
              background: active ? 'rgba(255,255,255,.85)' : 'rgba(255,255,255,.4)',
              display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'flex-start',
              textAlign: 'left',
            }}>
            <div style={{ display: 'flex', gap: 3 }}>
              {p.swatch.map((c, i) => (
                <div key={i} style={{ width: 18, height: 18, borderRadius: 4, background: c, border: '.5px solid rgba(0,0,0,.08)' }}></div>
              ))}
            </div>
            <div style={{ fontSize: 10.5, fontWeight: 600, color: '#29261b' }}>{p.label}</div>
            <div style={{ fontSize: 9, color: 'rgba(41,38,27,.55)' }}>{p.sub}</div>
          </button>
        );
      })}
    </div>
  );
}

function App() {
  const [lb, setLb] = useState(null);
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS_V3);

  useEffect(() => { applyPalette(t.palette); }, [t.palette]);

  useEffect(() => {
    const block = e => { if (e.target.tagName === 'IMG') e.preventDefault(); };
    document.addEventListener('contextmenu', block);
    return () => document.removeEventListener('contextmenu', block);
  }, []);
  useEffect(() => {
    let s = document.getElementById('__grain-override');
    if (!s) { s = document.createElement('style'); s.id = '__grain-override'; document.head.appendChild(s); }
    s.textContent = `body::before { opacity: ${t.grain} !important; }`;
  }, [t.grain]);

  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('in'); });
    }, { threshold: 0.12, rootMargin: '0px 0px -10% 0px' });
    document.querySelectorAll('.reveal:not(.in)').forEach(el => io.observe(el));
    return () => io.disconnect();
  });

  useEffect(() => {
    let ticking = false;
    const onScroll = () => {
      if (ticking) return;
      ticking = true;
      requestAnimationFrame(() => {
        document.querySelectorAll('[data-parallax]').forEach(el => {
          const speed = parseFloat(el.getAttribute('data-parallax') || '0.15');
          const rect = el.getBoundingClientRect();
          const center = rect.top + rect.height / 2;
          const fromMiddle = center - window.innerHeight / 2;
          el.style.transform = `translateY(${fromMiddle * speed * -0.5}px)`;
        });
        ticking = false;
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <>
      <GlobalAtmosphere />
      {t.spotlight && <CursorV3 />}
      <NavV3 />
      <HeroV3 />
      <ThemV3 />
      <WorksV3 onLightbox={setLb} />
      <PrintsV3 />
      <AboutV3 />
      <CommissionV3 />
      <FooterV3 />
      <LightboxV3 data={lb} onClose={() => setLb(null)} />

      <TweaksPanel>
        <TweakSection label="Palette" />
        <PaletteGridV3 value={t.palette} onChange={v => setTweak('palette', v)} />
        <TweakSection label="Atmosphere" />
        <TweakSlider label="Film grain" value={t.grain} min={0} max={1} step={0.05}
          onChange={v => setTweak('grain', v)} />
        <TweakToggle label="Cursor spotlight" value={t.spotlight}
          onChange={v => setTweak('spotlight', v)} />
      </TweaksPanel>
    </>
  );
}

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