/* global React */
const { useState, useEffect, useRef, useMemo, useLayoutEffect } = React;

// ─────────────────────────────────────────────────────────────────────────────
// PhotoBlock — placeholder for a real image. Subtle tonal block with mono index
// + caption. Switches tint by theme via CSS vars.
// ─────────────────────────────────────────────────────────────────────────────
function PhotoBlock({ photo, lang, ratio = '4 / 5', priority = false, label = true }) {
  const cap = photo[lang] || photo.en;
  // Deterministic "tone" jitter (-2..+2 lightness step) so blocks feel like
  // actual photographs, not flat tiles. Same id → same tone, every render.
  const tone = useMemo(() => {
    let h = 0;
    for (let i = 0; i < photo.id.length; i++) h = (h * 31 + photo.id.charCodeAt(i)) >>> 0;
    return (h % 5) - 2; // -2..+2
  }, [photo.id]);

  return (
    <figure className="photo" style={{ aspectRatio: ratio }} data-tone={tone} data-cat={photo.cat}>
      <div className="photo-fill" />
      {/* Faint diagonal stripes for "image" feel */}
      <svg className="photo-stripes" aria-hidden="true">
        <defs>
          <pattern id={`stripes-${photo.id}`} patternUnits="userSpaceOnUse" width="14" height="14" patternTransform="rotate(35)">
            <line x1="0" y1="0" x2="0" y2="14" stroke="currentColor" strokeWidth="0.6" />
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill={`url(#stripes-${photo.id})`} />
      </svg>

      {label && (
        <figcaption className="photo-cap">
          <span className="photo-num">{photo.id}</span>
          <span className="photo-name">{cap}</span>
        </figcaption>
      )}
    </figure>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Marquee — infinite, pauses on hover. Uses CSS animation with --marquee-dur.
// ─────────────────────────────────────────────────────────────────────────────
function Marquee({ children, dur = 40, reverse = false }) {
  const items = React.Children.toArray(children);
  return (
    <div className="marquee" aria-hidden="false">
      <div className="marquee-track" style={{ animationDuration: `${dur}s`, animationDirection: reverse ? 'reverse' : 'normal' }}>
        {items}
        {items}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Nav — sticky top bar with hamburger on mobile.
// ─────────────────────────────────────────────────────────────────────────────
function Nav({ route, setRoute, lang, setLang, theme, setTheme, t }) {
  const [open, setOpen] = useState(false);
  const links = [
    { id: 'portfolio', label: t.nav.portfolio },
    { id: 'about',     label: t.nav.about },
    { id: 'services',  label: t.nav.services },
    { id: 'contact',   label: t.nav.contact },
  ];
  const langs = ['en', 'ru', 'he'];

  function go(id) { setRoute(id); setOpen(false); }

  return (
    <header className="nav" data-open={open}>
      <div className="nav-inner">
        <a className="nav-logo" onClick={() => go('home')} aria-label="VLADI SOLO — home">
          <span className="logo-mark">VLADI<span className="logo-em">/</span>SOLO</span>
        </a>

        <nav className="nav-links" aria-label="primary">
          {links.map(l => (
            <a key={l.id}
               className={'nav-link' + (route === l.id ? ' is-active' : '')}
               onClick={() => go(l.id)}>
              {l.label}
              <span className="nav-link-rule" />
            </a>
          ))}
        </nav>

        <div className="nav-tools">
          <div className="lang-switch" role="group" aria-label="language">
            {langs.map((L, i) => (
              <React.Fragment key={L}>
                <button
                  className={'lang-btn' + (lang === L ? ' is-active' : '')}
                  onClick={() => setLang(L)}
                  aria-pressed={lang === L}>{L.toUpperCase()}</button>
                {i < langs.length - 1 && <span className="lang-dot" aria-hidden>·</span>}
              </React.Fragment>
            ))}
          </div>
          <button className="theme-btn"
                  onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
            {theme === 'dark' ? t.common.lightMode : t.common.darkMode}
          </button>
          <button className="nav-burger" onClick={() => setOpen(o => !o)} aria-expanded={open}
                  aria-label={open ? t.common.close : t.common.menu}>
            <span /><span /><span />
          </button>
        </div>
      </div>

      {/* Mobile drawer */}
      <div className="nav-drawer" hidden={!open}>
        {links.map(l => (
          <a key={l.id} onClick={() => go(l.id)} className="nav-drawer-link">{l.label}</a>
        ))}
        <div className="nav-drawer-tools">
          <div className="lang-switch">
            {langs.map((L, i) => (
              <React.Fragment key={L}>
                <button className={'lang-btn' + (lang === L ? ' is-active' : '')}
                        onClick={() => setLang(L)}>{L.toUpperCase()}</button>
                {i < langs.length - 1 && <span className="lang-dot" aria-hidden>·</span>}
              </React.Fragment>
            ))}
          </div>
          <button className="theme-btn" onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
            {theme === 'dark' ? t.common.lightMode : t.common.darkMode}
          </button>
        </div>
      </div>
    </header>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Footer
// ─────────────────────────────────────────────────────────────────────────────
function Footer({ t, route, setRoute, lang }) {
  const time = useNow(lang);
  return (
    <footer className="foot">
      <div className="foot-grid">
        <div className="foot-col foot-col-mark">
          <div className="foot-mark">VLADI<span className="logo-em">/</span>SOLO</div>
          <p className="foot-tag">
            <em>{t.footer.tagline}</em>
          </p>
        </div>
        <div className="foot-col">
          <div className="foot-eye">{t.contact.direct}</div>
          <a className="foot-link" href={`mailto:${t.contact.email_addr}`}>{t.contact.email_addr}</a>
          <a className="foot-link" href={`tel:${t.contact.phone.replace(/\s/g, '')}`}>{t.contact.phone}</a>
          <div className="foot-link foot-link-quiet">{t.contact.social}</div>
        </div>
        <div className="foot-col">
          <div className="foot-eye">{t.nav.portfolio}</div>
          {['portfolio','about','services','contact'].map(id => (
            <a key={id} className="foot-link" onClick={() => setRoute(id)}>{t.nav[id]}</a>
          ))}
        </div>
        <div className="foot-col foot-col-meta">
          <div className="foot-eye">Tel Aviv · {time}</div>
          <div className="foot-link foot-link-quiet">{t.common.based}</div>
        </div>
      </div>
      <div className="foot-rule" />
      <div className="foot-bottom">
        <span>{t.footer.rights}</span>
        <a onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })} className="foot-link">{t.common.backToTop} ↑</a>
      </div>
    </footer>
  );
}

// Live clock (hh:mm) for the chosen locale
function useNow(lang) {
  const [s, setS] = useState(() => fmt(new Date(), lang));
  useEffect(() => {
    const i = setInterval(() => setS(fmt(new Date(), lang)), 30 * 1000);
    return () => clearInterval(i);
  }, [lang]);
  return s;
  function fmt(d, l) {
    const locale = l === 'ru' ? 'ru-RU' : l === 'he' ? 'he-IL' : 'en-GB';
    try {
      return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit', timeZone: 'Asia/Jerusalem' }).format(d);
    } catch { return d.toTimeString().slice(0, 5); }
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// CursorBubble — small follow cursor on portfolio (editorial touch)
// Only active when prop `active` is true and pointer is inside container.
// ─────────────────────────────────────────────────────────────────────────────
function CursorBubble({ targetRef, label }) {
  const ref = useRef(null);
  const [show, setShow] = useState(false);
  useEffect(() => {
    const el = targetRef.current;
    if (!el) return;
    function move(e) {
      const b = ref.current;
      if (!b) return;
      b.style.transform = `translate3d(${e.clientX}px, ${e.clientY}px, 0) translate(-50%, -50%)`;
    }
    function enter() { setShow(true); }
    function leave() { setShow(false); }
    el.addEventListener('pointermove', move);
    el.addEventListener('pointerenter', enter);
    el.addEventListener('pointerleave', leave);
    return () => {
      el.removeEventListener('pointermove', move);
      el.removeEventListener('pointerenter', enter);
      el.removeEventListener('pointerleave', leave);
    };
  }, [targetRef]);
  return (
    <div ref={ref} className={'cursor-bubble' + (show ? ' is-on' : '')} aria-hidden="true">
      <span>{label}</span>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Page transition wrapper
// ─────────────────────────────────────────────────────────────────────────────
function PageFrame({ id, children }) {
  const [seen, setSeen] = useState(false);
  useLayoutEffect(() => {
    setSeen(false);
    const r = requestAnimationFrame(() => setSeen(true));
    return () => cancelAnimationFrame(r);
  }, [id]);
  return <main className={'page' + (seen ? ' is-in' : '')} key={id} data-page={id}>{children}</main>;
}

Object.assign(window, { PhotoBlock, Marquee, Nav, Footer, CursorBubble, PageFrame });
