/* global React, PhoneMock, Screens */
const { useEffect, useRef, useState } = React;

/* ─── Helpers ──────────────────────────────────────────────────────────── */
/* Email obfuscation — keeps plaintext out of source + rendered DOM until JS runs.
   Address is base64-encoded; the visible text inserts a zero-width space at the "@"
   to break naive scraper regexes. */
const EMAIL_PARTS = ["cHJwbXByb2Zlc3Npb25hbA==", "Z21haWwuY29t"]; // user, host
function getEmail() {
  try { return atob(EMAIL_PARTS[0]) + "@" + atob(EMAIL_PARTS[1]); }
  catch (e) { return ""; }
}
function EmailLinkText({ suffix = "" }) {
  const [ready, setReady] = useState(false);
  useEffect(() => { setReady(true); }, []);
  if (!ready) return <>email — enable JavaScript</>;
  return <>{atob(EMAIL_PARTS[0]) + "​@​" + atob(EMAIL_PARTS[1])}{suffix}</>;
}
function EmailLink({ className, children, suffix = "", style }) {
  const [ready, setReady] = useState(false);
  useEffect(() => { setReady(true); }, []);
  const email = ready ? getEmail() : "";
  const display = ready
    ? atob(EMAIL_PARTS[0]) + "​@​" + atob(EMAIL_PARTS[1])
    : "email — enable JavaScript";
  const href = ready ? "mailto:" + email : "#";
  return (
    <a
      className={className}
      href={href}
      style={style}
      onClick={(e) => {
        if (!ready) {
          e.preventDefault();
          window.location.href = "mailto:" + getEmail();
        }
      }}
    >
      {children ?? <>{display}{suffix}</>}
    </a>
  );
}

function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) e.target.classList.add("in"); });
    }, { threshold: 0.12 });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  });
}

function useCursorTracking() {
  useEffect(() => {
    const onMove = (e) => {
      // Hero
      const hero = document.querySelector(".hero");
      if (hero) {
        const r = hero.getBoundingClientRect();
        hero.style.setProperty("--mx", ((e.clientX - r.left) / r.width * 100) + "%");
        hero.style.setProperty("--my", ((e.clientY - r.top) / r.height * 100) + "%");
      }
      // Cards
      document.querySelectorAll(".app-card").forEach(card => {
        const r = card.getBoundingClientRect();
        if (e.clientX >= r.left && e.clientX <= r.right && e.clientY >= r.top && e.clientY <= r.bottom) {
          card.style.setProperty("--mx", (e.clientX - r.left) + "px");
          card.style.setProperty("--my", (e.clientY - r.top) + "px");
        }
      });
    };
    window.addEventListener("pointermove", onMove);
    return () => window.removeEventListener("pointermove", onMove);
  }, []);
}

/* ─── Apps data ────────────────────────────────────────────────────────── */
const APPS = [
  {
    id: "sudoku",
    name: "Fun Sudoku",
    tag: "Number puzzle for cozy commutes",
    cat: "Puzzle",
    rating: "5.0",
    downloads: "10+",
    tint: "#C25B3F",
    screenKey: "ScreenSudoku",
    url: "https://play.google.com/store/apps/details?id=com.prpm.funsudoku",
  },
  {
    id: "gravity",
    name: "Gravity Loop",
    tag: "One-thumb arcade about orbits",
    cat: "Arcade",
    rating: "4.6",
    downloads: "50K+",
    tint: "#7A5AE0",
    screenKey: "ScreenGravity",
    testing: true,
  },
  {
    id: "tracker",
    name: "Beautiful Tracker",
    tag: "Habits, but make it lovely",
    cat: "Productivity",
    rating: "4.8",
    downloads: "25K+",
    tint: "#6B8266",
    screenKey: "ScreenTracker",
    testing: true,
  },
  {
    id: "flapzy",
    name: "Flapzy",
    tag: "Pocket-sized arcade joy",
    cat: "Arcade",
    rating: "4.5",
    downloads: "10K+",
    tint: "#F5D547",
    screenKey: "ScreenFlapzy",
    testing: true,
  },
  {
    id: "195",
    name: "195",
    tag: "Guess every flag on Earth",
    cat: "Trivia",
    rating: "4.9",
    downloads: "5K+",
    tint: "#0055A4",
    screenKey: "Screen195",
    testing: true,
  },
];

/* ─── Nav ──────────────────────────────────────────────────────────────── */
function Nav() {
  return (
    <nav className="nav">
      <div className="shell nav-inner">
        <div className="nav-logo">
          <span className="dot"></span>
          <span>Paulo M.</span>
        </div>
        <div className="nav-links">
          <a href="#apps">Apps</a>
          <a href="#featured">Featured</a>
          <a href="#about">About</a>
          <a href="#contact">Contact</a>
        </div>
        <a className="nav-cta" href="#contact">Say hi →</a>
      </div>
    </nav>
  );
}

/* ─── Hero ─────────────────────────────────────────────────────────────── */
function Hero() {
  return (
    <header className="hero">
      <div className="hero-cursor"></div>
      <div className="hero-shapes">
        <span className="shape s1"></span>
        <span className="shape s2"></span>
        <span className="shape s3"></span>
      </div>
      <div className="shell">
        <div className="hero-grid">
          <div>
            <div className="hero-eyebrow"><span className="pulse"></span> Available for collabs · Lisbon</div>
            <h1 className="hero-title">
              I make <span className="it">cozy</span><br/>
              little Android<br/>
              <span className="strike">products</span> <span className="it">friends</span>.
            </h1>
            <p className="hero-sub">
              Hi, I'm <strong>Paulo M.</strong> — an indie Android developer designing
              small, polished apps for the Google Play Store. Five shipped, more in the oven.
            </p>
            <dl className="hero-meta reveal">
              <div>
                <dt>Apps shipped</dt>
                <dd>5</dd>
              </div>
              <div>
                <dt>Downloads</dt>
                <dd>190K+</dd>
              </div>
              <div>
                <dt>Coffee per ship</dt>
                <dd>∞</dd>
              </div>
            </dl>
          </div>
          <aside className="hero-side">
            <div className="brew">
              <div className="brew-head">
                <span className="brew-tag"><span className="blink"></span> Now brewing</span>
                <span className="mono" style={{ color: "var(--ink-muted)" }}>v0.3</span>
              </div>
              <div className="brew-title">A tiny weather app<br/>that whispers, not yells.</div>
              <div className="brew-line">Working title: <em>Drizzle</em>. Day 27 of build.</div>
              <div className="brew-bar"><i></i></div>
              <div className="brew-meta">
                <span>Build</span>
                <span>~64% · ETA July</span>
              </div>
            </div>
          </aside>
        </div>
      </div>
    </header>
  );
}

/* ─── Marquee ──────────────────────────────────────────────────────────── */
function Marquee() {
  const items = ["Indie Android", "★", "1 app on Play Store", "★", "Made in Lisbon", "★", "Calm UX", "★", "Fewer features, more polish", "★", "Currently brewing", "★"];
  return (
    <div className="marquee" aria-hidden="true">
      <div className="marquee-track">
        <span>
          {items.map((t, i) => (
            <React.Fragment key={i}>
              <span className={t === "★" ? "star" : ""}>{t}</span>
            </React.Fragment>
          ))}
        </span>
        <span>
          {items.map((t, i) => (
            <React.Fragment key={"b"+i}>
              <span className={t === "★" ? "star" : ""}>{t}</span>
            </React.Fragment>
          ))}
        </span>
      </div>
    </div>
  );
}

/* ─── Apps Grid ────────────────────────────────────────────────────────── */
function AppsGrid() {
  return (
    <section className="apps" id="apps">
      <div className="shell">
        <div className="section-head reveal">
          <div>
            <div className="kicker">→ The catalogue · 01</div>
            <h2>Five apps,<br/>many late nights.</h2>
          </div>
          <p className="lead">Each one ships with care, a real changelog, and zero dark patterns. Tap any card to peek at it on the Play Store.</p>
        </div>
        <div className="app-grid">
          {APPS.map((app, i) => {
            const Screen = Screens[app.screenKey];
            const linkProps = app.testing
              ? { role: "group", "aria-disabled": "true" }
              : {
                  href: app.url || `https://play.google.com/store/apps/details?id=com.paulom.${app.id}`,
                  target: "_blank",
                  rel: "noreferrer",
                };
            const Tag = app.testing ? "div" : "a";
            return (
              <Tag
                key={app.id}
                {...linkProps}
                className={"app-card reveal" + (app.testing ? " is-disabled" : "")}
                style={{ "--card-tint": app.tint, "--rd": (i * 80) + "ms" }}
              >
                {app.testing && (
                  <span className="ribbon" aria-label="In testing">
                    <span className="ribbon-text">In Testing</span>
                  </span>
                )}
                <div className="app-card-inner">
                  <div className="app-meta">
                    <span className="cat">{app.cat}</span>
                    <span>{String(i+1).padStart(2,"0")}/06</span>
                  </div>
                  <PhoneMock app={{ screen: <Screen /> }} />
                  <div>
                    <h3 className="app-name">{app.name}</h3>
                    <p className="app-tag">{app.tag}</p>
                  </div>
                  <div className="app-foot">
                    <span className="stars"><span className="star">★</span> {app.testing ? "N/A" : app.rating} · {app.testing ? "N/A" : app.downloads}</span>
                    <span className="play-btn">Play store ↗</span>
                  </div>
                </div>
              </Tag>
            );
          })}
          <div className="app-card coming reveal" style={{ "--rd": "400ms" }}>
            <div className="app-card-inner">
              <PhoneMock app={{ screen: <Screens.ScreenComing /> }} />
              <div>
                <h3 className="app-name serif it">Drizzle<span className="blink-dots"></span></h3>
                <p className="app-tag mono" style={{ marginTop: 8 }}>SHIPPING SUMMER '26</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Featured spotlight ───────────────────────────────────────────────── */
function Featured() {
  return (
    <section className="featured" id="featured">
      <div className="shell">
        <div className="featured-grid">
          <div className="featured-side reveal">
            <div className="kicker">★ Featured · 02</div>
            <h3>Beautiful<br/>Tracker.<br/><em className="it">A habit app you'll <span className="ulines">actually</span> open.</em></h3>
            <p>No guilt-trips, no streak loss anxiety. Just a calm, paper-quiet space to mark how today went — with type and color worth waking up to.</p>
            <ul className="feat-bullets">
              <li>Hand-tuned colour palettes for every habit</li>
              <li>Heatmap that doubles as art for your home screen</li>
              <li>Offline-first. No accounts</li>
            </ul>
            <span className="feat-cta is-disabled" aria-disabled="true" role="button">
              Coming soon...
            </span>
          </div>
          <div className="featured-phone-stage">
            <div className="phone tag">★ Editor's pick</div>
            <PhoneMock app={{ screen: <Screens.ScreenTracker /> }} />
            <div className="phone sm">
              <span className="punch"></span>
              <div className="screen"><Screens.ScreenSudoku /></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Stats ───────────────────────────────────────────────────────────── */
function Stats() {
  return (
    <section className="stats">
      <div className="shell">
        <div className="stats-grid reveal">
          <div className="stat lead-cell">
            <div className="lbl">By the numbers</div>
            <div className="lead-text" style={{ marginTop: 18 }}>
              Small numbers, made one user at a time.
            </div>
          </div>
          <div className="stat">
            <div className="num">10<small>+</small></div>
            <div className="lbl">Total downloads</div>
          </div>
          <div className="stat">
            <div className="num">5.0<small>★</small></div>
            <div className="lbl">Avg. Play rating</div>
          </div>
          <div className="stat">
            <div className="num">5</div>
            <div className="lbl">Apps · in oven</div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── About ───────────────────────────────────────────────────────────── */
function About() {
  return (
    <section className="about" id="about">
      <div className="shell">
        <div className="about-grid">
          <div className="reveal">
            <div className="pill-row">
              <span className="pill">Kotlin</span>
              <span className="pill">Jetpack Compose</span>
              <span className="pill">Android</span>
              <span className="pill">UX</span>
              <span className="pill">Motion</span>
              <span className="pill">Type-nerd</span>
            </div>
            <h2>I'm Paulo —<br/>I make small <span className="it">software</span> for big feelings.</h2>
            <p>
              I've been shipping Android apps solo for a short time. Days look like:
              coffee, Compose, a cat on the keyboard, slow iteration on the bits
              most people would skip.
            </p>
            <p>
              I care about the boring stuff — empty states, real loading,
              the way a button feels under your thumb. If you do too,
              <a href="#contact" style={{ color: "var(--accent)", textDecoration: "underline", textUnderlineOffset: 4 }}> let's chat</a>.
            </p>
          </div>
          <div className="portrait reveal has-photo" style={{ "--rd": "120ms" }}>
            <div className="sticker">5 apps<br/>in the oven</div>
            <img className="portrait-img" src="assets/portrait.png" alt="Paulo M. portrait" />
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Testimonials ─────────────────────────────────────────────────────── */
const REVIEWS = [
  { stars: 5, q: "Finally a sudoku app that doesn't bury me in ads. Pure joy.", who: "Marta L.", where: "Play Store · Fun Sudoku" },
  { stars: 5, q: "Beautiful Tracker is the only habit app that survived 6 months on my phone.", who: "Diego A.", where: "Play Store · Beautiful Tracker" },
  { stars: 4, q: "Gravity Loop made me miss my bus. Worth it.", who: "Yuki K.", where: "Play Store · Gravity Loop" },
  { stars: 5, q: "195 turned my kid into a flag-quoting overnight expert.", who: "Sam P.", where: "Play Store · 195" },
  { stars: 5, q: "Tiny apps with huge personality. Paulo gets it.", who: "Ana R.", where: "Play Store · Flapzy" },
  { stars: 5, q: "Polished like a AAA studio shipped them. They didn't.", who: "Tom W.", where: "Play Store · Beautiful Tracker" },
];

function Testimonials() {
  return (
    <section className="testi">
      <div className="shell">
        <div className="section-head reveal">
          <div>
            <div className="kicker">♥ Real reviews · 03</div>
            <h2>What folks<br/>are saying.</h2>
          </div>
          <p className="lead">Pulled straight from the Play Store. No, my mum is not in here.</p>
        </div>
        <div className="testi-grid">
          {REVIEWS.map((r,i) => (
            <div key={i} className="testi-card reveal" style={{ "--rd": (i*60) + "ms" }}>
              <div className="stars">{"★".repeat(r.stars)}{"☆".repeat(5-r.stars)}</div>
              <p className="quote">"{r.q}"</p>
              <div className="who">
                <div className="ava">{r.who.split(" ").map(n => n[0]).join("")}</div>
                <div className="name">{r.who}<small>{r.where}</small></div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ─── Newsletter ───────────────────────────────────────────────────────── */
function Newsletter() {
  const [done, setDone] = useState(false);
  return (
    <section className="news">
      <div className="shell">
        <div className="news-card reveal">
          <div>
            <div className="mono" style={{ color: "var(--ink-muted)", marginBottom: 14 }}>↘ The slow letter · 04</div>
            <h3>Get a postcard<br/>when I ship.</h3>
            <p>Once-a-quarter email from me with new app launches, design notes, and the occasional behind-the-scenes peek. No spam. Pinky promise.</p>
          </div>
          <form className="news-form" onSubmit={(e) => { e.preventDefault(); setDone(true); }}>
            <div className="row">
              <input type="email" placeholder="you@inbox.com" required />
              <button type="submit">{done ? "✓ added" : "Subscribe →"}</button>
            </div>
            <div className="hint">~ 4 emails a year · unsubscribe anytime</div>
          </form>
        </div>
      </div>
    </section>
  );
}

/* ─── Contact ──────────────────────────────────────────────────────────── */
function Contact() {
  return (
    <section className="contact" id="contact">
      <div className="shell">
        <div className="contact-grid">
          <div className="reveal">
            <div className="mono" style={{ color: "var(--ink-muted)", marginBottom: 14 }}>✉ Get in touch · 05</div>
            <h2>Let's make<br/><span className="it">something</span><br/>quietly great.</h2>
            <p className="lead">Working on a small app and need a Compose-fluent collaborator? Or just want to say hi about a font I picked? My inbox is open.</p>
          </div>
          <div className="contact-list reveal" style={{ "--rd": "120ms" }}>
            <EmailLink className="contact-row">
              <span className="k">Email</span>
              <span className="v"><EmailLinkText /></span>
              <span className="arrow">↗</span>
            </EmailLink>
            <a className="contact-row" href="https://play.google.com/store/apps/developer?id=Paulo+M" target="_blank" rel="noreferrer">
              <span className="k">Play Store</span>
              <span className="v">Paulo M · developer page</span>
              <span className="arrow">↗</span>
            </a>
            <a className="contact-row" href="#">
              <span className="k">Located</span>
              <span className="v">Lisbon, PT (UTC+0/+1)</span>
              <span className="arrow">·</span>
            </a>
            <a className="contact-row" href="#">
              <span className="k">Open to</span>
              <span className="v">Freelance · Collabs · Coffee</span>
              <span className="arrow">·</span>
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Footer with big CTA ──────────────────────────────────────────────── */
function Footer() {
  return (
    <footer className="foot">
      <div className="shell">
        <div className="foot-cta reveal">
          <div className="small">↓ The big finish</div>
          <h2>Let's build<br/><span className="it">something</span> small.</h2>
          <EmailLink className="big" suffix=" →" />
        </div>
        <div className="foot-bottom">
          <div>© 2026 Paulo M · Hand-rolled in Lisbon</div>
          <div className="links">
            <a href="#apps">Apps</a>
            <a href="#about">About</a>
            <a href="#contact">Contact</a>
            <a href="https://play.google.com/store/apps/developer?id=Paulo+M" target="_blank" rel="noreferrer">Play Store ↗</a>
            <a href="https://gist.github.com/prpm87/12bf0d42611774f02a5eabe35c99c916" target="_blank" rel="noreferrer">Privacy ↗</a>
          </div>
        </div>
      </div>
    </footer>
  );
}

window.Sections = { Nav, Hero, Marquee, AppsGrid, Featured, Stats, About, Testimonials, Newsletter, Contact, Footer };
window.useReveal = useReveal;
window.useCursorTracking = useCursorTracking;
