/* Page components — Home, About, Projects, Blog, Contact */

const MEDIUM_URL = "https://medium.com/@upadhyaykavy";
const MEDIUM_RSS = "https://medium.com/feed/@upadhyaykavy";

function stripHtml(html) {
  const tmp = document.createElement("div");
  tmp.innerHTML = html || "";
  return (tmp.textContent || tmp.innerText || "").replace(/\s+/g, " ").trim();
}
function truncate(s, n) {
  if (!s) return "";
  return s.length > n ? s.slice(0, n - 1).trimEnd() + "…" : s;
}
function fmtDate(iso) {
  if (!iso) return "";
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return "";
  return d.toLocaleDateString("en-US", { month: "short", year: "numeric" });
}

function useMediumPosts() {
  const [state, setState] = React.useState({
    status: "loading",
    posts: [],
    error: null,
  });
  React.useEffect(() => {
    let cancelled = false;
    const url =
      "https://api.rss2json.com/v1/api.json?rss_url=" +
      encodeURIComponent(MEDIUM_RSS);
    fetch(url)
      .then((r) => r.json())
      .then((data) => {
        if (cancelled) return;
        if (data.status !== "ok" || !Array.isArray(data.items)) {
          throw new Error(data.message || "Bad response");
        }
        const posts = data.items.map((it, i) => ({
          id: it.guid || it.link || String(i),
          title: it.title || "Untitled",
          desc: truncate(stripHtml(it.description), 130),
          date: fmtDate(it.pubDate),
          href: it.link,
        }));
        setState({ status: "ok", posts, error: null });
      })
      .catch((err) => {
        if (cancelled) return;
        setState({
          status: "error",
          posts: [],
          error: err.message || String(err),
        });
      });
    return () => {
      cancelled = true;
    };
  }, []);
  return state;
}

function BlogRow({ b, n }) {
  const Tag = b.href ? "a" : "div";
  const extra = b.href
    ? { href: b.href, target: "_blank", rel: "noreferrer" }
    : {};
  return (
    <Tag className="blog-row" {...extra}>
      <span className="blog-num">{String(n).padStart(2, "0")}</span>
      <span className="blog-title">{b.title}</span>
      <span className="blog-desc">{b.desc}</span>
      <span className="blog-date">{b.date}</span>
    </Tag>
  );
}

function BlogState({ status, error, empty }) {
  if (status === "loading") {
    return <div className="blog-state loading">Loading posts from Medium…</div>;
  }
  if (status === "error") {
    return (
      <div className="blog-state error">
        Couldn’t reach the Medium feed{error ? ` (${error})` : ""}.{" "}
        <a href={MEDIUM_URL} target="_blank" rel="noreferrer">
          Read on Medium ↗
        </a>
      </div>
    );
  }
  if (empty) {
    return (
      <div className="blog-state empty">
        No posts yet.{" "}
        <a href={MEDIUM_URL} target="_blank" rel="noreferrer">
          Follow on Medium ↗
        </a>
      </div>
    );
  }
  return null;
}

function Home({ go }) {
  const { status, posts, error } = useMediumPosts();
  const featured = posts.slice(0, 3);
  return (
    <div className="page page-enter">
      <section className="hero">
        <div className="hero-stage">
          <div className="hero-shine"></div>
          <div className="hero-shine second"></div>
          <div className="hero-core"></div>
        </div>
        <div className="hero-content">
          <span className="hero-eyebrow">
            <span className="pulse"></span>
            PORTFOLIO / 2026
          </span>
          <h1 className="shimmer">
            Exploring
            <br />
            order in chaos.
          </h1>
          <p className="hero-sub">
            I'm <strong>Kavy Upadhyay</strong> — I build systems, write about
            the patterns I find, and ship small tools that try to be precise
            about messy problems.
          </p>
          <div className="hero-actions">
            <a
              className="btn primary"
              href="#/projects"
              onClick={(e) => {
                e.preventDefault();
                go("projects");
              }}
            >
              See projects{" "}
              <span className="arrow">
                <ArrowIcon />
              </span>
            </a>
            <a
              className="btn"
              href="#/contact"
              onClick={(e) => {
                e.preventDefault();
                go("contact");
              }}
            >
              Get in touch <ArrowUpRight />
            </a>
          </div>

          <div className="tag-strip">
            <span className="tag">SYSTEMS</span>
            <span className="tag bullet">·</span>
            <span className="tag">DEVTOOLS</span>
            <span className="tag bullet">·</span>
            <span className="tag">INTERFACES</span>
            <span className="tag bullet">·</span>
            <span className="tag">WRITING</span>
            <span className="tag bullet">·</span>
            <span className="tag">RESEARCH</span>
          </div>
        </div>
      </section>

      <section className="section" style={{ paddingTop: 80 }}>
        <header className="section-head">
          <div className="left">
            <Eyebrow>Selected work</Eyebrow>
            <h2>Recent projects</h2>
          </div>
          <a
            className="right"
            href="#/projects"
            onClick={(e) => {
              e.preventDefault();
              go("projects");
            }}
          >
            VIEW ALL →
          </a>
        </header>
        <div className="projects">
          {FEATURED_PROJECTS.map((p) => (
            <ProjectCard key={p.id} p={p} />
          ))}
        </div>
      </section>

      <section className="section" style={{ paddingTop: 56 }}>
        <header className="section-head">
          <div className="left">
            <Eyebrow>Field notes</Eyebrow>
            <h2>Latest writing</h2>
          </div>
          <a
            className="right"
            href="#/blog"
            onClick={(e) => {
              e.preventDefault();
              go("blog");
            }}
          >
            ALL POSTS →
          </a>
        </header>
        <div className="blog-list">
          {featured.map((b, i) => (
            <BlogRow key={b.id} b={b} n={i + 1} />
          ))}
          <BlogState
            status={status}
            error={error}
            empty={status === "ok" && featured.length === 0}
          />
        </div>
      </section>
    </div>
  );
}

function About() {
  return (
    <div className="page page-enter">
      <header style={{ marginBottom: 56 }}>
        <Eyebrow>About</Eyebrow>
        <h1
          className="shimmer"
          style={{
            fontFamily: "var(--font-display)",
            fontSize: "clamp(48px, 8vw, 112px)",
            letterSpacing: "-0.04em",
            lineHeight: 0.95,
            fontWeight: 500,
            margin: "24px 0 0",
          }}
        >
          A short
          <br />
          introduction.
        </h1>
      </header>

      <div className="about-grid">
        <div className="about-prose">
          <p>
            I'm Kavy — an engineer who likes the part of a problem where it
            stops looking like a problem and starts looking like a system. Most
            of what I do is some flavour of that: take an unclear problem, a
            tangled idea, a vague brief, and turn it into something with clear
            edges.
          </p>
          <p className="muted">
            Outside of building, I dance. Mostly flavors of latin–salsa,
            bachata, tango, whatever feels more fun that week. The thread tying
            everything together is an attempt to bring that order in something
            so free and chaotic by design.
          </p>
          <p className="muted">
            Currently based on the internet. Open to collaborations on quant
            projects, ML research, adventure(?).
          </p>
        </div>

        <div className="facts">
          <div className="fact">
            <div className="label">Based</div>
            <div className="value">Helsinki · EU</div>
          </div>
          <div className="fact">
            <div className="label">Status</div>
            <div className="value">Inspired</div>
          </div>
          <div className="fact">
            <div className="label">Focus</div>
            <div className="value">Quantum · ML · Finance</div>
          </div>
          <div className="fact">
            <div className="label">Stack</div>
            <div className="value">Python · Rust</div>
          </div>
        </div>
      </div>

      <section style={{ marginTop: 80 }}>
        <Eyebrow>Trajectory</Eyebrow>
        <div className="timeline">
          {TIMELINE.map((t, i) => (
            <div className="tl-item" key={i}>
              <span className="tl-year">{t.year}</span>
              <div className="tl-body">
                <div className="title">{t.title}</div>
                <div className="desc">{t.desc}</div>
              </div>
              <span className="tl-tag">{t.tag}</span>
            </div>
          ))}
        </div>
      </section>
    </div>
  );
}

function Projects() {
  return (
    <div className="page page-enter">
      <header style={{ marginBottom: 48 }}>
        <Eyebrow>Projects</Eyebrow>
        <h1
          className="shimmer"
          style={{
            fontFamily: "var(--font-display)",
            fontSize: "clamp(48px, 8vw, 112px)",
            letterSpacing: "-0.04em",
            lineHeight: 0.95,
            fontWeight: 500,
            margin: "24px 0 16px",
          }}
        >
          Things I've built.
        </h1>
        <p
          style={{
            maxWidth: 560,
            color: "var(--muted)",
            fontSize: 16,
            lineHeight: 1.6,
            margin: 0,
          }}
        >
          A mix of shipped products, experiments, and the occasional weekend
          project that got out of hand. Hover for a closer look.
        </p>
      </header>

      <div className="projects">
        {PROJECTS.map((p) => (
          <ProjectCard key={p.id} p={p} />
        ))}
      </div>
    </div>
  );
}

function Blog() {
  const { status, posts, error } = useMediumPosts();
  return (
    <div className="page page-enter">
      <header style={{ marginBottom: 48 }}>
        <Eyebrow>Writing · Medium</Eyebrow>
        <h1
          className="shimmer"
          style={{
            fontFamily: "var(--font-display)",
            fontSize: "clamp(48px, 8vw, 112px)",
            letterSpacing: "-0.04em",
            lineHeight: 0.95,
            fontWeight: 500,
            margin: "24px 0 16px",
          }}
        >
          Notes &amp; essays.
        </h1>
        <p
          style={{
            maxWidth: 560,
            color: "var(--muted)",
            fontSize: 16,
            lineHeight: 1.6,
            margin: 0,
          }}
        >
          Pulled live from{" "}
          <a
            href={MEDIUM_URL}
            target="_blank"
            rel="noreferrer"
            style={{
              color: "var(--ink-2)",
              textDecoration: "underline",
              textUnderlineOffset: 3,
            }}
          >
            medium.com/@upadhyaykavy
          </a>{" "}
          — short pieces about software, systems, and the patterns I keep
          noticing.
        </p>
      </header>

      <div className="blog-list">
        {posts.map((b, i) => (
          <BlogRow key={b.id} b={b} n={i + 1} />
        ))}
        <BlogState
          status={status}
          error={error}
          empty={status === "ok" && posts.length === 0}
        />
      </div>
    </div>
  );
}

function Contact() {
  return (
    <div className="page page-enter">
      <header style={{ marginBottom: 56 }}>
        <Eyebrow>Contact</Eyebrow>
      </header>

      <div className="contact-grid">
        <div>
          <p className="contact-lead">
            Have something to build, write, or break?{" "}
            <span className="accent">Send a note — I read everything.</span>
          </p>
          <p
            style={{
              marginTop: 32,
              color: "var(--muted)",
              fontSize: 15.5,
              lineHeight: 1.6,
              maxWidth: 480,
            }}
          >
            Best for: Anything related to the corpus(text) on any of these pages
            or unusual collaborations. Worst for: anything that needs a meeting
            before there's a clear question.
          </p>
        </div>

        <div className="contact-list">
          {CONTACTS.map((c) => (
            <a
              className="contact-row"
              key={c.label}
              href={c.href}
              target={c.href.startsWith("http") ? "_blank" : undefined}
              rel="noreferrer"
            >
              <span className="label">{c.label}</span>
              <span className="value">{c.value}</span>
              <span className="ext">
                <ArrowUpRight size={16} />
              </span>
            </a>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ----------------------- data ----------------------- */

const PROJECTS = [
  {
    id: "quantum-ml",
    title: "Quantum-ML",
    glyph: "Ψ",
    desc: "Trains four neural-quantum-state architectures via variational Monte Carlo + stochastic reconfiguration on the 1D spin-½ XXZ chain. One self-contained notebook.",
    stack: ["Jupyter", "PyTorch", "NumPy"],
    year: "2025",
    href: "https://github.com/ItsSypher/Quantum-ML",
  },
  {
    id: "sabr",
    title: "SABR Volatility Insights",
    glyph: "σ",
    desc: "Interactive browser workbench for fitting SABR stochastic-volatility surfaces on live US equity option chains — calibrates a smile per expiry from an Alpaca snapshot.",
    stack: ["TypeScript", "React", "WASM"],
    year: "2025",
    href: "https://github.com/ItsSypher/sabr-volatility-insights",
  },
  {
    id: "quantumfolio",
    title: "QuantumFolio",
    glyph: "Q",
    desc: "Builds an optimised investment portfolio using a quantum algorithm — no finance background, no physics degree required. Pick stocks, set risk, done.",
    stack: ["TypeScript", "Qiskit"],
    year: "2025",
    href: "https://github.com/ItsSypher/QuantumFolio",
  },
  {
    id: "delta-vega",
    title: "Delta-Vega Hedging",
    glyph: "Δ",
    desc: "Hedgesimple runs option hedging simulations comparing delta-only vs delta–vega across tickers, expiries, rebalancing cadences, and transaction-cost assumptions.",
    stack: ["Python", "pandas"],
    year: "2025",
    href: "https://github.com/ItsSypher/Delta-Vega-Portfolio-Hedging",
  },
  {
    id: "cds-fx",
    title: "CDS Pricing for FX",
    glyph: "ƒ",
    desc: "A Python script that calculates Black–Scholes prices for European call options. Supports multiple time values and notional amounts; exports to formatted Excel.",
    stack: ["Python", "SciPy", "Excel"],
    year: "2024",
    href: "https://github.com/ItsSypher/CDS-Pricing-for-FX-Contract",
  },
  {
    id: "energy",
    title: "Energy Demand Prediction",
    glyph: "Ω",
    desc: "The solution for the Fortum forecasting challenge at Junction 2025 — short-term electricity demand modelling on real grid data.",
    stack: ["Python", "XGBoost"],
    year: "2025",
    href: "https://github.com/ItsSypher/Energy-Demand-Prediction",
  },
];

const FEATURED_PROJECTS = PROJECTS.slice(0, 2);

/* Blog posts are fetched live from Medium RSS — see useMediumPosts() below. */

const TIMELINE = [
  {
    year: "2026",
    title: "Independent",
    desc: "Building tools, writing, and consulting on systems.",
    tag: "NOW",
  },
  {
    year: "2026",
    title: "Data Engineer · Lifeline Ventures",
    desc: "Fund data management and AI-Native processes.",
    tag: "WORK",
  },
  {
    year: "2026",
    title: "VC Scout · Ellipsis",
    desc: "Scout for the nordics ecosystem.",
    tag: "WORK",
  },
  {
    year: "2025",
    title: "AI Lead · Stryv",
    desc: "Built the compay from the ground up. Team of 10",
    tag: "WORK",
  },
  {
    year: "2025",
    title: "Dip into ML",
    desc: "Started with ML research at Aalto.",
    tag: "EDU",
  },
  {
    year: "2024",
    title: "Started studying Quantum Technologies",
    desc: "Picked up quantum physics and never quite put it down.",
    tag: "EDU",
  },
];

const CONTACTS = [
  {
    label: "Email",
    value: "upadhyaykavy@gmail.com",
    href: "mailto:upadhyaykavy@gmail.com",
  },
  {
    label: "GitHub",
    value: "github.com/ItsSypher",
    href: "https://github.com/ItsSypher",
  },
  {
    label: "LinkedIn",
    value: "linkedin.com/in/kavy",
    href: "https://www.linkedin.com/in/kavy/",
  },
  {
    label: "PIGEON",
    value: "It will find me",
    href: "https://youtu.be/dQw4w9WgXcQ?si=R5tiiBLu0Gw1eCqt",
  },
];

Object.assign(window, { Home, About, Projects, Blog, Contact });
