/* archive.jsx — past events archive section + interactive primitives */

const { useState: useStateA, useEffect: useEffectA, useRef: useRefA } = React;

/* --- IntersectionObserver reveal hook (local copy; scopes are separate) --- */
function useReveal() {
  const ref = useRefA(null);
  useEffectA(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); } });
    }, { threshold: 0.18 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return ref;
}

/* --- Count-up number animation --- */
function CountUp({ end, duration = 1800, suffix = '', prefix = '', decimals = 0 }) {
  const [val, setVal] = useStateA(0);
  const ref = useRefA(null);
  const started = useRefA(false);
  useEffectA(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting && !started.current) {
          started.current = true;
          const start = performance.now();
          const tick = (t) => {
            const p = Math.min(1, (t - start) / duration);
            const eased = 1 - Math.pow(1 - p, 3);
            setVal(end * eased);
            if (p < 1) requestAnimationFrame(tick);
            else setVal(end);
          };
          requestAnimationFrame(tick);
          io.disconnect();
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [end, duration]);
  const formatted = decimals > 0 ? val.toFixed(decimals) : Math.round(val).toLocaleString('ru-RU');
  return <span ref={ref}>{prefix}{formatted}{suffix}</span>;
}

/* --- Tilt wrapper for cards --- */
function Tilt({ children, max = 6, className = '', style = {} }) {
  const ref = useRefA(null);
  const onMove = (e) => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width;
    const y = (e.clientY - r.top) / r.height;
    const rx = (0.5 - y) * max;
    const ry = (x - 0.5) * max;
    el.style.transform = `perspective(900px) rotateX(${rx}deg) rotateY(${ry}deg)`;
  };
  const onLeave = () => {
    if (ref.current) ref.current.style.transform = '';
  };
  return (
    <div ref={ref} className={className} style={{ transition: 'transform .35s cubic-bezier(.2,.7,.2,1)', willChange: 'transform', ...style }}
         onMouseMove={onMove} onMouseLeave={onLeave}>
      {children}
    </div>
  );
}

/* --- Magnetic button hook --- */
function useMagnetic(strength = 18) {
  const ref = useRefA(null);
  useEffectA(() => {
    const el = ref.current; if (!el) return;
    let raf;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const x = e.clientX - (r.left + r.width / 2);
      const y = e.clientY - (r.top + r.height / 2);
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        el.style.transform = `translate(${(x/r.width) * strength}px, ${(y/r.height) * strength}px)`;
      });
    };
    const onLeave = () => {
      cancelAnimationFrame(raf);
      el.style.transform = '';
    };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
    };
  }, [strength]);
  return ref;
}

/* --- Archive data --- */
const ARCHIVE = [
  { id:'AR-024', when:'Май 2026',  title:'Шаббат-ужин · Резиденция Альфаси', loc:'Кейсария',  guests:24, photos:38, scene:'scene-dinner',   size:'size-lg', cat:'Ужины',  desc:'Закрытый вечер в&nbsp;частной резиденции у&nbsp;моря. Шеф Эял Шани, разговор о&nbsp;поколениях капитала и&nbsp;о&nbsp;том, как&nbsp;дети наследуют не&nbsp;деньги, а&nbsp;этику.' },
  { id:'AR-023', when:'Апр 2026',  title:'Регата 24h · Хайфский залив',     loc:'Хайфа',       guests:18, photos:124, scene:'scene-sea',     size:'size-md', cat:'Спорт',  desc:'Три яхты, два дня, ночёвка под&nbsp;звёздами. Команды формируются жеребьёвкой — лучший способ узнать партнёра до&nbsp;подписания term sheet.' },
  { id:'AR-022', when:'Мар 2026',  title:'Винный салон · Долина Эла',       loc:'Иудейские горы', guests:32, photos:62, scene:'scene-vineyard', size:'size-md', cat:'Гастрономия', desc:'Резервные коллекции трёх виноделен. Авирам Кац открывает разговор о&nbsp;терруаре севера и&nbsp;инвестициях в&nbsp;винодельческий бизнес.' },
  { id:'AR-021', when:'Фев 2026',  title:'Открытие коллекции Шапиро',       loc:'Тель‑Авив',  guests:41, photos:89, scene:'scene-gallery', size:'size-sm', cat:'Культура', desc:'Приватный preview новой галереи Эстер Шапиро. Современное израильское искусство, разговор с&nbsp;куратором Тейт Модерн.' },
  { id:'AR-020', when:'Янв 2026',  title:'Пустынный завтрак · Махтеш Рамон', loc:'Негев',     guests:16, photos:47, scene:'scene-desert',  size:'size-sm', cat:'Путешествия', desc:'Восход в&nbsp;кратере, бедуинский завтрак, разговор о&nbsp;Негеве как&nbsp;следующей экономической границе Израиля.' },
  { id:'AR-019', when:'Дек 2025',  title:'Хануккальный приём · Старый город', loc:'Иерусалим', guests:52, photos:96, scene:'scene-jerusalem', size:'size-sm', cat:'Праздники', desc:'Восемь свечей, восемь спикеров, восемь историй о&nbsp;том, как свет переживает темноту. Закрытое мероприятие в&nbsp;Еврейском квартале.' },
  { id:'AR-018', when:'Ноя 2025',  title:'Tikkun Olam · вечер благотворения', loc:'Герцлия', guests:74, photos:148, scene:'scene-shabbat', size:'size-wide', cat:'Филантропия', desc:'Резиденты клуба собрали ₪4.2&nbsp;млн на&nbsp;программу образования для детей репатриантов. Спикер&nbsp;— президент Israel Education Fund.' },
];

const CATS = ['Все', 'Ужины', 'Гастрономия', 'Спорт', 'Культура', 'Путешествия', 'Праздники', 'Филантропия'];

/* --- Archive section --- */
function Archive() {
  const [filter, setFilter] = useStateA('Все');
  const [active, setActive] = useStateA(null); // selected event for lightbox
  const r = useReveal();

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

  useEffectA(() => {
    document.body.style.overflow = active ? 'hidden' : '';
  }, [active]);

  const items = filter === 'Все' ? ARCHIVE : ARCHIVE.filter(a => a.cat === filter);

  return (
    <section className="section" id="archive" data-screen-label="05 Archive">
      <div className="container">
        <div className="archive__head reveal" ref={r}>
          <div>
            <span className="eyebrow">§ 04 — Архив</span>
            <h2 className="display" style={{ marginTop: 18 }}>
              Что уже <em>было</em><br/>в&nbsp;этом году.
            </h2>
          </div>
          <p className="lead">
            Мы&nbsp;не&nbsp;публикуем фото в&nbsp;соцсетях — но&nbsp;архив открыт для тех, кто&nbsp;думает о&nbsp;вступлении. Семь моментов из&nbsp;двадцати четырёх событий 2025—2026.
          </p>
        </div>

        <div className="archive__filter reveal" ref={useReveal()} style={{ marginBottom: 'clamp(28px,3vw,44px)'}}>
          {CATS.map(c => (
            <button key={c} className={filter===c?'on':''} onClick={()=>setFilter(c)}>{c}</button>
          ))}
        </div>

        <div className="archive__grid">
          {items.map(a => (
            <ArchiveCard key={a.id} a={a} onOpen={()=>setActive(a)} />
          ))}
        </div>

        <div style={{ marginTop: 'clamp(40px,5vw,70px)', display:'flex', justifyContent:'space-between', alignItems:'center', gap:24, flexWrap:'wrap', paddingTop:24, borderTop:'1px solid var(--hairline)'}}>
          <div style={{ fontFamily:'var(--mono)', fontSize:11, letterSpacing:'.2em', color:'var(--ink-faint)', textTransform:'uppercase' }}>
            Полный архив доступен резидентам · 2019—2026
          </div>
          <a href="#join" className="uline" style={{ fontFamily:'var(--mono)', fontSize:11, letterSpacing:'.22em', textTransform:'uppercase' }}>
            Запросить доступ →
          </a>
        </div>
      </div>

      <Lightbox event={active} onClose={()=>setActive(null)} />
    </section>
  );
}

function ArchiveCard({ a, onOpen }) {
  return (
    <Tilt className={`arch-card ${a.size}`} max={4}>
      <div onClick={onOpen} style={{ position:'absolute', inset:0, zIndex:4, cursor:'pointer' }} />
      <div className="arch-photo">
        <div className={`scene ${a.scene}`} />
      </div>
      <div className="arch-frame"><span className="dot"/> FRAME {a.id}</div>
      <div className="arch-count">{a.photos} КАДРОВ</div>
      <div className="arch-meta">
        <div className="when">{a.when}</div>
        <div className="ttl" dangerouslySetInnerHTML={{__html: a.title}} />
        <div className="sub">
          <span>{a.loc}</span>
          <span>{a.guests} гостей</span>
        </div>
        <div className="open" aria-label="Открыть">
          <svg viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1">
            <path d="M3 9 L15 9 M9 3 L15 9 L9 15" />
          </svg>
        </div>
      </div>
    </Tilt>
  );
}

function Lightbox({ event, onClose }) {
  if (!event) {
    return <div className="lbox" onClick={onClose} />;
  }
  return (
    <div className={`lbox open`} onClick={onClose}>
      <div className="lbox__inner" onClick={(e)=>e.stopPropagation()}>
        <div className="lbox__image">
          <div className="arch-photo" style={{position:'absolute', inset:0}}>
            <div className={`scene ${event.scene}`} />
          </div>
          <div className="arch-frame"><span className="dot"/> FRAME {event.id}</div>
          <div className="arch-count">{event.photos} КАДРОВ</div>
          <button className="lbox__close" onClick={onClose} aria-label="Закрыть" />
        </div>
        <div className="lbox__body">
          <div className="lbox-when">{event.when} · {event.loc}</div>
          <h3>{event.title.replace(/&nbsp;/g, ' ')}</h3>
          <p dangerouslySetInnerHTML={{__html: event.desc}} />
          <div className="lbox-stats">
            <div><span className="n">{event.guests}</span><span className="l">Гостей</span></div>
            <div><span className="n">{event.photos}</span><span className="l">Фото в&nbsp;архиве</span></div>
            <div><span className="n">{event.cat}</span><span className="l">Категория</span></div>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Archive, CountUp, Tilt, useMagnetic });
