/* global React */
/* ============================================================================
   ui.jsx — small building blocks shared across sections.
   ----------------------------------------------------------------------------
   These are the pieces that more than one section needs, kept in one place so
   there's a single definition of each. Everything is published to `window` at
   the bottom so the section files (loaded as separate <script>s) can use them.

   Exports:
     FileIcon / FolderIcon  — the little file-tree glyphs
     Crumbs                 — the "~ / portfolio / about.md" breadcrumb line
     ImageSlot              — placeholder box you swap a real image into
     GithubContrib          — the live GitHub contribution graph
   ============================================================================ */

// ── File-tree icons ──────────────────────────────────────────────────────────
const FileIcon = ({ on }) => (
  <svg className={"icon" + (on ? " on" : "")} viewBox="0 0 16 16" fill="none">
    <path d="M3 1.5h6l4 4V14a.5.5 0 0 1-.5.5h-9A.5.5 0 0 1 3 14V1.5z" stroke="currentColor" strokeWidth="1" />
    <path d="M9 1.5V6h4" stroke="currentColor" strokeWidth="1" />
  </svg>
);
const FolderIcon = ({ on }) => (
  <svg className={"icon" + (on ? " on" : "")} viewBox="0 0 16 16" fill="none">
    <path d="M1.5 3.5h4l1.5 1.5h7.5v9h-13v-10.5z" stroke="currentColor" strokeWidth="1" />
  </svg>
);

// ── Breadcrumbs ───────────────────────────────────────────────────────────────
// Renders "a / b / c" with the last part emphasised. Pass an array of strings.
function Crumbs({ parts }) {
  return (
    <div className="rm-crumbs">
      {parts.map((p, i) => (
        <React.Fragment key={i}>
          {i > 0 && <span className="sep">/</span>}
          {i === parts.length - 1 ? <b>{p}</b> : <span>{p}</span>}
        </React.Fragment>
      ))}
    </div>
  );
}

// ── ImageSlot ─────────────────────────────────────────────────────────────────
// A drop-in spot for a picture. While `src` is empty it shows a hatched box with
// a hint telling you exactly where to put the file; once `src` is set it shows
// the image (cover-cropped). Used by project covers and the photo gallery.
//
//   ┌─ HOW TO ADD A PICTURE ─────────────────────────────────────────────┐
//   │ 1. Drop your image into  public/images/                            │
//   │ 2. Point the matching `image:` field in src/data.js at it, e.g.    │
//   │       image: "public/images/everyday-tracking.png"                 │
//   │ The placeholder is replaced automatically — no code change needed. │
//   └────────────────────────────────────────────────────────────────────┘
function ImageSlot({ src, alt = "", hint, caption }) {
  if (src) {
    return (
      <div className="pf-imgslot">
        <img src={src} alt={alt} loading="lazy" />
        {caption && <span className="cap">{caption}</span>}
      </div>
    );
  }
  return (
    <div className="pf-imgslot empty" role="img" aria-label={alt || "image placeholder"}>
      <div className="note">
        <b>{hint || "add an image"}</b><br />
        drop a file in <b>public/images/</b><br />
        then set its path in <b>data.js</b>
      </div>
    </div>
  );
}

// ── GithubContrib ─────────────────────────────────────────────────────────────
// Live contribution graph via ghchart.rshah.org (free SVG proxy, no auth).
// `color` is a hex WITHOUT the leading #. The src is set after mount so the
// request stays live even when the page is bundled into a single standalone file.
function GithubContrib({ username, color = "5b6b80" }) {
  const ref = React.useRef(null);
  const [state, setState] = React.useState("loading");
  React.useEffect(() => {
    if (!ref.current || !username) return;
    setState("loading");
    const img = ref.current;
    img.onload  = () => setState("loaded");
    img.onerror = () => setState("error");
    img.src = `https://ghchart.rshah.org/${color}/${username}`;
  }, [username, color]);
  if (!username) return null;
  return (
    <div className="rm-contrib-real">
      <img ref={ref} alt={`@${username} GitHub contributions`} />
      {state === "loading" && <div className="hint">Loading contributions for <code>@{username}</code>…</div>}
      {state === "error" && (
        <div className="hint">
          Couldn't reach the contribution service.{" "}
          <a className="link" href={`https://github.com/${username}`} target="_blank" rel="noopener">View on GitHub ↗</a>
        </div>
      )}
    </div>
  );
}

// Make these available to every other script (they load as separate files).
Object.assign(window, { FileIcon, FolderIcon, Crumbs, ImageSlot, GithubContrib });
