// Kashyap Mavani — Portfolio
// TODO_KASHYAP: walk through this file and replace anywhere you see TODO_KASHYAP
// with values that are actually true for you. Don't ship with mine.

const { useState, useEffect, useRef, useCallback } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#e8c547",
  "watermark": "BUILD",
  "glowIntensity": 60,
  "showWatermark": true,
  "showPhoto": true,
  "showMap": true
}/*EDITMODE-END*/;

// TODO_KASHYAP: Currently is the signature move — keep it real and re-date it.
// If you don't actually update this monthly, delete the panel.
const CURRENTLY = {
  updated: "Apr 26, 2026",
  items: [
    { kind: "shipping",  text: "ClauseGuard v1.2 — clause comparison view" },
    { kind: "learning",  text: "Rust + Tauri (rewriting a side-tool)" },
    { kind: "reading",   text: "Designing Data-Intensive Applications" },
    { kind: "open to",   text: "Frontend / creative eng roles" },
    // TODO_KASHYAP: replace with companies YOU actually want to work at
    { kind: "watching",  text: "Cohere · Ramp · Linear · Vercel" },
  ],
};

// ---------- Data ----------

const PROJECTS = [
  {
    n: "01",
    title: "ClauseGuard",
    badge: "AI · Live",
    badgeKind: "live",
    desc: "Reads a contract, flags the clauses that should worry you, answers questions about it. Built it because I got tired of skimming 40-page PDFs.",
    tags: ["Next.js", "Claude API", "TypeScript", "pdfjs", "Vercel KV"],
    meta: "live · updated Apr 2026",
    href: "https://clauseguard-seven.vercel.app/",
  },
  {
    n: "02",
    title: "Groccee",
    badge: "Built to scale",
    badgeKind: "metric",
    desc: "Grocery app for households. Shared lists, real-time sync, pantry tracking. Architected for 500+ users. Never shipped — we couldn't afford the App Store dev account that semester.",
    tags: ["React Native", "MongoDB", "WebSocket", "Expo"],
    meta: "github (under teammate's account)",
    href: "https://github.com/Nisarg0904/Groccee",
  },
  {
    n: "03",
    title: "E-commerce Platform",
    badge: null,
    badgeKind: null,
    desc: "Full storefront. Stripe, inventory, order management, admin dashboard. Built end-to-end as a learning project.",
    tags: ["Next.js", "Stripe", "Tailwind", "Node.js"],
    meta: "github",
    href: "#",
  },
];

const NAV_LINKS = [
  { label: "Work", href: "#work" },
  { label: "About", href: "#about" },
  { label: "Contact", href: "#contact" },
];

const CONTACT_LINKS = [
  { label: "email", sub: "kashmavani@gmail.com", href: "mailto:kashmavani@gmail.com" },
  { label: "linkedin", sub: "/in/kashyap-mavani", href: "https://www.linkedin.com/in/kashyap-mavani/" },
  { label: "github", sub: "@Kashh99", href: "https://github.com/Kashh99" },
  { label: "resume", sub: "PDF, 84kb", href: "#" },
];

// ---------- Cursor glow ----------

function CursorGlow({ accent, intensity }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf = 0;
    let tx = window.innerWidth / 2;
    let ty = window.innerHeight / 2;
    let cx = tx, cy = ty;
    const onMove = (e) => {
      tx = e.clientX;
      ty = e.clientY;
    };
    const tick = () => {
      cx += (tx - cx) * 0.12;
      cy += (ty - cy) * 0.12;
      el.style.transform = `translate3d(${cx - 400}px, ${cy - 400}px, 0)`;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    window.addEventListener("mousemove", onMove);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("mousemove", onMove);
    };
  }, []);
  const alpha = Math.max(0, Math.min(100, intensity)) / 100;
  return (
    <div
      ref={ref}
      aria-hidden="true"
      style={{
        position: "fixed",
        top: 0,
        left: 0,
        width: 800,
        height: 800,
        pointerEvents: "none",
        zIndex: 1,
        background: `radial-gradient(circle at center, ${hexToRgba(accent, 0.10 * alpha)} 0%, ${hexToRgba(accent, 0.04 * alpha)} 25%, transparent 60%)`,
        mixBlendMode: "screen",
        willChange: "transform",
      }}
    />
  );
}

function hexToRgba(hex, a) {
  const h = hex.replace("#", "");
  const r = parseInt(h.slice(0, 2), 16);
  const g = parseInt(h.slice(2, 4), 16);
  const b = parseInt(h.slice(4, 6), 16);
  return `rgba(${r},${g},${b},${a})`;
}

// ---------- Sections ----------

function Nav({ accent }) {
  const [menuOpen, setMenuOpen] = useState(false);
  const close = () => setMenuOpen(false);

  // prevent body scroll while menu is open
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  return (
    <nav className="km-nav" data-screen-label="Nav">
      <div className="km-nav__brand">
        <span className="km-nav__mark">KM</span>
        <span className="km-nav__sep">—</span>
        <span className="km-nav__year">2026</span>
      </div>
      <button
        className={`km-nav__hamburger${menuOpen ? " is-open" : ""}`}
        onClick={() => setMenuOpen(!menuOpen)}
        aria-label={menuOpen ? "Close menu" : "Open menu"}
        aria-expanded={menuOpen}
      >
        <span /><span /><span />
      </button>
      <div className={`km-nav__links${menuOpen ? " is-open" : ""}`}>
        {NAV_LINKS.map((l) => (
          <a key={l.label} href={l.href} className="km-nav__link" onClick={close}>
            {l.label}
          </a>
        ))}
        <a href="#" className="km-nav__link km-nav__link--accent" style={{ color: accent }} onClick={close}>
          Resume <span aria-hidden="true">↗</span>
        </a>
      </div>
    </nav>
  );
}

function Hero({ accent }) {
  return (
    <section className="km-hero" id="top" data-screen-label="Hero">
      <div className="km-hero__inner">
        <div className="km-hero__eyebrow">
          <span className="km-hero__line" style={{ background: accent }} />
          <span>Available for opportunities</span>
        </div>

        <h1 className="km-hero__name">
          <span className="km-hero__name-row">KASHYAP</span>
          <span className="km-hero__name-row" style={{ color: accent }}>
            MAVANI<span style={{ color: accent }}>.</span>
          </span>
        </h1>

        <p className="km-hero__sub">
          {/* TODO_KASHYAP: rewrite this in YOUR voice. The current line is fine but generic. */}
          I build things that ship. Full-stack apps, AI tools, whatever the team needs that week.
        </p>

        <div className="km-hero__stats">
          {/* TODO_KASHYAP: count your real GitHub repos and your real years building. Round numbers read fake. */}
          <Stat value="12" label="Projects shipped" />
          <Divider />
          <Stat value="#17" label="Canada — IEEEXtreme" accent={accent} />
          <Divider />
          <Stat value="3" label="Years building" />
        </div>

        <div className="km-hero__cta">
          <a
            href="#work"
            className="km-btn km-btn--solid"
            style={{ background: accent, color: "#0a0a0a" }}
          >
            View my work →
          </a>
          <a href="#contact" className="km-btn km-btn--ghost">
            Get in touch
          </a>
        </div>
      </div>

      <ScrollIndicator />
    </section>
  );
}

function Currently({ accent }) {
  return (
    <section className="km-currently" data-screen-label="Currently">
      <div className="km-currently__head">
        <div className="km-currently__label">
          <span className="km-currently__pulse" style={{ background: accent }} />
          <span>Currently</span>
        </div>
        <span className="km-currently__updated">Updated {CURRENTLY.updated}</span>
      </div>
      <ul className="km-currently__list">
        {CURRENTLY.items.map((it) => (
          <li key={it.kind} className="km-currently__item">
            <span className="km-currently__kind">{it.kind}</span>
            <span className="km-currently__text">{it.text}</span>
          </li>
        ))}
      </ul>
    </section>
  );
}

function Stat({ value, label, accent }) {
  return (
    <div className="km-stat">
      <div className="km-stat__value" style={accent ? { color: accent } : null}>{value}</div>
      <div className="km-stat__label">{label}</div>
    </div>
  );
}

function Divider() {
  return <span className="km-stat__divider" aria-hidden="true" />;
}

function ScrollIndicator() {
  return (
    <div className="km-scroll" aria-hidden="true">
      <span className="km-scroll__line" />
      <span className="km-scroll__label">SCROLL</span>
    </div>
  );
}

function Work({ accent }) {
  return (
    <section className="km-work" id="work" data-screen-label="Work">
      <SectionHeader index="01" title="Selected work" caption={`${PROJECTS.length} projects`} />
      <ol className="km-work__list">
        {PROJECTS.map((p, i) => (
          <ProjectRow key={p.n} project={p} accent={accent} last={i === PROJECTS.length - 1} />
        ))}
      </ol>
    </section>
  );
}

function ProjectRow({ project, accent, last }) {
  const [hover, setHover] = useState(false);
  return (
    <li
      className={`km-row ${hover ? "is-hover" : ""} ${last ? "is-last" : ""}`}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
    >
      <a href={project.href} className="km-row__link" target={project.href.startsWith("http") ? "_blank" : null} rel={project.href.startsWith("http") ? "noopener noreferrer" : null}>
        <span className="km-row__num">{project.n}</span>
        <div className="km-row__main">
          <div className="km-row__head">
            <h3 className="km-row__title">{project.title}</h3>
            {project.badge && (
              <span
                className={`km-badge km-badge--${project.badgeKind}`}
                style={project.badgeKind === "live" ? { borderColor: accent, color: accent } : null}
              >
                {project.badgeKind === "live" && (
                  <span className="km-badge__dot" style={{ background: accent }} />
                )}
                {project.badge}
              </span>
            )}
          </div>
          <p className="km-row__desc">{project.desc}</p>
          <div className="km-row__tags">
            {project.tags.map((t) => (
              <span key={t} className="km-tag">{t}</span>
            ))}
          </div>
          {project.meta && (
            <div className="km-row__meta">{project.meta}</div>
          )}
        </div>
        <span
          className="km-row__arrow"
          style={hover ? { color: accent, transform: "translate(4px, -4px)" } : null}
          aria-hidden="true"
        >
          ↗
        </span>
      </a>
    </li>
  );
}

function About({ accent }) {
  return (
    <section className="km-about" id="about" data-screen-label="About">
      <SectionHeader index="02" title="About" caption="who & where" />
      <div className="km-about__grid">
        <div className="km-about__left">
          {/* photo placeholder — drop a real image at uploads/kashyap.jpg and it'll appear */}
          <PhotoSlot show={true} />
          <h2 className="km-about__head">
            Adaptable dev.<br />
            Startup <span style={{ color: accent }}>minded</span>.
          </h2>
          <p className="km-about__p">
            Toronto. Just out of George Brown. I write the boring code that keeps things alive,
            and I care about the seam between design and engineering more than is healthy.
          </p>
          <blockquote className="km-quote" style={{ borderColor: accent }}>
            {/* TODO_KASHYAP: this should be a sentence only YOU would write. Use a real Slack quote, a hot take, anything specific. Or delete the quote entirely. */}
            Ship Friday, patch Monday. Decks can wait.
          </blockquote>
          <p className="km-about__p">
            React, Next.js, Node, React Native, Postgres. Happy to learn whatever a small team is
            already running on. Looking for frontend or creative engineering at a startup that
            ships often.
          </p>
        </div>
        <div className="km-about__right">
          <FactCard label="Availability" value="Open" sub="~2 weeks notice · EST" />
          <FactCard label="Strongest in" value="React · Next.js" sub="TypeScript, Tailwind, Node" />
          <FactCard label="Targeting" value="Frontend / creative" sub="seed → series B" />
          <FactCard
            label="Fun fact"
            value="#17 in Canada"
            sub="IEEEXtreme 2024 · 6,000+ teams"
            accent={accent}
          />
        </div>
      </div>
    </section>
  );
}

// Set PHOTO_SRC to a real image path (e.g. "uploads/kashyap.jpg") once uploaded.
const PHOTO_SRC = "uploads/kashyap.jpg?v=3";

function MapBreak({ accent }) {
  return (
    <section className="km-mapbreak" data-screen-label="Toronto">
      <div className="km-mapbreak__inner">
        <img
          src="uploads/toronto_midnight_blue_20260328_223738.png"
          alt="Map of Toronto"
          className="km-mapbreak__img"
        />
        <div className="km-mapbreak__overlay" />
        <div className="km-mapbreak__caption">
          <span
            className="km-mapbreak__line"
            style={{ background: accent }}
            aria-hidden="true"
          />
          <span className="km-mapbreak__city">Toronto.</span>
          <span className="km-mapbreak__coords">EST · open to remote</span>
        </div>
      </div>
    </section>
  );
}

function PhotoSlot({ show }) {
  if (!show) return null;
  return (
    <div className="km-photo">
      {PHOTO_SRC ? (
        <img src={PHOTO_SRC} alt="Kashyap Mavani" className="km-photo__img" />
      ) : (
        <div className="km-photo__placeholder">
          <span className="km-photo__ph-label">[ photo ]</span>
          <span className="km-photo__ph-sub">drop kashyap.jpg in /uploads</span>
        </div>
      )}
      <div className="km-photo__cap">
        <span>Kashyap, Toronto</span>
        <span className="km-photo__cap-date">2026</span>
      </div>
    </div>
  );
}

function FactCard({ label, value, sub, accent }) {
  return (
    <div className="km-fact">
      <div className="km-fact__label">{label}</div>
      <div className="km-fact__value" style={accent ? { color: accent } : null}>{value}</div>
      <div className="km-fact__sub">{sub}</div>
    </div>
  );
}

function Contact({ accent }) {
  return (
    <section className="km-contact" id="contact" data-screen-label="Contact">
      <SectionHeader index="03" title="Let's talk" caption="inbox is open" />
      <h2 className="km-contact__head">
        Got something to <span style={{ color: accent }}>build</span>?
      </h2>
      <ul className="km-contact__list">
        {CONTACT_LINKS.map((c) => (
          <ContactLink key={c.label} link={c} accent={accent} />
        ))}
      </ul>
    </section>
  );
}

function ContactLink({ link, accent }) {
  const [hover, setHover] = useState(false);
  return (
    <li
      className="km-clink"
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={hover ? { borderColor: accent } : null}
    >
      <a href={link.href} className="km-clink__a">
        <span className="km-clink__label">{link.label}</span>
        <span className="km-clink__sub">{link.sub}</span>
        <span
          className="km-clink__arrow"
          style={hover ? { color: accent, transform: "translate(2px, -2px)" } : null}
          aria-hidden="true"
        >
          ↗
        </span>
      </a>
    </li>
  );
}

function Footer({ accent }) {
  return (
    <footer className="km-footer" data-screen-label="Footer">
      <div className="km-footer__left">
        <span className="km-pulse" />
        <span>Open to work — Toronto & remote</span>
      </div>
      <div className="km-footer__right">
        <span>Kashyap Mavani · 2026</span>
        {/* TODO_KASHYAP: bump this date when you actually update the site */}
        <span className="km-footer__updated">last updated Apr 26, 2026</span>
      </div>
    </footer>
  );
}

function SectionHeader({ index, title, caption }) {
  return (
    <div className="km-sec-head">
      <span className="km-sec-head__idx">{index}</span>
      <span className="km-sec-head__title">{title}</span>
      <span className="km-sec-head__caption">{caption}</span>
    </div>
  );
}
// ---------- Watermark ----------

function Watermark({ text, show }) {
  if (!show) return null;
  return (
    <div className="km-watermark" aria-hidden="true">
      <span>{text}</span>
    </div>
  );
}

// ---------- App ----------

function App() {
  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);

  // smooth scroll for hash links
  useEffect(() => {
    const onClick = (e) => {
      const a = e.target.closest('a[href^="#"]');
      if (!a) return;
      const id = a.getAttribute("href").slice(1);
      if (!id) return;
      const target = document.getElementById(id);
      if (!target) return;
      e.preventDefault();
      target.scrollIntoView({ behavior: "smooth", block: "start" });
    };
    document.addEventListener("click", onClick);
    return () => document.removeEventListener("click", onClick);
  }, []);

  // expose accent as CSS var
  useEffect(() => {
    document.documentElement.style.setProperty("--km-accent", tweaks.accent);
  }, [tweaks.accent]);

  return (
    <>
      <CursorGlow accent={tweaks.accent} intensity={tweaks.glowIntensity} />
      <Watermark text={tweaks.watermark} show={tweaks.showWatermark} />
      <div className="km-shell">
        <Nav accent={tweaks.accent} />
        <Hero accent={tweaks.accent} />
        <Currently accent={tweaks.accent} />
        <Work accent={tweaks.accent} />
        {tweaks.showMap && <MapBreak accent={tweaks.accent} />}
        <About accent={tweaks.accent} />
        <Contact accent={tweaks.accent} />
        <Footer accent={tweaks.accent} />
      </div>

      <window.TweaksPanel title="Tweaks">
        <window.TweakSection title="Color">
          <window.TweakColor
            label="Accent"
            value={tweaks.accent}
            onChange={(v) => setTweak("accent", v)}
          />
        </window.TweakSection>
        <window.TweakSection title="Watermark">
          <window.TweakToggle
            label="Show watermark"
            value={tweaks.showWatermark}
            onChange={(v) => setTweak("showWatermark", v)}
          />
          <window.TweakText
            label="Text"
            value={tweaks.watermark}
            onChange={(v) => setTweak("watermark", v.toUpperCase().slice(0, 10))}
          />
        </window.TweakSection>
        <window.TweakSection title="Toronto map">
          <window.TweakToggle
            label="Show map break"
            value={tweaks.showMap}
            onChange={(v) => setTweak("showMap", v)}
          />
        </window.TweakSection>
        <window.TweakSection title="Cursor glow">
          <window.TweakSlider
            label="Intensity"
            value={tweaks.glowIntensity}
            min={0}
            max={100}
            step={5}
            onChange={(v) => setTweak("glowIntensity", v)}
          />
        </window.TweakSection>
      </window.TweaksPanel>
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
