// All page sections, composing the localized CV data into UI.
const { useState, useEffect, useRef } = React;

// helper: render a title with the middle word(s) in italic-accent
const Title = ({ parts }) => {
  const [a, mid, b] = parts || ["", "", ""];
  return <React.Fragment>{a}<em>{mid}</em>{b}</React.Fragment>;
};

// helper: localized label for a talk link based on its kind
const linkCta = (item, data) => {
  const labels = (data.ui && data.ui.linkLabels) || {};
  const kind = item.linkKind || "open";
  return labels[kind] || labels.open || "Open";
};

// ────────────────────────────────── Nav ──────────────────────────────────
function Nav({ data }) {
  const [active, setActive] = useState("hero");
  useEffect(() => {
    const ids = ["about", "now", "experience", "skills", "wordson", "education", "awards", "talks", "hobbies", "contact"];
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.id); });
      },
      { rootMargin: "-50% 0% -40% 0%" }
    );
    ids.forEach((id) => {
      const el = document.getElementById(id);
      if (el) io.observe(el);
    });
    return () => io.disconnect();
  }, []);

  return (
    <nav className="nav" aria-label="Primary">
      <div className="wrap nav-inner">
        <span className="nav-location">{data.ui.based} {data.meta.location}</span>
        <div className="nav-right">
          <div className="nav-links">
            <a href="#about" className={active === "about" ? "active" : ""} aria-current={active === "about" ? "true" : undefined}>{data.ui.navAbout}</a>
            <a href="#experience" className={active === "experience" ? "active" : ""} aria-current={active === "experience" ? "true" : undefined}>{data.ui.navWork}</a>
            <a href="#contact" className={active === "contact" ? "active" : ""} aria-current={active === "contact" ? "true" : undefined}>{data.ui.navContact}</a>
          </div>
        </div>
      </div>
    </nav>
  );
}

// ────────────────────────────────── Hero ──────────────────────────────────
function Avatar({ tag }) {
  const ref = useRef(null);
  const target = useRef({ x: 0, y: 0, on: 0 });
  const cur = useRef({ x: 0, y: 0, on: 0 });
  const rafRef = useRef(0);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (window.matchMedia("(pointer: coarse)").matches) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const lerp = 0.09;
    const tick = () => {
      cur.current.x += (target.current.x - cur.current.x) * lerp;
      cur.current.y += (target.current.y - cur.current.y) * lerp;
      cur.current.on += (target.current.on - cur.current.on) * lerp;
      const { x, y, on } = cur.current;
      el.style.transform =
        `translateY(${-10 * on}px) scale(${1 + 0.025 * on}) perspective(1100px) ` +
        `rotateX(${-y * 9}deg) rotateY(${x * 9}deg)`;
      rafRef.current = requestAnimationFrame(tick);
    };
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      target.current.x = (e.clientX - r.left) / r.width - 0.5;
      target.current.y = (e.clientY - r.top) / r.height - 0.5;
      target.current.on = 1;
    };
    const leave = () => {
      target.current.x = 0;
      target.current.y = 0;
      target.current.on = 0;
    };
    el.addEventListener("mousemove", onMove);
    el.addEventListener("mouseleave", leave);
    rafRef.current = requestAnimationFrame(tick);
    return () => {
      el.removeEventListener("mousemove", onMove);
      el.removeEventListener("mouseleave", leave);
      cancelAnimationFrame(rafRef.current);
    };
  }, []);
  return (
    <div ref={ref} className="avatar">
      <img src="photo.jpg" alt="Portrait of Yurii Malna" />
      <span className="avatar-tag">{tag}</span>
    </div>
  );
}

function Hero({ data }) {
  const [role, setRole] = useState(0);
  useEffect(() => {
    setRole(0);
    const t = setInterval(() => setRole((r) => (r + 1) % data.hero.roles.length), 2400);
    return () => clearInterval(t);
  }, [data.hero.roles]);

  const nameParts = data.meta.name.split(" ");
  const first = nameParts[0];
  const rest = nameParts.slice(1).join(" ");

  return (
    <header id="hero" className="hero">
      <div className="wrap">
        <div className="hero-grid">
          <div>
            <h1 className="hero-name">
              <span>{first}</span>{rest && " "}
              {rest && <em className="lastname">{rest}</em>}
            </h1>
            <div className="hero-role">
              <span className="role-chip primary">{data.meta.title}</span>
              <span className="role-rotator" aria-live="polite">
                {data.ui.alsoReadsAs} <span key={role} className="swap">{data.hero.roles[role]}</span>
              </span>
            </div>
            <p className="hero-tagline" dangerouslySetInnerHTML={{ __html: data.hero.tagline }} />
            <div className="hero-actions">
              <Magnetic>
                <a className="btn btn-accent" href={data.meta.cvUrl} download data-cursor={data.ui.downloadCV}>
                  ↓ {data.ui.downloadCV} <span className="arrow" aria-hidden="true">↗</span>
                </a>
              </Magnetic>
              <Magnetic>
                <a className="btn btn-ghost" href={`mailto:${data.meta.email}`} data-cursor={data.ui.sayHello}>
                  {data.meta.email}
                </a>
              </Magnetic>
            </div>
          </div>
          <Avatar tag={data.ui.photoHere} />
        </div>
      </div>
    </header>
  );
}

// ────────────────────────────────── About ──────────────────────────────────
function About({ data }) {
  return (
    <section id="about" aria-labelledby="about-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectAbout}</span>
          <h2 id="about-title" className="section-title"><Title parts={data.ui.sectAboutTitle} /></h2>
        </div>
        <div className="about-prose reveal">
          <p className="lede" dangerouslySetInnerHTML={{ __html: data.about.lede }} />
          <div className="about-body">
            {data.about.paragraphs.map((p, i) => (
              <p key={i}>{p}</p>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Now ──────────────────────────────────
function Now({ data }) {
  const [time, setTime] = useState(new Date());
  useEffect(() => {
    const t = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(t);
  }, []);
  const utcHour = time.getUTCHours();
  const cetHour = (utcHour + 2) % 24;
  const fmt = `${String(cetHour).padStart(2,"0")}:${String(time.getUTCMinutes()).padStart(2,"0")}:${String(time.getUTCSeconds()).padStart(2,"0")} CET`;

  return (
    <section id="now" aria-labelledby="now-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectNow}</span>
          <h2 id="now-title" className="section-title"><Title parts={data.ui.sectNowTitle} /></h2>
        </div>
        <div className="now-card reveal">
          <div className="now-grid">
            <div className="now-item">
              <div className="lbl"><span className="pulse" aria-hidden="true" /> {data.ui.nowShipping}</div>
              <div className="val" dangerouslySetInnerHTML={{ __html: data.now.shipping }} />
            </div>
            <div className="now-item">
              <div className="lbl"><span className="pulse" aria-hidden="true" /> {data.ui.nowReading}</div>
              <div className="val" dangerouslySetInnerHTML={{ __html: data.now.reading }} />
            </div>
            <div className="now-item">
              <div className="lbl"><span className="pulse" aria-hidden="true" /> {data.ui.nowLearning}</div>
              <div className="val" dangerouslySetInnerHTML={{ __html: data.now.learning }} />
            </div>
            <div className="now-item">
              <div className="lbl"><span className="pulse" aria-hidden="true" /> {data.ui.nowObsessing}</div>
              <div className="val" dangerouslySetInnerHTML={{ __html: data.now.obsessing }} />
            </div>
          </div>
          <div className="now-meta">
            <span>{data.ui.nowLastEdited} · {time.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" })}</span>
            <span>{data.ui.nowLocal} · {fmt}</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Experience ──────────────────────────────────
function Experience({ data }) {
  const timeline = data.timeline.filter(forWeb);
  const primaryIdx = timeline.findIndex((j) => j.current && !j.parallel);
  const initialOpen = primaryIdx >= 0 ? primaryIdx : 0;
  const [open, setOpen] = useState(initialOpen);
  useEffect(() => { setOpen(initialOpen); }, [data.timeline]);

  const kindLabel = (k) => {
    switch (k) {
      case "employment": return data.ui.kindEmployment;
      case "consulting": return data.ui.kindConsulting;
      case "solo":       return data.ui.kindSolo;
      case "advisor":    return data.ui.kindAdvisor;
      default:           return null;
    }
  };

  const toggle = (i) => setOpen((cur) => (cur === i ? -1 : i));

  return (
    <section id="experience" aria-labelledby="experience-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectExp}</span>
          <h2 id="experience-title" className="section-title"><Title parts={data.ui.sectExpTitle} /></h2>
        </div>
        <div className="exp-list reveal">
          {timeline.map((job, i) => {
            const isOpen = i === open;
            const isPrimary = i === primaryIdx;
            const cls = [
              "exp-card",
              isOpen ? "open" : "",
              isPrimary ? "top" : "",
              job.parallel ? "parallel" : "",
              job.current ? "current" : "",
              `kind-${job.kind || "employment"}`,
            ].filter(Boolean).join(" ");
            return (
              <article key={i} className={cls}>
                <div
                  className="exp-head"
                  onClick={() => toggle(i)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggle(i); }
                  }}
                  role="button"
                  tabIndex={0}
                  data-cursor={isOpen ? data.ui.expCollapse : data.ui.expExpand}
                  aria-expanded={isOpen}
                >
                  <span className="exp-titles">
                    <span className="exp-role">
                      {job.parallel && <span className="exp-along" aria-hidden="true">↳ </span>}
                      {job.role}
                    </span>
                    <span className="exp-co">
                      {job.nda ? (
                        <span className="exp-nda">{data.ui.ndaLabel || "Under NDA"}</span>
                      ) : job.companyUrl ? (
                        <a
                          href={job.companyUrl}
                          target="_blank"
                          rel="noreferrer"
                          className="exp-co-link"
                          onClick={(e) => e.stopPropagation()}
                        >
                          {job.company}<span className="ext" aria-hidden="true">↗</span>
                        </a>
                      ) : (
                        <span>{job.company}</span>
                      )}
                      <span className="exp-dot" aria-hidden="true">·</span>
                      <span className="exp-dur">{job.duration}</span>
                    </span>
                  </span>
                  <span className="exp-tags">
                    {job.kind && kindLabel(job.kind) && (
                      <span className={`exp-kind kind-${job.kind}`}>{kindLabel(job.kind)}</span>
                    )}
                    {job.parallel && (
                      <span className="exp-along-pill">{data.ui.alongside}</span>
                    )}
                    {job.current && (
                      <span className="exp-now-pill">{data.ui.currentLabel}</span>
                    )}
                  </span>
                  <span className="exp-chev" aria-hidden="true">{isOpen ? "−" : "+"}</span>
                </div>
                <div className="exp-body" aria-hidden={!isOpen}>
                  <div className="exp-body-inner">
                    <p>{job.desc}</p>
                    <div className="role-tags">
                      {job.tags.map((t, k) => <span key={k} className="role-tag">{t}</span>)}
                    </div>
                    {job.projects && job.projects.filter(forWeb).length > 0 && (
                      <div className="exp-projects">
                        {job.projects.filter(forWeb).map((p, k) => (
                          <div key={k} className="exp-proj">
                            {p.title && <div className="ep-title">{p.title}</div>}
                            {p.desc && <p className="ep-desc">{p.desc}</p>}
                            {p.url && (
                              <a
                                href={p.url}
                                target="_blank"
                                rel="noreferrer"
                                className="ep-link"
                                onClick={(e) => e.stopPropagation()}
                              >
                                {p.linkLabel || "Open"}<span className="ext" aria-hidden="true">↗</span>
                              </a>
                            )}
                            {((p.tags && p.tags.length > 0) || (p.impact && p.impact.length > 0)) && (
                              <div className="ep-meta">
                                {p.tags && p.tags.map((t, j) => <span key={`t${j}`} className="ep-tag">{t}</span>)}
                                {p.impact && p.impact.map((it, j) => (
                                  <span key={`i${j}`} className="ep-impact-pill"><strong>{it.v}</strong> {it.k}</span>
                                ))}
                              </div>
                            )}
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                </div>
              </article>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Skills (static, grouped) ──────────────────────────────────
function SkillsCluster({ data }) {
  const cats = data.ui.stackOrder || ["leadership", "ai", "lang", "infra"];
  const labels = data.ui.stackCategories || {};
  const visibleSkills = data.skills.filter(forWeb);
  const grouped = cats
    .map((c) => ({ cat: c, label: labels[c] || c, items: visibleSkills.filter((s) => s.cat === c) }))
    .filter((g) => g.items.length > 0);

  return (
    <section id="skills" aria-labelledby="skills-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectStack}</span>
          <h2 id="skills-title" className="section-title"><Title parts={data.ui.sectStackTitle} /></h2>
        </div>

        {data.domains && data.domains.length > 0 && (
          <div className="domains-block reveal">
            <div className="domains-label">{data.ui.domainsLabel}</div>
            <div className="domains-row">
              {data.domains.map((d, i) => (
                <span key={i} className="domain-chip">{d}</span>
              ))}
            </div>
          </div>
        )}

        <div className="stack-label reveal">{data.ui.stackLabel}</div>
        <div className="stack-grid reveal">
          {grouped.map((g, gi) => (
            <div key={g.cat} className={`stack-group group-${g.cat}`}>
              <div className="stack-group-meta">
                <span className="stack-group-num">{String(gi + 1).padStart(2, "0")}</span>
                <span className="stack-group-label">{g.label}</span>
                <span className="stack-group-count">{g.items.length}</span>
              </div>
              <div className="stack-chips">
                {g.items.map((s, i) => (
                  <span key={s.name + i} className={`stack-chip cat-${g.cat}`}>
                    {s.name}
                  </span>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Education ──────────────────────────────────
function Education({ data }) {
  return (
    <section id="education" aria-labelledby="education-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectEdu}</span>
          <h2 id="education-title" className="section-title"><Title parts={data.ui.sectEduTitle} /></h2>
        </div>
        <div className="ed-list reveal">
          {data.education.filter(forWeb).map((e, i) => (
            <div className="ed-row" key={i}>
              <span className="ed-yr">{e.yr}</span>
              <span className="ed-deg">{e.deg}</span>
              <span className="ed-school">{e.school}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Awards ──────────────────────────────────
function Awards({ data }) {
  const items = (data.awards || []).filter(forWeb);
  if (items.length === 0) return null;
  return (
    <section id="awards" aria-labelledby="awards-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectAwards}</span>
          <h2 id="awards-title" className="section-title"><Title parts={data.ui.sectAwardsTitle} /></h2>
        </div>
        <div className="awards-list reveal">
          {items.map((a, i) => (
            <div className="award-row" key={i}>
              <span className="aw-yr">{a.yr}</span>
              <div className="aw-content">
                <div className="aw-title">{a.title}</div>
                {a.body && <div className="aw-body">{a.body}</div>}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Talks ──────────────────────────────────
function Talks({ data }) {
  return (
    <section id="talks" aria-labelledby="talks-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectTalks}</span>
          <h2 id="talks-title" className="section-title"><Title parts={data.ui.sectTalksTitle} /></h2>
        </div>
        <div className="talks-list reveal">
          {data.talks.filter(forWeb).map((t, i) => (
            <div className={`talk-row ${t.url ? "has-url" : ""}`} key={i}>
              <span className="t-yr">{t.yr}</span>
              <span className="t-title">
                {t.url ? (
                  <a href={t.url} target="_blank" rel="noreferrer">{t.title}</a>
                ) : (
                  <span>{t.title}</span>
                )}
                {t.em && <em>· {t.em}</em>}
                {t.url && (
                  <a
                    className="t-cta"
                    href={t.url}
                    target="_blank"
                    rel="noreferrer"
                    aria-label={`${linkCta(t, data)} - ${t.title}`}
                  >
                    · {linkCta(t, data)}<span className="arrow" aria-hidden="true">↗</span>
                  </a>
                )}
              </span>
              <span className="t-venue">{t.venue}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Hobbies ──────────────────────────────────
function Hobbies({ data }) {
  return (
    <section id="hobbies" aria-labelledby="hobbies-title">
      <div className="wrap">
        <div className="section-head reveal">
          <span className="section-tag">{data.ui.sectHobbies}</span>
          <h2 id="hobbies-title" className="section-title"><Title parts={data.ui.sectHobbiesTitle} /></h2>
        </div>
        <div className="hobby-grid reveal">
          {data.hobbies.filter(forWeb).map((h, i) => (
            <div className="hobby-card" key={i}>
              <div className="h-title">{h.title}</div>
              <div className="h-blurb">{h.blurb}</div>
              <div className="h-meta">
                {h.meta.map((m, j) => <span key={j}>· {m}</span>)}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Contact ──────────────────────────────────
function Contact({ data }) {
  return (
    <section id="contact" className="contact" aria-labelledby="contact-title">
      <div className="wrap">
        <div className="contact-card reveal">
          <span className="eyebrow" style={{ color: "var(--accent)" }}>{data.ui.sectContact}</span>
          <h2 id="contact-title" className="big" style={{ marginTop: 14 }}>
            {data.ui.contactBig[0]}<em>{data.ui.contactBig[1]}</em>
          </h2>
          <div className="contact-actions">
            <Magnetic>
              <a className="btn btn-accent" href={`mailto:${data.meta.email}`} data-cursor={data.ui.sayHello}>
                ✦ {data.ui.ctaSayHello} → <span className="arrow" aria-hidden="true">↗</span>
              </a>
            </Magnetic>
            {data.meta.phone && (
              <Magnetic>
                <a className="btn btn-ghost" href={`tel:${data.meta.phone.replace(/\s/g, "")}`} data-cursor={data.ui.ctaCall || "call"}>
                  ☎ {data.meta.phone}
                </a>
              </Magnetic>
            )}
            <Magnetic>
              <a className="btn" href={data.meta.socials.linkedin} target="_blank" rel="noreferrer" data-cursor="LinkedIn">{data.ui.ctaLinkedIn}</a>
            </Magnetic>
            <Magnetic>
              <a className="btn btn-ghost" href={data.meta.socials.github} target="_blank" rel="noreferrer" data-cursor="GitHub">⌨ {data.ui.ctaGithub}</a>
            </Magnetic>
            <Magnetic>
              <a className="btn btn-ghost" href={data.meta.cvUrl} download data-cursor="CV">↓ {data.ui.downloadCV}</a>
            </Magnetic>
          </div>
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────── Footer ──────────────────────────────────
function Footer({ data }) {
  return (
    <footer className="footer">
      <div className="wrap footer-inner">
        <span>© {new Date().getFullYear()} {data.meta.name} · {data.meta.domain}</span>
        <span className="legal">
          <span>{data.ui.footerHandmade}</span>
          <span aria-hidden="true">{data.ui.konamiHint}</span>
        </span>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Nav, Hero, About, Now, Experience, SkillsCluster,
  Education, Awards, Talks, Hobbies, Contact, Footer,
});
