/* ==============================================================
   Jacksonville Site Works — Project Gallery + Testimonials
   ============================================================== */

/* ------------------------------------------------------------------ */
/*  WORK GALLERY — filter + lightbox                                    */
/* ------------------------------------------------------------------ */
function Work() {
  const projects = [
    {
      id: "p01", title: "Mandarin homesite", county: "Duval", acres: "3.2",
      cat: "Clearing", year: "2025",
      ph: window.PHOTOS.p01,
      phLabel: "MANDARIN ⋅ 3.2 AC",
      notes: "Full clear-and-grub. Saved 14 mature oaks per owner request.",
    },
    {
      id: "p02", title: "Twin Lakes mulching", county: "Clay", acres: "11.0",
      cat: "Mulching", year: "2025",
      ph: window.PHOTOS.p02,
      phLabel: "TWIN LAKES ⋅ 11 AC",
      notes: "Selective understory mulching for hunting lanes and firebreaks.",
    },
    {
      id: "p03", title: "St. Johns subdivision", county: "St. Johns", acres: "42.5",
      cat: "Excavation", year: "2024",
      ph: window.PHOTOS.p03,
      phLabel: "ST. JOHNS ⋅ 42 AC ⋅ 28 PADS",
      notes: "Full clear + 28 building pads cut to grade in 6 weeks.",
    },
    {
      id: "p04", title: "Storm response — Helene", county: "Duval", acres: "—",
      cat: "Tree Removal", year: "2024",
      ph: window.PHOTOS.p04,
      phLabel: "STORM CLEANUP ⋅ ATLANTIC BLVD",
      notes: "Emergency roadside cleanup along Atlantic Blvd after Helene. Crew on-site within 6 hours of call.",
    },
    {
      id: "p05", title: "Pasture conversion", county: "Baker", acres: "27.0",
      cat: "Clearing", year: "2024",
      ph: window.PHOTOS.p05,
      phLabel: "MACCLENNY ⋅ 27 AC",
      notes: "Scrub-to-pasture conversion. Seeded for bahia within 30 days.",
    },
    {
      id: "p06", title: "Driveway + pond", county: "Clay", acres: "6.4",
      cat: "Excavation", year: "2024",
      ph: window.PHOTOS.p06,
      phLabel: "MIDDLEBURG ⋅ 1/2 AC POND",
      notes: "800-ft driveway + half-acre stocked pond with overflow swale.",
    },
    {
      id: "p07", title: "Commercial lot prep", county: "Duval", acres: "8.8",
      cat: "Clearing", year: "2023",
      ph: window.PHOTOS.p07,
      phLabel: "WESTSIDE JAX ⋅ 8.8 AC",
      notes: "Wooded commercial parcel cleared to bare pad in 9 working days.",
    },
    {
      id: "p08", title: "Trail system", county: "St. Johns", acres: "55.0",
      cat: "Mulching", year: "2023",
      ph: window.PHOTOS.p08,
      phLabel: "HASTINGS ⋅ 4 MI TRAILS",
      notes: "Four miles of 12-ft equestrian trails through palmetto scrub.",
    },
  ];

  const cats = ["All", "Clearing", "Mulching", "Excavation", "Tree Removal"];
  const [filter, setFilter] = useState("All");
  const [open, setOpen] = useState(null); // project id

  const filtered = filter === "All" ? projects : projects.filter(p => p.cat === filter);

  // Keyboard nav for lightbox
  useEffect(() => {
    if (!open) return;
    const idx = filtered.findIndex(p => p.id === open);
    const onKey = (e) => {
      if (e.key === "Escape") setOpen(null);
      if (e.key === "ArrowRight") setOpen(filtered[(idx + 1) % filtered.length].id);
      if (e.key === "ArrowLeft")  setOpen(filtered[(idx - 1 + filtered.length) % filtered.length].id);
    };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [open, filtered]);

  const openProject = filtered.find(p => p.id === open);

  return (
    <section id="work" className="work section-pad">
      <div className="container">
        <div className="section-header">
          <div>
            <div className="eyebrow"><span className="dot" />Recent work / 03</div>
            <h2 className="h-display" style={{ marginTop: 20 }}>
              Dirt under<br/>our nails.
            </h2>
          </div>
          <p className="lede">
            A few jobs from the last two seasons. Every site is photographed daily —
            ask us for the full set during your quote.
          </p>
        </div>

        <div className="work-filter">
          <div className="wf-left mono">FILTER ⋅</div>
          <div className="wf-cats">
            {cats.map(c => (
              <button
                key={c}
                className={`wf-cat ${filter === c ? "is-on" : ""}`}
                onClick={() => setFilter(c)}
              >
                {c}
                <span className="wf-count">
                  {c === "All" ? projects.length : projects.filter(p => p.cat === c).length}
                </span>
              </button>
            ))}
          </div>
          <div className="wf-right mono">{filtered.length} project{filtered.length === 1 ? "" : "s"}</div>
        </div>

        <div className="work-grid">
          {filtered.map((p, i) => (
            <button
              key={p.id}
              className={`work-card ${i === 0 ? "is-feature" : ""}`}
              onClick={() => setOpen(p.id)}
              aria-label={`Open project ${p.title}`}
            >
              <Photo src={p.ph} label={p.phLabel} className="work-ph" />
              <div className="work-meta">
                <div className="wm-cat mono">{p.cat} ⋅ {p.year}</div>
                <h3 className="h-head wm-title">{p.title}</h3>
                <div className="wm-foot mono">
                  <span>{p.county} County</span>
                  <span>{p.acres === "—" ? "Residential" : `${p.acres} ac`}</span>
                </div>
              </div>
              <span className="work-zoom" aria-hidden="true">+</span>
            </button>
          ))}
        </div>
      </div>

      {openProject && (
        <div className="lightbox" onClick={() => setOpen(null)}>
          <div className="lb-inner" onClick={e => e.stopPropagation()}>
            <button className="lb-close" onClick={() => setOpen(null)} aria-label="Close">×</button>
            <Photo src={openProject.ph} label={openProject.phLabel} className="lb-photo" />
            <div className="lb-body">
              <div className="lb-meta mono">
                {openProject.cat} ⋅ {openProject.county} County ⋅ {openProject.year}
              </div>
              <h3 className="h-display lb-title">{openProject.title}</h3>
              <div className="lb-row">
                <div>
                  <div className="lb-k mono">Acreage</div>
                  <div className="lb-v">{openProject.acres === "—" ? "Residential" : `${openProject.acres} acres`}</div>
                </div>
                <div>
                  <div className="lb-k mono">Scope</div>
                  <div className="lb-v">{openProject.cat}</div>
                </div>
                <div>
                  <div className="lb-k mono">Completed</div>
                  <div className="lb-v">{openProject.year}</div>
                </div>
              </div>
              <p className="lb-notes">{openProject.notes}</p>
              <div className="lb-nav mono">
                <span>← / → to browse</span>
                <span>ESC to close</span>
              </div>
            </div>
          </div>
        </div>
      )}

      <style>{`
        .work { background: var(--bg); border-top: 1px solid var(--line); }

        .work-filter {
          display: flex; align-items: center; gap: 24px;
          padding: 18px 0;
          border-top: 1px solid var(--line);
          border-bottom: 1px solid var(--line);
          margin-bottom: 32px;
          flex-wrap: wrap;
        }
        .wf-left, .wf-right {
          font-size: 11px; letter-spacing: 0.2em; color: var(--ink-4);
        }
        .wf-right { margin-left: auto; }
        .wf-cats { display: flex; gap: 4px; flex-wrap: wrap; }
        .wf-cat {
          background: transparent;
          border: 1px solid var(--line-2);
          color: var(--ink-3);
          font-family: var(--head);
          text-transform: uppercase;
          letter-spacing: 0.08em;
          font-size: 12px;
          padding: 10px 14px;
          display: inline-flex; align-items: center; gap: 8px;
          transition: all .15s ease;
        }
        .wf-cat:hover { color: var(--ink); border-color: var(--ink-4); }
        .wf-cat.is-on {
          background: var(--clay);
          border-color: var(--clay);
          color: var(--bg);
        }
        .wf-count {
          font-family: var(--mono);
          font-size: 10px;
          opacity: 0.7;
          padding: 2px 6px;
          background: rgba(0,0,0,0.15);
        }

        .work-grid {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 20px;
        }
        .work-card.is-feature {
          grid-column: span 2;
          grid-row: span 2;
        }
        .work-card {
          background: var(--bg-3);
          border: 1px solid var(--line);
          padding: 0;
          text-align: left;
          color: var(--ink);
          position: relative;
          overflow: hidden;
          transition: transform .25s ease, border-color .25s ease;
        }
        .work-card:hover {
          border-color: var(--clay);
          transform: translateY(-2px);
        }
        .work-ph {
          width: 100%;
          aspect-ratio: 4 / 3;
        }
        .work-card.is-feature .work-ph { aspect-ratio: auto; height: calc(100% - 100px); min-height: 360px; }

        .work-meta {
          padding: 18px 20px 20px;
          display: flex; flex-direction: column; gap: 6px;
        }
        .wm-cat { font-size: 10px; letter-spacing: 0.16em; color: var(--clay); }
        .wm-title { font-size: 22px; margin: 4px 0; color: var(--ink); }
        .work-card.is-feature .wm-title { font-size: 32px; }
        .wm-foot {
          display: flex; gap: 16px;
          font-size: 11px; letter-spacing: 0.14em;
          color: var(--ink-3);
          padding-top: 8px;
          border-top: 1px solid var(--line);
          margin-top: 4px;
        }

        .work-zoom {
          position: absolute;
          top: 12px; right: 12px;
          width: 36px; height: 36px;
          background: rgba(0,0,0,0.55);
          color: var(--ink);
          font-size: 22px;
          display: flex; align-items: center; justify-content: center;
          border: 1px solid rgba(255,255,255,0.1);
          z-index: 4;
          transition: background .15s ease, color .15s ease;
        }
        .work-card:hover .work-zoom { background: var(--clay); color: var(--bg); }

        /* Lightbox */
        .lightbox {
          position: fixed; inset: 0; z-index: 100;
          background: rgba(10,12,10,0.92);
          backdrop-filter: blur(8px);
          display: flex; align-items: center; justify-content: center;
          padding: 40px 20px;
          animation: lbIn .2s ease;
        }
        @keyframes lbIn { from { opacity: 0; } to { opacity: 1; } }

        .lb-inner {
          background: var(--bg-2);
          border: 1px solid var(--line-2);
          width: 100%; max-width: 1100px;
          max-height: 90vh;
          display: grid;
          grid-template-columns: 1.4fr 1fr;
          overflow: hidden;
          position: relative;
        }
        .lb-close {
          position: absolute; top: 12px; right: 12px; z-index: 5;
          width: 40px; height: 40px;
          background: rgba(0,0,0,0.6);
          border: 1px solid var(--line-2);
          color: var(--ink);
          font-size: 24px;
        }
        .lb-close:hover { background: var(--clay); color: var(--bg); }
        .lb-photo { width: 100%; height: 100%; min-height: 400px; }
        .lb-body { padding: 36px; overflow-y: auto; }
        .lb-meta { font-size: 11px; letter-spacing: 0.18em; color: var(--clay); }
        .lb-title { font-size: 48px; margin: 16px 0 28px; }
        .lb-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; padding-bottom: 24px; border-bottom: 1px solid var(--line); }
        .lb-k { font-size: 10px; letter-spacing: 0.18em; color: var(--ink-4); margin-bottom: 6px; }
        .lb-v { font-family: var(--head); text-transform: uppercase; letter-spacing: 0.04em; font-size: 15px; }
        .lb-notes { color: var(--ink-2); margin: 24px 0; line-height: 1.6; }
        .lb-nav {
          font-size: 10px; letter-spacing: 0.18em; color: var(--ink-4);
          display: flex; justify-content: space-between;
          padding-top: 18px; border-top: 1px solid var(--line);
        }

        @media (max-width: 900px) {
          .work-grid { grid-template-columns: 1fr 1fr; }
          .work-card.is-feature { grid-column: span 2; grid-row: auto; }
          .work-card.is-feature .work-ph { aspect-ratio: 4/3; min-height: 0; height: auto; }
          .lb-inner { grid-template-columns: 1fr; max-height: 95vh; }
          .lb-photo { min-height: 240px; }
          .lb-body { padding: 24px; }
          .lb-title { font-size: 32px; }
        }
        @media (max-width: 560px) {
          .work-grid { grid-template-columns: 1fr; }
          .work-card.is-feature { grid-column: auto; }
        }
      `}</style>
    </section>
  );
}

/* ------------------------------------------------------------------ */
/*  TESTIMONIALS — large editorial quote w/ thumbnails to switch        */
/* ------------------------------------------------------------------ */
function Reviews() {
  const reviews = [
    {
      quote: "Showed up when they said they would, finished a day early, and the price didn't move a dime from the original quote. I've used three clearing outfits in 20 years — these guys are the only ones I'll call again.",
      name: "Ray Holcomb",
      role: "General Contractor",
      project: "12-acre commercial lot ⋅ Westside Jax",
      rating: 5,
    },
    {
      quote: "Mulched 8 acres of palmetto and scrub oak in two days. Left the topsoil in shape to seed bahia immediately. No burn piles, no debris hauls, no headaches.",
      name: "Denise Faulkner",
      role: "Cattle owner",
      project: "Pasture conversion ⋅ Baker County",
      rating: 5,
    },
    {
      quote: "Had a 90-foot pine on the house after Hurricane Helene. Called Tuesday at noon, crew was on-site Wednesday morning. Tree gone, roof tarped, debris hauled, all in one visit.",
      name: "Marcus & Lily Tate",
      role: "Homeowners",
      project: "Storm response ⋅ Fernandina Beach",
      rating: 5,
    },
    {
      quote: "We bid out 42 acres to four contractors. JSW wasn't the cheapest — they were the most specific. Quote broke down every phase. Came in on budget on a six-week job.",
      name: "Cameron Liu",
      role: "Developer, Coastline Homes",
      project: "Subdivision prep ⋅ St. Johns County",
      rating: 5,
    },
  ];

  const [i, setI] = useState(0);
  const r = reviews[i];

  // auto-advance
  useEffect(() => {
    const id = setInterval(() => setI(x => (x + 1) % reviews.length), 8000);
    return () => clearInterval(id);
  }, []);

  return (
    <section id="reviews" className="reviews section-pad">
      <div className="container">
        <div className="rv-grid">
          <aside className="rv-aside">
            <div className="eyebrow"><span className="dot" />Reviews / 04</div>
            <h2 className="h-display rv-h">
              They've seen<br/>us work.
            </h2>
            <div className="rv-summary">
              <div className="rv-rate">
                <span className="rv-stars">★★★★★</span>
                <span className="rv-num h-display">4.9</span>
              </div>
              <div className="rv-from mono">
                from <strong>187 Google reviews</strong>
              </div>
            </div>
            <div className="rv-thumbs" role="tablist">
              {reviews.map((rev, n) => (
                <button
                  key={n}
                  role="tab"
                  aria-selected={i === n}
                  className={`rv-thumb ${i === n ? "is-on" : ""}`}
                  onClick={() => setI(n)}
                >
                  <span className="rt-n mono">0{n + 1}</span>
                  <span className="rt-name">{rev.name}</span>
                </button>
              ))}
            </div>
          </aside>

          <div className="rv-stage">
            <div className="rv-quote-mark" aria-hidden="true">“</div>
            <blockquote key={i} className="rv-quote">
              {r.quote}
            </blockquote>
            <div className="rv-attr">
              <div>
                <div className="rv-name h-head">{r.name}</div>
                <div className="rv-role mono">{r.role}</div>
              </div>
              <div className="rv-project mono">{r.project}</div>
            </div>
            <div className="rv-progress">
              {reviews.map((_, n) => (
                <span key={n} className={`rp ${i === n ? "is-on" : ""}`} />
              ))}
            </div>
          </div>
        </div>
      </div>

      <style>{`
        .reviews { background: var(--bg-2); border-top: 1px solid var(--line); }
        .rv-grid {
          display: grid;
          grid-template-columns: 380px 1fr;
          gap: 80px;
          align-items: start;
        }
        .rv-h { font-size: clamp(48px, 5vw, 80px); margin: 16px 0 32px; }
        .rv-summary {
          padding: 20px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
          margin-bottom: 24px;
        }
        .rv-rate { display: flex; align-items: baseline; gap: 16px; }
        .rv-stars { color: var(--clay); letter-spacing: 4px; font-size: 18px; }
        .rv-num { font-size: 56px; color: var(--ink); }
        .rv-from { font-size: 11px; letter-spacing: 0.16em; color: var(--ink-3); margin-top: 8px; }
        .rv-from strong { color: var(--ink); font-weight: 500; }

        .rv-thumbs { display: flex; flex-direction: column; gap: 0; }
        .rv-thumb {
          display: flex; align-items: center; gap: 14px;
          background: transparent; border: none; border-top: 1px solid var(--line);
          padding: 14px 0; text-align: left;
          color: var(--ink-3);
          transition: color .15s ease, padding .15s ease;
        }
        .rv-thumb:last-child { border-bottom: 1px solid var(--line); }
        .rv-thumb:hover { color: var(--ink); }
        .rv-thumb.is-on { color: var(--clay); padding-left: 8px; }
        .rt-n { font-size: 11px; letter-spacing: 0.16em; }
        .rt-name { font-family: var(--head); text-transform: uppercase; letter-spacing: 0.06em; font-size: 14px; }

        .rv-stage { position: relative; }
        .rv-quote-mark {
          position: absolute; top: -40px; left: -20px;
          font-family: var(--display);
          font-size: 240px; line-height: 1;
          color: var(--clay);
          opacity: 0.15;
          z-index: 0;
        }
        .rv-quote {
          font-family: var(--head);
          font-weight: 400;
          font-size: clamp(24px, 2.6vw, 38px);
          line-height: 1.35;
          letter-spacing: 0.005em;
          color: var(--ink);
          margin: 0 0 48px;
          position: relative;
          z-index: 1;
          max-width: 28ch;
          text-transform: none;
          animation: fadeIn .4s ease;
        }
        @keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

        .rv-attr {
          display: flex; align-items: flex-end; justify-content: space-between;
          padding-top: 24px;
          border-top: 1px solid var(--line);
          flex-wrap: wrap; gap: 16px;
        }
        .rv-name { font-size: 20px; }
        .rv-role { font-size: 11px; letter-spacing: 0.16em; color: var(--ink-3); margin-top: 4px; }
        .rv-project { font-size: 11px; letter-spacing: 0.14em; color: var(--ink-4); }

        .rv-progress { display: flex; gap: 6px; margin-top: 36px; }
        .rp { width: 36px; height: 2px; background: var(--line-2); }
        .rp.is-on { background: var(--clay); }

        @media (max-width: 900px) {
          .rv-grid { grid-template-columns: 1fr; gap: 32px; }
          .rv-quote-mark { font-size: 140px; top: -20px; left: -8px; }
        }
      `}</style>
    </section>
  );
}

Object.assign(window, { Work, Reviews });
