// === Jairo Gallo — Photography Portfolio ===
// Concept: "The Photography Book"
const { useState, useEffect, useMemo, useCallback, useRef } = React;

// ── API helper ───────────────────────────────────────────────
async function apiFetch(path) {
  try {
    const r = await fetch(path);
    if (!r.ok) return null;
    return r.json();
  } catch { return null; }
}

// ── Scroll reveal hook ───────────────────────────────────────
function useReveal(delay) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (!window.IntersectionObserver) { el.classList.add("in"); return; }
    const obs = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) { el.classList.add("in"); obs.unobserve(el); }
    }, { threshold: 0.1, rootMargin: "0px 0px -40px 0px" });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return ref;
}

// ── Copy ─────────────────────────────────────────────────────
const COPY = {
  en: {
    nav: { work: "Work", collections: "Collections", about: "About", contact: "Contact" },
    hero: { tag: "Photography from Miami, Florida.", cta: "View the work", scroll: "Scroll" },
    work: { title: "Selected", em: "frames" },
    collections: { title: "Bodies of", em: "work" },
    view: "View collection",
    frames: "frames",
    bio: {
      label: "About",
      lines: [
        "My interest in photography was not something from nothing, it was not born in the morning, it is something that I had always been excited about from a very young age, photography is an image saved at a precise moment taken with a camera.",
        "Photography makes me perceive and transmit what I see and capture with the lens and the camera. An image endures in time because time stopped with the image."
      ],
      sign: "J. Gallo",
      stats: [
        { n: "18", l: "years shooting" },
        { n: "207", l: "published" },
        { n: "04", l: "collections" }
      ]
    },
    quote: "The best photographs are motivated by human feelings.",
    quoteAttr: "Jairo Gallo",
    contact: {
      title: "Get in", em: "touch",
      lead: "Available for editorial work, portrait sessions, and limited-edition prints.",
      phone: "+1 (305) 607-9894",
      city: "Miami, Florida, USA",
      cta: "Message on WhatsApp"
    },
    foot: { role: "Photographer / Author", year: "MMXXVI", rights: "All rights reserved" }
  },
  es: {
    nav: { work: "Obra", collections: "Colecciones", about: "Acerca", contact: "Contacto" },
    hero: { tag: "Fotografia desde Miami, Florida.", cta: "Ver el trabajo", scroll: "Desplaza" },
    work: { title: "Cuadros", em: "selectos" },
    collections: { title: "Cuerpos de", em: "obra" },
    view: "Ver coleccion",
    frames: "imagenes",
    bio: {
      label: "Acerca",
      lines: [
        "Mi interés por la fotografía no fue algo de la nada, no nació por la mañana, es algo que siempre me había emocionado desde muy pequeño, fotografía es una imagen guardada en un preciso momento y tomada con una cámara.",
        "La fotografía me hace percibir y transmitir lo que yo veo y capturo con el lente y la cámara. Una imagen perdura en el tiempo porque el tiempo se detuvo con la imagen."
      ],
      sign: "J. Gallo",
      stats: [
        { n: "18", l: "anos disparando" },
        { n: "207", l: "publicadas" },
        { n: "04", l: "colecciones" }
      ]
    },
    quote: "Las mejores fotografías están motivadas por sentimientos humanos.",
    quoteAttr: "Jairo Gallo",
    contact: {
      title: "Hablemos", em: "",
      lead: "Disponible para trabajo editorial, sesiones de retrato e impresiones de edicion limitada.",
      phone: "+1 (305) 607-9894",
      city: "Miami, Florida, USA",
      cta: "Mensaje por WhatsApp"
    },
    foot: { role: "Fotografo / Autor", year: "MMXXVI", rights: "Todos los derechos reservados" }
  }
};

const FALLBACK = {
  en: [
    { id: "nature",    name: "Nature",     count: 56, year: "2012", desc: "Leaves, light, water, the green pulse of things.",          seed: 2 },
    { id: "portraits", name: "Portraits",  count: 42, year: "2019", desc: "Faces, gestures, the quiet between words.",                 seed: 0 },
    { id: "landscapes",name: "Landscapes", count: 38, year: "2015", desc: "Andean horizons and the silence of vast space.",            seed: 1 },
    { id: "street",    name: "Street",     count: 71, year: "2010", desc: "City rhythm, strangers passing, accidental geometry.",      seed: 3 }
  ],
  es: [
    { id: "nature",    name: "Naturaleza", count: 56, year: "2012", desc: "Hojas, luz, agua, el pulso verde de las cosas.",            seed: 2 },
    { id: "portraits", name: "Retratos",   count: 42, year: "2019", desc: "Rostros, gestos, el silencio entre palabras.",              seed: 0 },
    { id: "landscapes",name: "Paisajes",   count: 38, year: "2015", desc: "Horizontes andinos y el silencio del espacio.",             seed: 1 },
    { id: "street",    name: "Calle",      count: 71, year: "2010", desc: "Ritmo urbano, transeuentes, geometria casual.",             seed: 3 }
  ]
};

// ── Featured grid — adaptive editorial composition (1–6 cells) ─
function FeaturedGrid({ photos, labels, onOpen }) {
  const count = Math.min(photos.length, 6);
  if (count >= 1) {
    return (
      <div className={"featured-grid fg-" + count}>
        {photos.slice(0, 6).map((p, i) => (
          <div key={p.id} className={"gi gi-" + i}
            role="button" tabIndex={0}
            onClick={() => onOpen && onOpen(i)}
            onKeyDown={e => e.key === "Enter" && onOpen && onOpen(i)}>
            <img src={p.url} alt={p.title || "Photograph by Jairo Gallo"} />
          </div>
        ))}
      </div>
    );
  }
  // Preview state — no real photos yet
  return (
    <div className="featured-grid fg-6">
      {labels.map((lb, i) => (
        <div key={i} className={"gi gi-" + i}>
          <PhotoPlaceholder seed={i + 5} ratio="4/3" showCap={false} />
        </div>
      ))}
    </div>
  );
}

// ── Collection card — cover with overlaid title ───────────────
function CollectionCard({ c, idx, cover, featured, t, onOpen }) {
  const ref = useReveal();
  return (
    <div ref={ref} className={"coll-card reveal" + (featured ? " featured" : "")}
      role="button" tabIndex={0}
      onClick={onOpen} onKeyDown={e => e.key === "Enter" && onOpen()}>
      <div className="coll-card-photo">
        {cover
          ? <img src={cover.url} alt={c.name} />
          : <PhotoPlaceholder seed={c.seed ?? idx} ratio={featured ? "5/2" : "3/2"} showCap={false} />
        }
      </div>
      <div className="coll-card-body">
        <div className="coll-card-meta">{c.year} &middot; {c.count} {t.frames}</div>
        <h3 className="coll-card-name">{c.name}</h3>
        <span className="coll-card-cta">{t.view} <span className="arrow">&#8594;</span></span>
      </div>
    </div>
  );
}

// ── Collection overlay + lightbox ─────────────────────────────
function CollectionView({ collection, photos, lang, t, onClose }) {
  const [lb, setLb] = useState(null); // lightbox index, or null

  useEffect(() => {
    document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = ""; };
  }, []);

  useEffect(() => {
    const fn = e => {
      if (e.key === "Escape") { lb !== null ? setLb(null) : onClose(); }
      else if (lb !== null && e.key === "ArrowRight") setLb(i => (i + 1) % photos.length);
      else if (lb !== null && e.key === "ArrowLeft")  setLb(i => (i - 1 + photos.length) % photos.length);
    };
    window.addEventListener("keydown", fn);
    return () => window.removeEventListener("keydown", fn);
  }, [lb, photos.length, onClose]);

  const cur = lb !== null ? photos[lb] : null;
  const next = () => setLb(i => (i + 1) % photos.length);
  const prev = () => setLb(i => (i - 1 + photos.length) % photos.length);

  return (
    <div className="coll-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="coll-overlay-panel">
        <div className="coll-overlay-head">
          <button className="coll-back-btn" onClick={onClose}>
            {lang === "en" ? "Back" : "Volver"}
          </button>
          <div className="coll-overlay-meta">
            <h2>{collection.name}</h2>
            <span className="n">{photos.length} {t.frames}</span>
          </div>
          <button className="coll-close-btn" onClick={onClose} aria-label="Close">&#x2715;</button>
        </div>
        <div className="coll-overlay-grid">
          {photos.length > 0
            ? photos.map((p, idx) => (
                <div className="coll-overlay-item" key={p.id}
                  role="button" tabIndex={0}
                  onClick={() => setLb(idx)}
                  onKeyDown={e => e.key === "Enter" && setLb(idx)}>
                  <img src={p.url} alt={p.title || p.filename} loading="lazy" />
                </div>
              ))
            : <div className="coll-empty">
                {lang === "en" ? "No photos in this collection yet." : "Sin fotos en esta coleccion aun."}
              </div>
          }
        </div>
      </div>

      {cur && (
        <div className="lightbox" onClick={e => e.target === e.currentTarget && setLb(null)}>
          <button className="lb-close" onClick={() => setLb(null)} aria-label="Close">&#x2715;</button>
          {photos.length > 1 && (
            <button className="lb-nav prev" onClick={prev} aria-label="Previous">&#8592;</button>
          )}
          <figure className="lb-figure">
            <img key={cur.id} src={cur.url} alt={cur.title || cur.filename} />
            <figcaption>
              {cur.title && <span className="lb-title">{cur.title}</span>}
              <span className="lb-count">{lb + 1} / {photos.length}</span>
            </figcaption>
          </figure>
          {photos.length > 1 && (
            <button className="lb-nav next" onClick={next} aria-label="Next">&#8594;</button>
          )}
        </div>
      )}
    </div>
  );
}

// ── Root ─────────────────────────────────────────────────────
function App() {
  const [lang, setLang] = useState(() => {
    try { return localStorage.getItem("jg.lang") || "en"; } catch { return "en"; }
  });
  const [apiCollections, setApiCollections] = useState(null);
  const [apiBio, setApiBio]                 = useState(null);
  const [allPhotos, setAllPhotos]           = useState([]);
  const [featuredPhotos, setFeaturedPhotos] = useState([]);
  const [openColl, setOpenColl]             = useState(null);

  const t = COPY[lang];

  useEffect(() => {
    try { localStorage.setItem("jg.lang", lang); } catch {}
  }, [lang]);

  useEffect(() => {
    const fn = e => { if (e.data?.type === "__jg_lang") setLang(e.data.lang); };
    window.addEventListener("message", fn);
    return () => window.removeEventListener("message", fn);
  }, []);
  useEffect(() => { window.__jg_setLang = setLang; }, []);

  useEffect(() => {
    apiFetch("/api/collections.php").then(d => d && setApiCollections(d));
    apiFetch("/api/bio.php").then(d => d && setApiBio(d));
    apiFetch("/api/photos.php").then(d => {
      if (d) {
        setAllPhotos(d);
        setFeaturedPhotos(d.filter(p => p.featured).slice(0, 6));
      }
    });
  }, []);

  const collections = useMemo(() => {
    if (!apiCollections || !apiCollections.length) return FALLBACK[lang];
    return apiCollections.map((c, i) => ({
      id:    c.slug || String(c.id),
      apiId: c.id,
      name:  lang === "es" ? (c.name_es || c.name_en) : (c.name_en || c.name_es),
      count: c.photo_count ?? 0,
      year:  c.year ? String(c.year) : "ongoing",
      desc:  lang === "es" ? (c.description_es || c.description_en || "")
                           : (c.description_en || c.description_es || ""),
      seed:  i
    }));
  }, [apiCollections, lang]);

  const byCollection = useMemo(() => {
    const map = {};
    for (const p of allPhotos) {
      const k = String(p.collection_id);
      if (!map[k]) map[k] = [];
      map[k].push(p);
    }
    return map;
  }, [allPhotos]);

  const openCollection = useCallback((c) => {
    const k = String(c.apiId ?? c.id);
    setOpenColl({ collection: c, photos: byCollection[k] || [] });
  }, [byCollection]);

  const openFeatured = useCallback(() => {
    setOpenColl({
      collection: { name: lang === "en" ? "Selected frames" : "Cuadros selectos" },
      photos: featuredPhotos
    });
  }, [featuredPhotos, lang]);

  const bioLines = useMemo(() => {
    if (!apiBio) return t.bio.lines;
    const raw = lang === "es" ? apiBio.bio_es : apiBio.bio_en;
    if (!raw?.trim()) return t.bio.lines;
    return raw.split(/\n+/).filter(Boolean);
  }, [apiBio, lang, t.bio.lines]);

  const quote = useMemo(() => {
    if (!apiBio) return t.quote;
    const raw = lang === "es" ? apiBio.quote_es : apiBio.quote_en;
    return raw?.trim() || t.quote;
  }, [apiBio, lang, t.quote]);

  const heroPhoto = featuredPhotos[0] || null;
  const portraitUrl = apiBio && apiBio.portrait_url ? apiBio.portrait_url : null;

  // Live stats — real where we can, derived from loaded data
  const liveStats = useMemo(() => ([
    { n: "18", l: t.bio.stats[0].l },
    { n: allPhotos.length ? String(allPhotos.length) : t.bio.stats[1].n, l: t.bio.stats[1].l },
    { n: String(collections.length).padStart(2, "0"), l: t.bio.stats[2].l },
  ]), [allPhotos.length, collections.length, t.bio.stats]);

  const workRef    = useReveal();
  const bioRef     = useReveal();
  const contactRef = useReveal();

  // Nav goes solid once the hero photo is scrolled past the bar
  const heroRef = useRef(null);
  const [navSolid, setNavSolid] = useState(false);
  useEffect(() => {
    const el = heroRef.current;
    if (!el || !window.IntersectionObserver) { setNavSolid(true); return; }
    const obs = new IntersectionObserver(
      ([e]) => setNavSolid(!e.isIntersecting),
      { rootMargin: "-64px 0px 0px 0px", threshold: 0 }
    );
    obs.observe(el);
    return () => obs.disconnect();
  }, []);

  const featLabels = lang === "en"
    ? ["Highland morning","Portrait, Ana","Avenida 19","Fern study","Cordillera","Window light"]
    : ["Manana andina","Retrato, Ana","Avenida 19","Estudio helecho","Cordillera","Luz de ventana"];

  return (
    <>
      {/* NAV */}
      <header className={"topbar" + (navSolid ? " solid" : "")}>
        <div className="brand">Jairo <em>Gallo</em></div>
        <nav>
          <a href="#work">{t.nav.work}</a>
          <a href="#collections">{t.nav.collections}</a>
          <a href="#about">{t.nav.about}</a>
          <a href="#contact">{t.nav.contact}</a>
        </nav>
        <div className="tools">
          <div className="lang-toggle">
            <button className={lang === "en" ? "active" : ""} onClick={() => setLang("en")}>EN</button>
            <button className={lang === "es" ? "active" : ""} onClick={() => setLang("es")}>ES</button>
          </div>
        </div>
      </header>

      {/* HERO — full-bleed photograph */}
      <section className="hero" ref={heroRef}>
        <div className="hero-photo">
          {heroPhoto
            ? <img src={heroPhoto.url} alt="Featured photograph by Jairo Gallo" />
            : <PhotoPlaceholder seed={3} ratio="3/4" showCap={false} />
          }
        </div>

        <div className="hero-content">
          <span className="hero-kicker">{lang === "en" ? "Photographer" : "Fotografo"}</span>
          <h1 className="hero-name">
            <span className="line-one">Jairo</span>
            <span className="line-two">Gallo.</span>
          </h1>
          <p className="hero-tag">{t.hero.tag}</p>
          <div className="hero-cta">
            <a className="btn light" href="#work">
              {t.hero.cta} <span className="arrow">&#8594;</span>
            </a>
            <span className="hero-location">Miami, FL &middot; Est. 2008</span>
          </div>
        </div>
      </section>

      {/* MARQUEE */}
      <div className="marquee-strip">
        <div className="marquee-track">
          <span>Nature</span><span className="sep" />
          <span>Portraits</span><span className="sep" />
          <span>Landscapes</span><span className="sep" />
          <span>Street</span><span className="sep" />
          <span>Miami, FL</span><span className="sep" />
          <span>35mm</span><span className="sep" />
          <span>Digital</span><span className="sep" />
          <span>Film</span><span className="sep" />
          <span>Editorial</span><span className="sep" />
          <span>Print</span><span className="sep" />
          <span>Est. 2008</span><span className="sep" />
          {/* duplicate */}
          <span>Nature</span><span className="sep" />
          <span>Portraits</span><span className="sep" />
          <span>Landscapes</span><span className="sep" />
          <span>Street</span><span className="sep" />
          <span>Miami, FL</span><span className="sep" />
          <span>35mm</span><span className="sep" />
          <span>Digital</span><span className="sep" />
          <span>Film</span><span className="sep" />
          <span>Editorial</span><span className="sep" />
          <span>Print</span><span className="sep" />
          <span>Est. 2008</span><span className="sep" />
        </div>
      </div>

      {/* FEATURED WORK */}
      <section id="work" className="work-section">
        <div ref={workRef} className="reveal">
          <div className="work-header">
            <h2>
              {t.work.title} <em>{t.work.em}</em>
            </h2>
            {featuredPhotos.length > 0 && (
              <span className="count">{featuredPhotos.length} {t.frames}</span>
            )}
          </div>
          <FeaturedGrid photos={featuredPhotos} labels={featLabels} onOpen={openFeatured} />
        </div>
      </section>

      {/* COLLECTIONS */}
      <section id="collections" className="collections-section">
        <div className="collections-intro">
          <h2>{t.collections.title} <em>{t.collections.em}</em></h2>
        </div>
        <div className="collections-grid">
          {collections.map((c, i) => {
            const k = String(c.apiId ?? c.id);
            const cover = (byCollection[k] || [])[0];
            const featured = collections.length % 2 === 1 && i === 0;
            return (
              <CollectionCard
                key={c.id}
                c={c}
                idx={i}
                cover={cover}
                featured={featured}
                t={t}
                onOpen={() => openCollection(c)}
              />
            );
          })}
        </div>
      </section>

      {/* BIO */}
      <section id="about" className="bio-section">
        <span className="bio-eyebrow">{t.bio.label}</span>
        <div ref={bioRef} className="bio-layout reveal">
          <div className="bio-portrait-wrap">
            {portraitUrl
              ? <img src={portraitUrl} alt="Jairo Gallo" />
              : <PhotoPlaceholder seed={0} ratio="4/5" showCap={false} />}
            <div className="bio-stats-row">
              {liveStats.map((s, i) => (
                <div className="bio-stat" key={i}>
                  <span className="bio-stat-n">{s.n}</span>
                  <span className="bio-stat-l">{s.l}</span>
                </div>
              ))}
            </div>
          </div>
          <div className="bio-copy">
            {bioLines.map((line, i) => <p key={i}>{line}</p>)}
            <div className="bio-sign">{t.bio.sign}</div>
          </div>
        </div>
      </section>

      {/* PULL QUOTE */}
      <div className="pull-quote">
        <div className="mark">"</div>
        <blockquote>{quote}</blockquote>
        <p className="attr">{t.quoteAttr}</p>
      </div>

      {/* CONTACT */}
      <section id="contact" className="contact-section">
        <div ref={contactRef} className="reveal">
          <div className="contact-grid">
            <div className="contact-left">
              <h2 className="contact-heading">
                {t.contact.title}
                {t.contact.em && <> <em>{t.contact.em}</em></>}
              </h2>
              <p className="contact-lead">{t.contact.lead}</p>
            </div>
            <div className="contact-card">
              <div className="contact-row">
                <span className="lbl">Instagram</span>
                <a className="val" href="https://www.instagram.com/gallo_azul_blanco/"
                  target="_blank" rel="noopener noreferrer">
                  @gallo_azul_blanco &#x2197;
                </a>
              </div>
              <div className="contact-row">
                <span className="lbl">WhatsApp</span>
                <a className="val" href="https://wa.me/13056079894">{t.contact.phone}</a>
              </div>
              <div className="contact-row">
                <span className="lbl">{lang === "en" ? "Studio" : "Estudio"}</span>
                <span className="val">{t.contact.city}</span>
              </div>
              <div className="contact-btn-wrap">
                <a className="btn" href="https://wa.me/13056079894">
                  {t.contact.cta} <span className="arrow">&#8594;</span>
                </a>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* COLLECTION OVERLAY */}
      {openColl && (
        <CollectionView
          collection={openColl.collection}
          photos={openColl.photos}
          lang={lang}
          t={t}
          onClose={() => setOpenColl(null)}
        />
      )}

      {/* FOOTER */}
      <footer className="site-foot">
        <div className="foot-brand">
          <div className="brand-mark">Jairo <em>Gallo</em></div>
          <div className="sub">{t.foot.role}</div>
          <div className="foot-tagline">{t.hero.tag}</div>
        </div>
        <div>
          <h4>{lang === "en" ? "Navigate" : "Navegar"}</h4>
          <ul>
            <li><a href="#work">{t.nav.work}</a></li>
            <li><a href="#collections">{t.nav.collections}</a></li>
            <li><a href="#about">{t.nav.about}</a></li>
            <li><a href="#contact">{t.nav.contact}</a></li>
          </ul>
        </div>
        <div>
          <h4>{lang === "en" ? "Connect" : "Contacto"}</h4>
          <ul>
            <li>
              <a href="https://www.instagram.com/gallo_azul_blanco/"
                target="_blank" rel="noopener noreferrer">
                Instagram &#x2197;
              </a>
            </li>
            <li><a href="https://wa.me/13056079894">WhatsApp &#x2197;</a></li>
            <li className="foot-city">{t.contact.city}</li>
          </ul>
        </div>
        <div className="colophon">
          <span>&#169; {t.foot.year} Jairo Gallo</span>
          <span>{t.foot.rights}</span>
        </div>
      </footer>
    </>
  );
}

window.JGApp = App;
