// Hero — two-column: photo + identity card on left, bio on right.

const { useState: useStateHero, useEffect: useEffectHero, useRef: useRefHero } = React;

function Icon({ name }) {
  const ICONS = {
    scholar:
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M22 10v6M2 10l10-5 10 5-10 5z" />
        <path d="M6 12v5c3 2.5 9 2.5 12 0v-5" />
      </svg>,

    github:
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" />
      </svg>,

    x:
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
        <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
      </svg>,

    linkedin:
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
        <path d="M20.5 2h-17A1.5 1.5 0 0 0 2 3.5v17A1.5 1.5 0 0 0 3.5 22h17a1.5 1.5 0 0 0 1.5-1.5v-17A1.5 1.5 0 0 0 20.5 2zM8 19H5v-9h3zM6.5 8.25A1.75 1.75 0 1 1 8.3 6.5a1.78 1.78 0 0 1-1.8 1.75zM19 19h-3v-4.74c0-1.42-.6-1.93-1.38-1.93A1.74 1.74 0 0 0 13 14.19a.66.66 0 0 0 0 .14V19h-3v-9h2.9v1.3a3.11 3.11 0 0 1 2.7-1.4c1.55 0 3.36.86 3.36 3.66z" />
      </svg>,

    email:
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <rect x="3" y="5" width="18" height="14" rx="2" />
        <path d="m3 7 9 6 9-6" />
      </svg>,

    pin:
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M20 10c0 7-8 12-8 12s-8-5-8-12a8 8 0 0 1 16 0z" />
        <circle cx="12" cy="10" r="3" />
      </svg>,

    mail:
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <rect x="3" y="5" width="18" height="14" rx="2" />
        <path d="m3 7 9 6 9-6" />
      </svg>,

    speaker:
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M11 5 6 9H2v6h4l5 4z" />
        <path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
        <path d="M19.07 4.93a10 10 0 0 1 0 14.14" />
      </svg>

  };
  return ICONS[name] || null;
}

function Hero() {
  const [playingName, setPlayingName] = useStateHero(false);
  const [hasAudio, setHasAudio] = useStateHero(false);
  const audioRef = useRefHero(null);

  // Pre-load TTS voices so the Italian voice is available on first click.
  useEffectHero(() => {
    if (typeof window === "undefined" || !window.speechSynthesis) return;
    // calling getVoices() once triggers loading on some browsers
    window.speechSynthesis.getVoices();
    function onVoices() {/* keeps reference alive */}
    window.speechSynthesis.addEventListener("voiceschanged", onVoices);
    return () => window.speechSynthesis.removeEventListener("voiceschanged", onVoices);
  }, []);

  function pronounceName() {
    // Try the StreamElements TTS endpoint first (proper Italian voice).
    // IMPORTANT for mobile (esp. iOS Safari): call .play() synchronously
    // inside the user-gesture handler. Do NOT call .load() or set
    // currentTime first — those can break the gesture chain on iOS and
    // cause play() to reject silently.
    const el = audioRef.current;
    if (el) {
      try {
        // Try to rewind only if already started; ignore failures.
        try { if (el.currentTime > 0) el.currentTime = 0; } catch (_) {}
        const p = el.play();
        setPlayingName(true);
        if (p && typeof p.then === "function") {
          p.catch(() => { setPlayingName(false); fallbackToTTS(); });
        }
        return;
      } catch (e) {/* fall through to TTS */}
    }
    fallbackToTTS();
  }

  function fallbackToTTS() {
    if (typeof window === "undefined" || !window.speechSynthesis) return;
    try {
      window.speechSynthesis.cancel();
      const u = new SpeechSynthesisUtterance("Simone");
      u.lang = "it-IT";
      u.rate = 0.9;
      u.pitch = 1;
      // Pick the highest-quality Italian voice we can find.
      const voices = window.speechSynthesis.getVoices();
      const italian = voices.filter((v) => /^it(-|_)?/i.test(v.lang));
      // Prefer named-personality voices that tend to be higher quality (Alice on macOS, Federica, Luca, etc.)
      const preferred = italian.find((v) => /Alice|Federica|Luca|Paolo|Cosimo|Eloisa/i.test(v.name)) || italian[0];
      if (preferred) u.voice = preferred;
      u.onstart = () => setPlayingName(true);
      u.onend = () => setPlayingName(false);
      u.onerror = () => setPlayingName(false);
      window.speechSynthesis.speak(u);
    } catch (e) {
      setPlayingName(false);
    }
  }
  return (
    <header className="hero">
      <audio
        ref={audioRef}
        preload="auto"
        playsInline
        src="https://api.streamelements.com/kappa/v2/speech?voice=Giorgio&text=Simone"
        onCanPlay={() => setHasAudio(true)}
        onEnded={() => setPlayingName(false)}
        onError={() => {setHasAudio(false);setPlayingName(false);}} />
      
      <aside className="left">
        <div className="left-center">
          <div className="photo-wrap">
            <img src="assets/simone.jpeg" alt="Portrait of Simone Antonelli at Ytri Tunga beach, Iceland, with a seal in the background." />
            <div className="cap-default">
              <span>YTRI TUNGA · IS</span>
              <span>2022</span>
            </div>
            <div className="seal-bubble" aria-hidden="true">
              <span>blub</span>
            </div>
          </div>

          <div className="id">
            <div className="name">Simone Antonelli</div>
            <div className="role-line">
              <span className="role-eyebrow">Ph.D. candidate,</span>{" "}
              <a href="https://cispa.de" target="_blank" rel="noopener" className="role-org">CISPA</a>
            </div>
          </div>
        </div>

        <div className="contact-line">
          <span className="contact-item">
            <Icon name="pin" />
            <span>London, UK</span>
          </span>
          <span className="contact-item">
            <Icon name="mail" />
            <a href="mailto:simone[dot]antonelli[at]cispa[dot]de">simone[dot]antonelli[at]cispa[dot]de</a>
          </span>
        </div>
      </aside>

      <div className="right">
        <div className="bio">
          <p>
            Hey there! I’m <button
              type="button"
              className={"name-pronounce-text" + (playingName ? " is-playing" : "")}
              onClick={pronounceName}
              aria-label="Hear how to pronounce my name"
              title="Hear how to pronounce my name">Simone<sup className="pronounce-mark"><Icon name="speaker" /></sup></button>, a Ph.D. candidate at <a className="org-link" href="https://cispa.de" target="_blank" rel="noopener"><img className="org-favicon" src="https://www.google.com/s2/favicons?sz=64&domain=cispa.de" alt="" />CISPA Helmholtz Center for Information Security</a>, working with Aleksandar Bojchevski (<a href="https://cs.uni-koeln.de/tail" target="_blank" rel="noopener">Trustworthy Artificial Intelligence Lab</a>). I build tools for stress-testing large models and understanding what shapes their behavior.
          </p>
          <p>
            I’m particularly interested in <strong>LLM Safety</strong>, focusing on the attack surfaces opened by test-time training. I also work on <strong>Data-centric methods</strong> such as influence functions for data valuation, to help trace a model’s behavior back to its training data.
          </p>
          <p>
            I’m currently a student researcher at <a className="org-link" href="https://deepmind.google/" target="_blank" rel="noopener"><img className="org-favicon" src="https://www.google.com/s2/favicons?sz=64&domain=deepmind.google" alt="" />Google DeepMind</a> in London. Before that, I visited the <a className="org-link" href="https://caraml-group.github.io/" target="_blank" rel="noopener"><img className="org-favicon" src="https://github.com/caraml-group.png?size=128" alt="" />CaRAML group</a> at the University of Cambridge and interned at <a className="org-link" href="https://amboss.tech/" target="_blank" rel="noopener"><img className="org-favicon" src="https://www.google.com/s2/favicons?sz=64&domain=amboss.tech" alt="" />Amboss</a>. I completed both my B.Sc. and M.Sc. in Computer Science at Sapienza University of Rome, graduating with distinction as an outstanding graduate student.
          </p>
        </div>

        <div className="socials">
          <a href="https://scholar.google.com/citations?user=xzgqj2wAAAAJ" target="_blank" rel="noopener" aria-label="Google Scholar"><Icon name="scholar" /></a>
          <a href="https://github.com/siantonelli" target="_blank" rel="noopener" aria-label="GitHub"><Icon name="github" /></a>
          <a href="https://x.com/sntonelli" target="_blank" rel="noopener" aria-label="X"><Icon name="x" /></a>
          <a href="https://www.linkedin.com/in/siantonelli" target="_blank" rel="noopener" aria-label="LinkedIn"><Icon name="linkedin" /></a>
        </div>
      </div>
    </header>);

}

window.Hero = Hero;