/* Galleries: People (editorial stack), Food (mosaic), Predmet (airy grid).
   Each sets its own --accent and uses a distinct layout. Real photos open in
   the lightbox; empty cells are fillable <image-slot> placeholders. */

/* Scales a display title to exactly fit its container width (caps at max).
   Fixes long words like "Предметка" overflowing the vw-based clamp. */
function FitTitle({ text, max = 260, min = 38 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const fit = () => {
      const avail = el.parentElement ? el.parentElement.clientWidth : 0;
      if (!avail) return;
      let lo = min, hi = max;
      el.style.whiteSpace = "nowrap";
      for (let i = 0; i < 20; i++) {
        const mid = (lo + hi) / 2;
        el.style.fontSize = mid + "px";
        if (el.scrollWidth <= avail) lo = mid; else hi = mid;
      }
      el.style.fontSize = Math.floor(lo) + "px";
    };
    fit();
    const ro = new ResizeObserver(fit); ro.observe(document.body);
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(fit);
    return () => ro.disconnect();
  }, [text]);
  return <h1 ref={ref} className="mega">{text}</h1>;
}

function GalleryIntro({ g }) {
  const real = g.photos.length, total = real + g.slots;
  return (
    <section className="gal-intro">
      <Reveal><div className="kicker">{g.kicker}</div></Reveal>
      <Reveal delay={60}><FitTitle text={g.title} /></Reveal>
      <div className="gal-meta">
        <Reveal><span className="gal-mood">{g.mood}</span></Reveal>
        <Reveal delay={50}><p className="gal-lead">{g.lead}</p></Reveal>
        <Reveal delay={90}><span className="gal-count">{String(total).padStart(2, "0")} работ · {real} в галерее</span></Reveal>
      </div>
    </section>
  );
}

function Slot({ id, label, ratio, style = {} }) {
  return (
    <Reveal img style={{ aspectRatio: ratio, ...style }}>
      <image-slot id={id} placeholder={label || "Добавить фото"} shape="rect"
        style={{ width: "100%", height: "100%", display: "block" }}></image-slot>
    </Reveal>
  );
}

/* ---------------- PEOPLE — editorial alternating stack ---------------- */
function PeopleGallery() {
  const g = window.SITE.galleries.people;
  const P = g.photos;
  const ph = (i, aspect, cls) => <Photo item={P[i]} list={P} index={i} num={i + 1} aspect={aspect} className={cls} noInfo />;
  const duo = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 34, alignItems: "start" };
  return (
    <div className="page page-fade" style={{ "--accent": g.accent }}>
      <GalleryIntro g={g} />
      <section className="people-grid">
        {/* opener — first photo with text, kept as-is */}
        <div className="people-row r1">
          <Photo item={P[0]} list={P} index={0} num={1} className="tall" aspect="4/5" />
          <div className="people-side">
            <Reveal><p className="q">«Хороший портрет — это про характер, а не про позу.»</p></Reveal>
            <Reveal delay={60}><div className="num n cred"><span className="cred-seg">Живой&nbsp;свет · мягкая&nbsp;ретушь</span><span className="cred-seg">ваш&nbsp;темп</span></div></Reveal>
          </div>
        </div>

        <div className="people-row r2">
          {ph(1, "4/5")}
          {ph(2, "4/5")}
        </div>

        <div style={duo}>
          {ph(5, "3/2")}
          {ph(6, "3/2")}
        </div>

        <div className="people-row r1">
          {ph(3, "4/5")}
          {ph(4, "4/5")}
        </div>

        <div className="people-row r2">
          {ph(7, "4/5")}
          {ph(8, "4/5")}
        </div>

        <div className="people-row r1">
          {ph(9, "4/5")}
          {ph(10, "4/5")}
        </div>

        <div className="people-row r2">
          {ph(11, "4/5")}
          {ph(12, "3/2")}
        </div>
      </section>
      <GalleryFoot navTo="food" next="Food" />
    </div>
  );
}

/* ---------------- FOOD — warm mosaic ---------------- */
function FoodGallery() {
  const g = window.SITE.galleries.food;
  const P = g.photos;
  // grid spans: [colSpan, rowSpan] — all cells are real photos now
  const cells = [
    { i: 0, c: "span 3", r: "span 3" },
    { i: 1, c: "span 3", r: "span 2" },
    { i: 2, c: "span 2", r: "span 2" },
    { i: 3, c: "span 1", r: "span 2" },
    { i: 4, c: "span 2", r: "span 3" },
    { i: 5, c: "span 4", r: "span 2" },
    { i: 6, c: "span 3", r: "span 2" },
    { i: 7, c: "span 3", r: "span 2" },
  ];
  return (
    <div className="page page-fade" style={{ "--accent": g.accent }}>
      <GalleryIntro g={g} />
      <section className="food-grid">
        {cells.map((cell, k) => (
          <div key={k} style={{ gridColumn: cell.c, gridRow: cell.r }}>
            <Photo item={P[cell.i]} list={P} index={cell.i} num={cell.i + 1} noInfo style={{ height: "100%" }} />
          </div>
        ))}
      </section>
      <GalleryFoot navTo="predmet" next="Предметка" />
    </div>
  );
}

/* ---------------- PREDMET — airy minimal grid ---------------- */
function PredmetGallery() {
  const g = window.SITE.galleries.predmet;
  const P = g.photos;
  const cells = [
    { col: "1 / 7",  ratio: "4/5" },
    { col: "8 / 13", ratio: "4/5" },
    { col: "1 / 8",  ratio: "16/10" },
    { col: "9 / 13", ratio: "3/4" },
    { col: "1 / 5",  ratio: "4/5" },
    { col: "6 / 13", ratio: "16/10" },
    { col: "1 / 5",  ratio: "3/4" },
    { col: "6 / 13", ratio: "16/10" },
    { col: "1 / 7",  ratio: "4/5" },
    { col: "8 / 13", ratio: "4/5" },
    { col: "1 / 8",  ratio: "16/10" },
    { col: "9 / 13", ratio: "3/4" },
  ];
  return (
    <div className="page page-fade" style={{ "--accent": g.accent }}>
      <GalleryIntro g={g} />
      <section className="predmet-grid">
        {cells.map((cell, k) => (
          <div className="predmet-cell" key={k} style={{ "--col": cell.col }}>
            <Photo item={P[k]} list={P} index={k} num={k + 1} aspect={cell.ratio} noInfo />
          </div>
        ))}
      </section>
      <GalleryFoot navTo="services" next="Услуги" />
    </div>
  );
}

function GalleryFoot({ navTo, next }) {
  const nav = window.__navigate;
  return (
    <footer className="foot">
      <Reveal><div className="big" style={{ color: "var(--text-dim)" }}>Дальше</div></Reveal>
      <Reveal delay={60}>
        <a data-cursor data-cursor-label="Перейти" onClick={() => nav && nav(navTo)} className="big" style={{ color: "var(--accent)", display: "inline-flex", alignItems: "center", gap: 18 }}>
          {next} {Icon.arrow({ style: { width: 40, height: 40, stroke: "currentColor" } })}
        </a>
      </Reveal>
    </footer>
  );
}

Object.assign(window, { PeopleGallery, FoodGallery, PredmetGallery });
