// projects.jsx — project cards drawn from the original site.

const PROJECTS = [
  {
    title: "Coptic Dictionary App",
    brief: "An app that translates to and from Coptic.",
    media: {
      kind: "iosframe",
      src: "assets/coptic_app.mp4",
      poster: "assets/coptic-poster.jpg",
      layout: "phone",
    },
    badge: "Mobile",
    tags: ["SwiftUI", "UIKit", "iOS"],
    page: "coptic.html",
  },
  {
    title: "Wordle Clone",
    brief: "A faithful Wordle remake — daily word, keyboard, win/loss states.",
    media: {
      kind: "iosframe",
      src: "assets/wordle_app.mp4",
      poster: "assets/wordle-poster.jpg",
      layout: "phone",
    },
    badge: "Mobile",
    tags: ["React Native", "Game Logic", "iOS / Android"],
    page: "wordle.html",
  },
  {
    title: "Tic Tac Toe Bot",
    brief: "A Tic-Tac-Toe AI that cannot lose.",
    media: { kind: "image", src: "assets/tictactoe_img.png", layout: "screen", fit: "contain", invertOnDark: true },
    badge: "AI",
    tags: ["Minimax", "JavaScript", "Game AI"],
    page: "tictactoe.html",
  },
  {
    title: "Hangman",
    brief: "A hangman game that picks words randomly and draws the figure.",
    media: { kind: "image", src: "assets/hangman_img.png", layout: "screen", fit: "contain", invertOnDark: true },
    badge: "Game",
    tags: ["JavaScript", "Canvas", "DOM"],
    page: "hangman.html",
  },
  {
    title: "Old Portfolio Two",
    brief: "My second portfolio — React, scroll-driven 3D airplane, dark glassy chrome.",
    media: {
      kind: "browser",
      src: "assets/old-portfolio-2.png",
      url: "website-portfolio-two-lovat.vercel.app",
      layout: "screen",
    },
    badge: "Web",
    tags: ["React", "Three.js", "Scroll Animation"],
    page: "https://website-portfolio-two-lovat.vercel.app/",
    external: true,
  },
  {
    title: "Old Portfolio One",
    brief: "My very first portfolio site — vanilla HTML/CSS/JS with playable demos.",
    media: {
      kind: "browser",
      src: "assets/old-portfolio-1.png",
      url: "website-old-wheat.vercel.app",
      layout: "screen",
    },
    badge: "Web",
    tags: ["HTML", "CSS", "JavaScript"],
    page: "https://website-old-wheat.vercel.app/",
    external: true,
  },
  {
    title: "Researcher's Website",
    brief: "A website built for the Saleeb Lab — a cancer molecular research group.",
    media: {
      kind: "browser",
      src: "assets/saleeblab.png",
      url: "saleeblab.com",
      layout: "screen",
    },
    badge: "Web",
    tags: ["React", "Client Work", "Responsive"],
    page: "https://www.saleeblab.com/",
    external: true,
  },
];

function useDarkMode() {
  const [dark, setDark] = React.useState(() =>
    typeof document !== "undefined" && document.documentElement.getAttribute("data-theme") === "dark"
  );
  React.useEffect(() => {
    const mo = new MutationObserver(() => {
      setDark(document.documentElement.getAttribute("data-theme") === "dark");
    });
    mo.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
    return () => mo.disconnect();
  }, []);
  return dark;
}

// LazyVideo: defers loading the video bytes until the element scrolls near the
// viewport. Heavy mp4s (~9MB) otherwise hold back first paint and feel sluggish.
// Until visible, we render a same-sized div with the poster image as background
// so the IntersectionObserver has something to observe and the user sees a still
// of the app instantly.
function LazyVideo({ src, poster, lockMute, style }) {
  const ref = React.useRef(null);
  const [shouldLoad, setShouldLoad] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (!('IntersectionObserver' in window)) { setShouldLoad(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setShouldLoad(true);
          io.disconnect();
        }
      });
    }, { rootMargin: '300px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  if (!shouldLoad) {
    const placeholderStyle = {
      ...style,
      backgroundColor: '#000',
      backgroundSize: 'cover',
      backgroundPosition: 'center',
    };
    if (poster) placeholderStyle.backgroundImage = `url(${poster})`;
    return <div ref={ref} style={placeholderStyle} aria-hidden="true" />;
  }
  return (
    <video
      ref={(el) => { ref.current = el; if (lockMute) lockMute(el); }}
      src={src}
      poster={poster}
      muted
      autoPlay
      loop
      playsInline
      preload="metadata"
      style={style}
    />
  );
}

function ProjectMedia({ p }) {
  const { kind, src, layout, href, poster, url, fit, invertOnDark } = p.media;
  const dark = useDarkMode();
  const extraClasses = [
    layout === "phone" ? "phone" : "",
    kind === "iosframe" ? "iosframe" : "",
    fit === "contain" ? "fit-contain" : "",
    invertOnDark ? "invert-on-dark" : "",
  ].filter(Boolean).join(" ");
  const classes = `proj-media ${extraClasses}`;
  let inner;
  const lockMute = (el) => {
    if (!el) return;
    el.muted = true;
    el.defaultMuted = true;
    el.volume = 0;
    el.addEventListener("volumechange", () => {
      if (!el.muted) el.muted = true;
    });
  };
  if (kind === "iosframe") {
    const IOSDevice = window.IOSDevice;
    inner = (
      <div className="proj-iphone-wrap">
        {IOSDevice ? (
          <IOSDevice width={402} height={874} dark={dark} statusBar={false}>
            <LazyVideo
              src={src}
              poster={poster}
              lockMute={lockMute}
              style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
            />
          </IOSDevice>
        ) : (
          <LazyVideo src={src} poster={poster} lockMute={lockMute} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
        )}
      </div>
    );
  } else if (kind === "video") {
    inner = (
      <LazyVideo
        src={src}
        poster={poster}
        lockMute={lockMute}
        style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
      />
    );
  } else if (kind === "browser") {
    // Static screenshot framed by a small macOS-style browser chrome (traffic lights
    // + address bar). For websites that exist as URLs, not embeddable iframes.
    inner = (
      <div className="proj-browser">
        <div className="proj-browser-chrome">
          <div className="proj-browser-dots"><i /><i /><i /></div>
          <div className="proj-browser-addr">{url || ""}</div>
        </div>
        <div className="proj-browser-screen">
          <img src={src} alt={p.title} />
        </div>
      </div>
    );
  } else if (kind === "image") {
    inner = <img src={src} alt={p.title} />;
  } else if (kind === "iframe") {
    // Show a styled placeholder card rather than embedding for performance
    inner = (
      <a
        href={href}
        target="_blank"
        rel="noopener noreferrer"
        style={{
          display: "flex", alignItems: "center", justifyContent: "center",
          width: "100%", height: "100%",
          background: "linear-gradient(135deg, #1b1d23, #2a2e36)",
          color: "#f5f5f7", fontFamily: "var(--font-mono)",
          fontSize: 12, letterSpacing: ".14em", textTransform: "uppercase",
        }}
      >
        <span style={{ opacity:.5, position:"absolute", top:14, left:14, fontSize:10 }}>website-old-wheat.vercel.app</span>
        <span style={{
          padding:"10px 16px", border:"1px solid rgba(255,255,255,.25)", borderRadius: 999
        }}>Open live site ↗</span>
      </a>
    );
  }
  return <div className={classes}>{p.badge && <span className="proj-badge">{p.badge}</span>}{inner}</div>;
}

function ProjectsSection() {
  return (
    <section className="section projects" id="projects" data-screen-label="Projects">
      <div className="section-head">
        <div>
          <div className="section-num">03 / PROJECTS</div>
          <h2 className="section-title">Things I&apos;ve built.</h2>
        </div>
        <div className="section-sub">
          Side projects, client work, and weekend experiments.
        </div>
      </div>

      <div className="proj-grid">
        {PROJECTS.map((p, i) => {
          const inner = (
            <>
              <ProjectMedia p={p} />
              <div className="proj-body">
                <h3 className="proj-title">{p.title}</h3>
                <p className="proj-brief">{p.brief}</p>
                <div className="proj-tags">
                  {p.tags.map((t) => <span className="proj-tag" key={t}>{t}</span>)}
                </div>
              </div>
            </>
          );
          if (p.page) {
            const isExternal = !!p.external;
            return (
              <a
                className="proj-card proj-card-link"
                key={p.title}
                href={p.page}
                target={isExternal ? "_blank" : undefined}
                rel={isExternal ? "noopener noreferrer" : undefined}
              >
                {inner}
                <span className="proj-card-cta" aria-hidden="true">
                  {isExternal ? (<>Visit site ↗</>) : (<>View case study →</>)}
                </span>
              </a>
            );
          }
          return (
            <article className="proj-card" key={p.title}>
              {inner}
            </article>
          );
        })}
      </div>
    </section>
  );
}

window.ProjectsSection = ProjectsSection;
