/* ============================================================
   IFE & CHILL — shared UI components
   ============================================================ */

function Shot({ label, hint, aspect = "16/9", rounded = true, big = false, src, video, bgVideo = false }) {
  return (
    <div
      className="ix-shot"
      style={{ aspectRatio: aspect, borderRadius: rounded ? (big ? 0 : "4px") : 0 }}
    >
      {video ? (
        <video
          className="ix-shot-img"
          src={video}
          poster={src}
          controls={!bgVideo}
          autoPlay={bgVideo}
          muted={bgVideo}
          loop={bgVideo}
          playsInline
        />
      ) : src ? (
        <img className="ix-shot-img" src={src} alt={label} />
      ) : (
        <>
          <div className="ix-shot-stripes" />
          <div className="ix-shot-label">
            <span className="ix-shot-frame">▢</span>
            <span className="ix-shot-name">{label}</span>
            {hint && <span className="ix-shot-hint">{hint}</span>}
          </div>
        </>
      )}
    </div>
  );
}

/* ---- Image gallery with prev/next, dots, and click-to-enlarge lightbox ---- */
function Gallery({ images, label, hint }) {
  const [i, setI] = React.useState(0);
  const [zoom, setZoom] = React.useState(false);
  const has = images && images.length > 0;
  const count = has ? images.length : 0;

  const go = (dir) => setI((n) => (n + dir + count) % count);   // wraps around

  // arrow keys flip photos while zoomed
  React.useEffect(() => {
    if (!zoom) return;
    const onKey = (e) => {
      if (e.key === "ArrowLeft") go(-1);
      else if (e.key === "ArrowRight") go(1);
      else if (e.key === "Escape") setZoom(false);
    };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [zoom, count]);

  return (
    <div className="ix-gallery">
      <div
        className="ix-gallery-frame"
        onClick={(e) => { if (has) { e.stopPropagation(); setZoom(true); } }}
      >
        <Shot
          label={label}
          src={has ? images[i] : undefined}
          hint={hint}
          aspect="auto"
          big={true}
          rounded={false}
        />
        {has && <span className="ix-gal-zoom" aria-hidden="true">⤢</span>}
      </div>

      {count > 1 && (
        <>
          <button
            className="ix-gal-arrow ix-gal-prev"
            onClick={(e) => { e.stopPropagation(); go(-1); }}
            aria-label="Previous image"
          >‹</button>
          <button
            className="ix-gal-arrow ix-gal-next"
            onClick={(e) => { e.stopPropagation(); go(1); }}
            aria-label="Next image"
          >›</button>

          <div className="ix-gal-dots">
            {images.map((_, n) => (
              <button
                key={n}
                className={"ix-gal-dot" + (n === i ? " on" : "")}
                onClick={(e) => { e.stopPropagation(); setI(n); }}
                aria-label={"Go to image " + (n + 1)}
              />
            ))}
          </div>
        </>
      )}

      {zoom && (
        <div className="ix-lightbox" onClick={(e) => { e.stopPropagation(); setZoom(false); }}>
          <button className="ix-lightbox-close" aria-label="Close">✕</button>
          <img
            className="ix-lightbox-img"
            src={images[i]}
            alt={label}
            onClick={(e) => e.stopPropagation()}
          />
          {count > 1 && (
            <>
              <button
                className="ix-gal-arrow ix-gal-prev"
                onClick={(e) => { e.stopPropagation(); go(-1); }}
                aria-label="Previous image"
              >‹</button>
              <button
                className="ix-gal-arrow ix-gal-next"
                onClick={(e) => { e.stopPropagation(); go(1); }}
                aria-label="Next image"
              >›</button>
            </>
          )}
        </div>
      )}
    </div>
  );
}

/* NEW / TOP 10 style badge */
function Badge({ kind }) {
  if (kind === "TOP 10") {
    return (
      <span className="ix-badge ix-badge-top">
        <span className="ix-badge-top-box">TOP<br/>10</span>
        <span className="ix-badge-top-text">in Projects today</span>
      </span>
    );
  }
  return <span className="ix-badge ix-badge-new">{kind}</span>;
}

function MatchPct({ value }) {
  return <span className="ix-match">{value}% Match</span>;
}

function RatingPill({ text }) {
  return <span className="ix-rating">{text}</span>;
}

/* 5-dot proficiency meter */
function LevelDots({ level }) {
  return (
    <span className="ix-dots" aria-label={level + " of 5"}>
      {[1, 2, 3, 4, 5].map((n) => (
        <span key={n} className={"ix-dot" + (n <= level ? " on" : "")} />
      ))}
    </span>
  );
}

function ProgressBar({ value }) {
  return (
    <div className="ix-progress">
      <div className="ix-progress-fill" style={{ width: value + "%" }} />
    </div>
  );
}

/* ---- Standard title card (projects, education, work) ---- */
function TitleCard({ item, playful, onOpen, showProgress }) {
  return (
    <button className="ix-card" onClick={() => onOpen(item)}>
      <div className="ix-card-art">
        <Shot
          label={item.shot}
          src={item.image || (item.images && item.images[0])}
          hint={item.runtime}
        />
        {playful && item.badges && item.badges.map((b) => (
          <span key={b} className="ix-card-badge"><Badge kind={b} /></span>
        ))}
        {playful && item.rating && (
          <span className="ix-card-rating">{item.rating}</span>
        )}
        {showProgress && typeof item.progress === "number" && (
          <div className="ix-card-progress"><ProgressBar value={item.progress} /></div>
        )}
      </div>
      <div className="ix-card-hover">
        <div className="ix-card-actions">
          <span className="ix-ico-btn ix-ico-play" aria-hidden="true">▶</span>
          <span className="ix-ico-btn" aria-hidden="true">+</span>
          <span className="ix-ico-btn ix-ico-more" aria-hidden="true">⌄</span>
        </div>
        <div className="ix-card-meta">
          {playful && <MatchPct value={item.match} />}
          <span className="ix-card-year">{item.year}</span>
        </div>
        <div className="ix-card-title">{item.title}</div>
        <div className="ix-card-genre">{item.genre || item.type}</div>
      </div>
    </button>
  );
}

/* ---- Skill card (maturity-rating styling) ---- */
function SkillCard({ item, playful }) {
  return (
    <div className="ix-skill">
      <div className="ix-skill-top">
        <span className="ix-skill-name">{item.name}</span>
        {playful && <span className="ix-skill-rating">{item.rating}</span>}
      </div>
      <Shot
        label={"skill · " + item.name.toLowerCase().split(" ")[0]}
        src={item.image}
        aspect="16/9"
      />
      <div className="ix-skill-body">
        <LevelDots level={item.level} />
        <span className="ix-skill-note">{item.note}</span>
      </div>
    </div>
  );
}

/* ---- My Week card (numbered, like episodes) ---- */
function DayCard({ item, index, playful }) {
  return (
    <div className="ix-day">
      <span className="ix-day-num">{index + 1}</span>
      <div className="ix-day-art">
        <Shot label={item.shot} src={item.image} aspect="16/10" />
        <span className="ix-day-emoji">{item.emoji}</span>
      </div>
      <div className="ix-day-text">
        <div className="ix-day-head">
          <span className="ix-day-title">{item.title}</span>
          {playful && <span className="ix-day-match">{item.match}%</span>}
        </div>
        <p className="ix-day-blurb">{item.blurb}</p>
      </div>
    </div>
  );
}

/* ---- Horizontal scrolling row with arrows ---- */
function Row({ title, anchor, children, variant }) {
  const ref = React.useRef(null);
  const scroll = (dir) => {
    const el = ref.current;
    if (!el) return;
    el.scrollBy({ left: dir * el.clientWidth * 0.86, behavior: "smooth" });
  };
  return (
    <section className="ix-row" id={anchor}>
      <h2 className="ix-row-title">{title}</h2>
      <div className="ix-row-viewport">
        <button className="ix-row-arrow left" onClick={() => scroll(-1)} aria-label="Scroll left">‹</button>
        <div className={"ix-row-track" + (variant ? " " + variant : "")} ref={ref}>
          {children}
        </div>
        <button className="ix-row-arrow right" onClick={() => scroll(1)} aria-label="Scroll right">›</button>
      </div>
    </section>
  );
}

Object.assign(window, {
  Shot, Gallery, Badge, MatchPct, RatingPill, LevelDots, ProgressBar,
  TitleCard, SkillCard, DayCard, Row,
});