// sections.jsx
// The menu and section windows: about / portfolio / contact / story.

(function () {
  const { useEffect, useState, useRef } = React;

  // ============================================================
  // TILE FRAME — perimeter border drawn by a running indicator
  // ============================================================
  // Normalized 100×100 path stretched over the tile (preserveAspectRatio
  // none). `start` corner + `dir` control where the pen begins and which
  // way it travels. A glowing dot rides the draw head via offset-path.
  const CORNERS = { TL: [0, 0], TR: [100, 0], BR: [100, 100], BL: [0, 100] };
  const CW = ['TL', 'TR', 'BR', 'BL'];

  function perimeterPath(start, dir) {
    let seq = dir === 'cw' ? [...CW] : [...CW].reverse();
    const i = seq.indexOf(start);
    seq = seq.slice(i).concat(seq.slice(0, i));
    seq.push(seq[0]); // close back to start
    return 'M' + seq.map(c => CORNERS[c].join(',')).join(' L');
  }

  function TileFrame({ start = 'TL', dir = 'cw', delay = 0 }) {
    const d = perimeterPath(start, dir);
    return (
      <svg className="tile__frame" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
        <path
          className="tile__frame-path"
          d={d}
          pathLength="100"
          style={{ animationDelay: `${delay}ms` }}
        ></path>
        <circle
          className="tile__frame-dot"
          r="1.6"
          style={{ offsetPath: `path('${d}')`, animationDelay: `${delay}ms` }}
        ></circle>
      </svg>
    );
  }

  // ============================================================
  // BSOD — Win98/ME-era blue screen joke for dead links
  // ============================================================
  function Bsod({ onClose }) {
    const { t } = useLang();
    useEffect(() => {
      window.Audio && window.Audio.blip(140);
      function onKey(e) { e.preventDefault(); onClose(); }
      window.addEventListener('keydown', onKey);
      return () => window.removeEventListener('keydown', onKey);
    }, [onClose]);
    return (
      <div className="bsod" onClick={onClose}>
        <div className="bsod__inner">
          <div className="bsod__title">ÐYSBALANS</div>
          <p>{t('bsod_p1')}</p>
          <p dangerouslySetInnerHTML={{ __html: t('bsod_p2') }}></p>
          <p className="bsod__wait">{t('bsod_wait')}</p>
        </div>
      </div>
    );
  }

  // ============================================================
  // MENU — section selector
  // ============================================================
  function Menu({ onOpen }) {
    const { t } = useLang();
    useEffect(() => {
      function onKey(e) {
        if (e.key === '1') onOpen('about');
        else if (e.key === '2') onOpen('portfolio');
        else if (e.key === '3') onOpen('contact');
        else if (e.key === '4') onOpen('story');
      }
      window.addEventListener('keydown', onKey);
      return () => window.removeEventListener('keydown', onKey);
    }, [onOpen]);

    function open(id) {
      window.Audio && window.Audio.woosh();
      onOpen(id);
    }

    return (
      <div className="view">
        <div className="menu">
          <div className="menu__head">
            <RevealText tag="h2" speed={36} startDelay={150}
              html={t('menu_head')} />
          </div>

          <button className="tile" onClick={() => open('about')}
                  onMouseEnter={() => window.Audio && window.Audio.tick()}>
            <TileFrame start="BR" dir="cw" delay={200} />
            <span className="tile__num">01 / SYS.ABOUT</span>
            <span className="tile__corner">[1]</span>
            <span className="tile__label"><ScrambleText text={t('tile_about')} /></span>
            <span className="tile__desc">{t('tile_about_sub')}</span>
          </button>

          <button className="tile" onClick={() => open('portfolio')}
                  onMouseEnter={() => window.Audio && window.Audio.tick()}>
            <TileFrame start="BR" dir="ccw" delay={320} />
            <span className="tile__num">02 / SYS.PORTFOLIO</span>
            <span className="tile__corner">[2]</span>
            <span className="tile__label"><ScrambleText text={t('tile_portfolio')} /></span>
            <span className="tile__desc">{t('tile_portfolio_sub')}</span>
          </button>

          <button className="tile" onClick={() => open('contact')}
                  onMouseEnter={() => window.Audio && window.Audio.tick()}>
            <TileFrame start="TR" dir="cw" delay={440} />
            <span className="tile__num">03 / SYS.CONTACT</span>
            <span className="tile__corner">[3]</span>
            <span className="tile__label"><ScrambleText text={t('tile_contact')} /></span>
            <span className="tile__desc tile__desc--lock">
              <svg className="lock-ico" viewBox="0 0 24 24" aria-hidden="true">
                <rect x="5" y="11" width="14" height="9" rx="1"></rect>
                <path d="M8 11V8a4 4 0 0 1 8 0v3"></path>
              </svg>
              {t('tile_contact_sub')}
            </span>
          </button>

          <button className="tile tile--feature" onClick={() => open('story')}
                  onMouseEnter={() => window.Audio && window.Audio.tick()}>
            <TileFrame start="TL" dir="ccw" delay={560} />
            <span className="tile__num">04 / SYS.STORY</span>
            <span className="tile__corner">[4]</span>
            <span className="tile__label tile__label--syn"><ScrambleText text="2226" /></span>
            <span className="tile__desc">{t('tile_story_sub')}</span>
          </button>

          <div className="menu__slogan">
            {t('menu_slogan').map((part, i) => <span key={i}>{part}</span>)}
          </div>
        </div>
      </div>
    );
  }

  // ============================================================
  // WINDOW shell
  // ============================================================
  function Window({ title, code, onClose, children, lights = true, wide = false, actions = null }) {
    const { t } = useLang();
    useEffect(() => {
      function onKey(e) {
        if (e.key === 'Escape') {
          e.preventDefault();
          window.Audio && window.Audio.blip(440);
          onClose();
        }
      }
      window.addEventListener('keydown', onKey);
      return () => window.removeEventListener('keydown', onKey);
    }, [onClose]);

    return (
      <div className="view">
        <div className={`window ${wide ? 'window--wide' : ''}`}>
          <div className="window__bar">
            <span className="window__title">{title}</span>
            <div className="window__actions">
              {actions}
              <button className="window__close" onClick={onClose}>{t('win_close')}</button>
            </div>
          </div>
          <div className="window__body">
            {children}
          </div>
        </div>
      </div>
    );
  }

  // ============================================================
  // ABOUT
  // ============================================================
  // Holographic origami unicorn (Gaff's, Blade Runner). Vector — so it tilts
  // toward the cursor with pure CSS 3D, no photo-depth calibration. Clicking it
  // doesn't scramble; it routes to the "it's a shame…" screen.
  function HoloUnicorn() {
    const hostRef = useRef(null);   // SVG injection target (gets tilted)
    const wrapRef = useRef(null);   // pointer-tracking surface

    // inject the unicorn SVG once (cached on window like the eagle)
    useEffect(() => {
      const host = hostRef.current;
      if (!host) return;
      function decorate() {
        const svg = host.querySelector('svg');
        if (!svg) return;
        // amber→red holographic duotone gradient (the path carries an inline
        // fill:white, so we also force fill via !important in CSS)
        if (!svg.querySelector('#holoGrad')) {
          svg.insertAdjacentHTML('afterbegin',
            '<defs><linearGradient id="holoGrad" x1="0" y1="0" x2="0" y2="1" gradientUnits="objectBoundingBox">' +
            '<stop offset="0" stop-color="#ffce4a"/>' +
            '<stop offset="0.55" stop-color="#f2af0d"/>' +
            '<stop offset="1" stop-color="#a90000"/>' +
            '</linearGradient></defs>');
        }
      }
      if (window.__unicornSvg) { host.innerHTML = window.__unicornSvg; decorate(); return; }
      let cancelled = false;
      fetch(window.__res('unicorn', 'assets/art/unicorn.svg'))
        .then((r) => r.text())
        .then((txt) => { if (!cancelled) { window.__unicornSvg = txt; host.innerHTML = txt; decorate(); } })
        .catch(() => {});
      return () => { cancelled = true; };
    }, []);

    // gentle 3D sway toward the cursor, smoothed with rAF lerp
    useEffect(() => {
      const host = hostRef.current;
      if (!host) return;
      let raf = 0;
      let tx = 0, ty = 0;       // target rot
      let cx = 0, cy = 0;       // current rot
      const MAX = 14;           // deg
      function onMove(e) {
        const w = window.innerWidth, h = window.innerHeight;
        tx = ((e.clientX / w) - 0.5) * 2 * MAX;       // rotateY
        ty = -((e.clientY / h) - 0.5) * 2 * MAX;      // rotateX
      }
      function tick() {
        cx += (tx - cx) * 0.06;
        cy += (ty - cy) * 0.06;
        host.style.transform =
          `rotateX(${cy.toFixed(2)}deg) rotateY(${cx.toFixed(2)}deg)`;
        raf = requestAnimationFrame(tick);
      }
      window.addEventListener('pointermove', onMove);
      raf = requestAnimationFrame(tick);
      return () => { window.removeEventListener('pointermove', onMove); cancelAnimationFrame(raf); };
    }, []);

    function enter() {
      if (window.Audio && window.Audio.isEnabled && window.Audio.isEnabled()) {
        window.Audio.woosh && window.Audio.woosh();
      }
      // brief fade so the jump isn't jarring
      document.body.style.transition = 'opacity 0.45s ease';
      document.body.style.opacity = '0';
      setTimeout(() => { window.location.href = 'shame.html'; }, 460);
    }

    return (
      <button
        className="holo-unicorn"
        ref={wrapRef}
        onClick={enter}
        aria-label="origami"
        title="◇"
      >
        <span className="holo-unicorn__float">
          <span className="holo-unicorn__svg" ref={hostRef}></span>
        </span>
      </button>
    );
  }

  function About({ onClose }) {
    const { t } = useLang();
    return (
      <Window title={t('win_about')} onClose={onClose} lights={false}>
        <div className="about">
          <div className="about__holo">
            <HoloUnicorn />
            <span className="about__serial" aria-hidden="true">B26354</span>
            <span className="about__holo-c about__holo-c--tl"></span>
            <span className="about__holo-c about__holo-c--tr"></span>
            <span className="about__holo-c about__holo-c--br"></span>
            <span className="about__holo-c about__holo-c--bl"></span>
          </div>
          <div className="about__copy">
            <h3 dangerouslySetInnerHTML={{ __html: t('about_h3') }}></h3>
            <p dangerouslySetInnerHTML={{ __html: t('about_p1') }}></p>
            <p className="about__tears" aria-hidden="true">All those moments will be lost in time, like tears in rain.</p>
            <p>{t('about_p2')}</p>
            <p className="about__cta" dangerouslySetInnerHTML={{ __html: t('about_p3') }}></p>
            <div className="about__tags">
              {t('about_tags').map((tag) => <span key={tag}>{tag}</span>)}
            </div>
          </div>
        </div>
      </Window>
    );
  }

  // ============================================================
  // PORTFOLIO
  // ============================================================
  function Portfolio({ onClose }) {
    const { t } = useLang();
    const [bsod, setBsod] = useState(false);
    const projects = t('pf_full');

    if (bsod) return <Bsod onClose={() => setBsod(false)} />;

    return (
      <Window title={t('win_portfolio')} onClose={onClose}>
        <div className="portfolio">
          <div className="portfolio__intro"
               dangerouslySetInnerHTML={{ __html: t('pf_status_intro').replace('{n}', projects.length) }}>
          </div>
          <div className="portfolio__grid">
            {projects.map((p) => (
              <div
                className={`project ${p.locked ? 'project--locked' : ''} ${p.url ? 'project--link' : ''}`}
                key={p.num} data-clickable
                onClick={() => {
                  if (p.locked) { setBsod(true); return; }
                  if (p.url) {
                    if (window.Audio && window.Audio.isEnabled()) window.Audio.woosh();
                    window.open(p.url, '_blank', 'noopener,noreferrer');
                  }
                }}
                onMouseEnter={() => window.Audio && window.Audio.tick()}
              >
                <div className="project__head">
                  <span className="project__num">{p.num}</span>
                  <span className={`project__status ${p.locked ? 'project__status--locked' : ''}`}>
                    {p.status}
                  </span>
                </div>
                <div className="project__title">
                  {p.title}{p.url && <span className="project__arrow"><svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true" focusable="false"><path d="M5 11L11 5M11 5H6M11 5V10" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="square"/></svg></span>}
                </div>
                <div className="project__meta">{p.meta}</div>
                <div className="project__bar"></div>
              </div>
            ))}
          </div>
        </div>
      </Window>
    );
  }

  // ============================================================
  // STORY — 2226 intro crawl (Blade Runner homage)
  // ============================================================
  // System typography. Tab indentation preserved. Text reveals behind a
  // travelling caret at a tweakable speed. "III Wojnę Światową" burns red
  // in Nippo (the easter-egg nod to Blade Runner's red "replicants").
  const STORY_HTML =
`\tU schyłku 2027 roku, pomniejsze konflikty rozprzestrzenione po całym globie, ostatecznie przerodziły się w pełnoskalową, <span class="story-hot">III Wojnę Światową.</span>
Fizyka kwantowa, SI i technologia fuzji jądrowej — rozwijające się w tempie geometrycznym — stały się instrumentami Nowego Imperium Sowieckiego, wymierzonymi przeciwko ludzkości. Dywersanci zaatakowali CERN i ośrodki programu ITER i EAST, doprowadzając do katastrofy na biblijną skalę.

\tW wyniku uszkodzeń reaktorów jądrowych i TOKAMAK, w atmosferze utworzyły się Osobliwości, które zmiotły z powierzchni ziemi 95% życia i ludzkiej infrastruktury.

\tPo 200 latach, nieliczni, którym udało się schować głęboko pod ziemią, utworzyli na zgliszczach dawnej cywilizacji nowe społeczeństwo, podejmujące trud odbudowy świata.

\tChaos, który ogarnął glob, pozwolił wyjść z cienia tym, którzy dotychczas nie uczestniczyli w projektowaniu świata.

\tTak, zaczęła się nowa era.
\tEra ĐysBalans(u).`;

  function Story({ onClose, speed = 26, audioOn = true }) {
    const { t } = useLang();
    const audioRef = useRef(null);
    const [done, setDone] = useState(false);
    const scrollRef = useRef(null);

    // Easter egg: "I'm afraid I can't let you do that." Block copying the intro
    // text — intercept the copy event (covers Ctrl/Cmd+C, menu, right-click) and
    // play the HAL clip instead of letting the text reach the clipboard.
    useEffect(() => {
      const node = scrollRef.current;
      if (!node) return;
      function onCopy(e) {
        e.preventDefault();
        if (e.clipboardData) e.clipboardData.setData('text/plain', '');
        window.Audio && window.Audio.playSample('imafraid');
      }
      node.addEventListener('copy', onCopy);
      return () => node.removeEventListener('copy', onCopy);
    }, []);

    // Standalone score: silence the site ambient while on 2226. On exit, ask the
    // engine to resume — it restarts the bed only if SFX is globally enabled,
    // so ambient comes back on main regardless of what happened on 2226.
    useEffect(() => {
      if (window.Audio && window.Audio.suspendAmbient) window.Audio.suspendAmbient();
      return () => {
        if (window.Audio && window.Audio.resumeAmbient) window.Audio.resumeAmbient();
      };
    }, []);

    // Fixed playback level for the standalone score (the on-screen volume knob
    // was removed — unusable on touch and it broke the mobile layout viewport).
    useEffect(() => {
      if (audioRef.current) audioRef.current.volume = 0.5;
    }, []);

    // Play / pause the score with the SCORE toggle; default ON. If the browser
    // blocks autoplay, retry on the next user gesture.
    useEffect(() => {
      const el = audioRef.current;
      if (!el) return;
      if (audioOn) {
        el.play().catch(() => {
          const retry = () => { el.play().catch(() => {}); document.removeEventListener('pointerdown', retry); };
          document.addEventListener('pointerdown', retry, { once: true });
        });
      } else {
        el.pause();
      }
    }, [audioOn]);

    const srcWebm = (window.__res ? window.__res('story2226Webm', 'assets/audio/story-2226.webm') : 'assets/audio/story-2226.webm');
    const srcMp3 = (window.__res ? window.__res('story2226Mp3', 'assets/audio/story-2226.mp3') : 'assets/audio/story-2226.mp3');

    return (
      <Window title={t('win_story')} onClose={onClose} wide={true}>
        <div className="story">
          <audio ref={audioRef} preload="auto" playsInline>
            <source src={srcWebm} type="audio/webm" />
            <source src={srcMp3} type="audio/mpeg" />
          </audio>
          <div className="story__scroll" ref={scrollRef}>
            <RevealText
              tag="div"
              className="story__crawl"
              html={t('story_html')}
              speed={speed}
              startDelay={500}
              onDone={() => setDone(true)}
            />

            <div className={`story__cta ${done ? 'is-visible' : ''}`}>
              <div className="story__cta-line">{t('story_cta_line')}</div>
              <a className="story__buy" href="#" onClick={(e) => e.preventDefault()} data-clickable>
                {t('story_buy')}
                <svg className="arrow-ne" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" focusable="false">
                  <path d="M5 11L11 5M11 5H6M11 5V10" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="square"/>
                </svg>
              </a>
              <div className="story__cta-sub">{t('story_cta_sub')}</div>
            </div>
          </div>
        </div>
      </Window>
    );
  }

  // ============================================================
  // CONTACT
  // ============================================================
  function Contact({ onClose, email }) {
    const { t } = useLang();
    const [copied, setCopied] = useState(false);

    function copy() {
      // Play synchronously inside the gesture — calling it from the
      // clipboard.writeText().then() callback runs AFTER the gesture and the
      // autoplay policy blocks it (that's why it only worked via mailto).
      window.Audio && window.Audio.playSample('cells');
      navigator.clipboard.writeText(email).then(() => {
        setCopied(true);
        setTimeout(() => setCopied(false), 1800);
      }).catch(() => {});
    }

    return (
      <Window title={t('win_contact')} onClose={onClose}>
        <div className="contact">
          <div className="contact__label">{t('contact_label')}</div>

          <div className="contact__email-row">
            <a href={`mailto:${email}`} className="contact__email"
               onClick={() => window.Audio && window.Audio.playSample('cells')}>{email}</a>
            <button
              className={`contact__copy ${copied ? 'is-copied' : ''}`}
              onClick={copy}
            >
              {copied ? t('contact_copied') : t('contact_copy')}
            </button>
          </div>

          <div className="contact__channels">
            <a className="contact__channel" href="https://www.instagram.com/dysbalans.studio/" target="_blank" rel="noopener noreferrer"><ScrambleText text="instagram" /></a>
            <a className="contact__channel" href="https://www.behance.net/dysbalans" target="_blank" rel="noopener noreferrer"><ScrambleText text="behance" /></a>
          </div>

          <div className="contact__sig">
            {t('contact_sig1')}<br />
            {t('contact_sig2')}
          </div>
        </div>
      </Window>
    );
  }

  Object.assign(window, { Menu, About, Portfolio, Contact, Story, Bsod, TileFrame });
})();
