/* SECTION — Selected Projects.
   Categorized cinematic explorer · 4 brochure categories ·
   container transforms, clip-path masking, layered depth. */

const PROJECT_CATEGORIES = [
  { id: 'health', label: 'HEALTHCARE',               tag: 'Healthcare' },
  { id: 'comm',   label: 'COMMERCIAL',               tag: 'Commercial' },
  { id: 'sport',  label: 'SPORTS & EDUCATION',       tag: 'Sports & Higher Education' },
  { id: 'res',    label: 'DWELLING & RESIDENTIAL',   tag: 'Dwelling & Residential' },
];

/* Minimalist schematic line icons per category — thin 1.2px stroke,
   currentColor so they inherit the node tint (active = charcoal, inactive = muted). */
function CategoryIcon({ id, className = '' }) {
  const common = {
    width: 16, height: 16, viewBox: '0 0 24 24',
    fill: 'none', stroke: 'currentColor', strokeWidth: 1.2,
    strokeLinecap: 'round', strokeLinejoin: 'round',
    className, 'aria-hidden': true,
  };
  switch (id) {
    case 'health':  // medical cross inside rounded square
      return (
        <svg {...common}>
          <rect x="3.5" y="3.5" width="17" height="17" rx="3" />
          <path d="M12 8v8 M8 12h8" />
        </svg>
      );
    case 'comm':    // skyscraper trio
      return (
        <svg {...common}>
          <path d="M3.5 20.5h17" />
          <path d="M6 20.5V9l4-2v13.5" />
          <path d="M14 20.5V4l4 2v14.5" />
          <path d="M8 12h0 M8 15h0 M16 9h0 M16 13h0 M16 17h0" />
        </svg>
      );
    case 'sport':   // graduation cap
      return (
        <svg {...common}>
          <path d="M2.5 9.5 12 5l9.5 4.5L12 14 2.5 9.5z" />
          <path d="M6 11.5v4.2c0 1 2.7 2.3 6 2.3s6-1.3 6-2.3v-4.2" />
          <path d="M21.5 9.5v4.5" />
        </svg>
      );
    case 'res':     // house with pitched roof
      return (
        <svg {...common}>
          <path d="M3.5 11 12 4l8.5 7" />
          <path d="M5.5 10v10h13V10" />
          <path d="M10 20v-5h4v5" />
        </svg>
      );
    default: return null;
  }
}

const PROJECTS = [
  // ---------- HEALTHCARE ----------
  { id: 'monash',     cat: 'health', img: 'assets/projects/monash.jpg',     name: 'Monash Medical Centre — Tower Expansion', sector: 'Healthcare · Public hospital', loc: 'Clayton, VIC',     scope: 'Performance-based fire engineering · NLA strategy' },
  { id: 'barwon',     cat: 'health', img: 'assets/projects/barwon.jpg',     name: 'University Hospital Geelong',             sector: 'Healthcare · Barwon Health',   loc: 'Geelong, VIC',     scope: 'Code-equivalence · critical-care strategy' },
  { id: 'berwick',    cat: 'health', img: 'assets/projects/berwick.jpg',    name: 'Berwick Health Hospital',                 sector: 'Healthcare · Acute facility',  loc: 'Berwick, VIC',     scope: 'Performance-based DTS departures' },
  { id: 'swan-hill',  cat: 'health', img: 'assets/projects/swan-hill.jpg',  name: 'Swan Hill Emergency Department',          sector: 'Healthcare · Regional ED',     loc: 'Swan Hill, VIC',   scope: 'Critical-care fire strategy' },
  { id: 'alfred',     cat: 'health', img: 'assets/projects/alfred.jpg',     name: 'Alfred Health — JMS Accommodation',       sector: 'Healthcare · Institutional',   loc: 'Prahran, VIC',     scope: 'Adaptive-reuse fire safety upgrade' },
  { id: 'camperdown', cat: 'health', img: 'assets/projects/camperdown.jpg', name: 'Camperdown Aged-Care',                    sector: 'Healthcare · Aged care',       loc: 'Camperdown, VIC',  scope: 'Egress modelling · vulnerable occupants' },
  { id: 'mayflower',  cat: 'health', img: 'assets/projects/mayflower.jpg',  name: 'Mayflower Aged-Care',                     sector: 'Healthcare · Aged care',       loc: 'Brighton, VIC',    scope: 'Compartmentation strategy' },

  // ---------- COMMERCIAL ----------
  { id: 'hobart',         cat: 'comm', img: 'assets/projects/hobart-airport.jpg', name: 'Hobart Airport Terminal Expansion', sector: 'Commercial · Aviation',  loc: 'Hobart, TAS',     scope: 'Smoke management · CFD analysis' },
  { id: 'state-trustees', cat: 'comm', img: 'assets/projects/state-trustees.jpg', name: 'State Trustees',                    sector: 'Commercial · Office tower', loc: 'Footscray, VIC', scope: 'Performance-based fire engineering' },
  { id: 'box-hill',       cat: 'comm', img: 'assets/projects/box-hill.png',       name: 'Box Hill Central — Southern Mall',  sector: 'Commercial · Retail',    loc: 'Box Hill, VIC',   scope: 'Retail refurbishment compliance' },
  { id: 'cobram',         cat: 'comm', img: 'assets/projects/cobram.jpg',         name: '206 Healy Road',                    sector: 'Commercial · Industrial', loc: 'Cobram, VIC',    scope: 'Glasshouse fire engineering' },

  // ---------- SPORTS & HIGHER EDUCATION ----------
  { id: 'vatl',         cat: 'sport', img: 'assets/projects/vatl-bairnsdale.png', name: 'VATL — Bairnsdale Campus',     sector: 'Higher Education',     loc: 'Bairnsdale, VIC',  scope: 'Adaptive-reuse · school authority approval' },
  { id: 'queenscliffe', cat: 'sport', img: 'assets/projects/queenscliffe.png',    name: 'Queenscliffe Community Hub',   sector: 'Civic · Sports facility', loc: 'Queenscliffe, VIC', scope: 'Heritage-sensitive performance design' },
  { id: 'rgyc',         cat: 'sport', img: 'assets/projects/rgyc.jpg',            name: 'Royal Geelong Yacht Club',     sector: 'Sports · Mixed-use',    loc: 'Geelong, VIC',     scope: 'Coastal facility fire engineering' },

  // ---------- DWELLING & RESIDENTIAL ----------
  { id: 'little-bourke', cat: 'res', img: 'assets/projects/little-bourke.jpg', name: '570 Little Bourke Street',  sector: 'Residential · Student accommodation', loc: 'Melbourne CBD, VIC', scope: 'Façade & egress modelling · approval pathway' },
  { id: 'glen-iris',     cat: 'res', img: 'assets/projects/glen-iris.png',    name: '13 Irymple Avenue',         sector: 'Residential · Multi-dwelling',         loc: 'Glen Iris, VIC',    scope: 'Multi-dwelling residential strategy' },
  { id: 'malvern',       cat: 'res', img: 'assets/projects/malvern.png',      name: 'Rotherwood Drive',          sector: 'Residential · Boundary-protection',    loc: 'Malvern East, VIC', scope: 'Boundary-protection strategy' },
];

/* Stack Shuffle — position-driven dimensional transform.
   pos === 0 : front (full presence)
   pos 1..2  : stacked behind, offset down-right, scaled down, dimmed
   pos > 2   : hidden in the queue
   pos < 0   : already viewed — exit to the left with a small rotation */
function pjStackStyle(pos) {
  if (pos === 0) {
    return {
      transform: 'translate3d(0, 0, 0) scale(1) rotate(0deg)',
      opacity: 1,
      zIndex: 40,
      pointerEvents: 'auto',
    };
  }
  if (pos === 1) {
    return {
      transform: 'translate3d(44px, 32px, 0) scale(0.93) rotate(0.4deg)',
      opacity: 0.55,
      zIndex: 30,
      pointerEvents: 'auto',
      cursor: 'pointer',
    };
  }
  if (pos === 2) {
    return {
      transform: 'translate3d(80px, 60px, 0) scale(0.86) rotate(0.8deg)',
      opacity: 0.28,
      zIndex: 20,
      pointerEvents: 'auto',
      cursor: 'pointer',
    };
  }
  if (pos > 2) {
    return {
      transform: `translate3d(${90 + (pos - 2) * 6}px, ${70 + (pos - 2) * 4}px, 0) scale(0.82)`,
      opacity: 0,
      zIndex: 10,
      pointerEvents: 'none',
    };
  }
  // pos < 0 — exited cards drift off to the left and back
  return {
    transform: `translate3d(calc(-118% + ${pos * 4}px), ${-14 + pos * 2}px, 0) scale(0.9) rotate(${-3 + pos * 0.4}deg)`,
    opacity: 0,
    zIndex: 5,
    pointerEvents: 'none',
  };
}

function Projects() {
  const [activeCat, setActiveCat] = React.useState('health');
  const [activeIdx, setActiveIdx] = React.useState(0);

  // Sliding "pill" indicator that wraps the active category label and
  // re-measures (position + width) whenever the selection or layout changes.
  const catbarRef  = React.useRef(null);
  const labelRefs  = React.useRef({});
  const [pill, setPill] = React.useState(null);

  // activeCat drives the pill (immediate); displayCat drives the stage content,
  // swapped mid-transition so the outgoing content can fade out first.
  const [displayCat, setDisplayCat] = React.useState('health');
  const [transState, setTransState] = React.useState('in'); // 'out' | 'in'

  const list       = PROJECTS.filter((p) => p.cat === displayCat);
  const mobileList = PROJECTS.filter((p) => p.cat === activeCat);
  const catIdx     = PROJECT_CATEGORIES.findIndex((c) => c.id === activeCat);

  const onCat = (id) => { if (id !== activeCat) setActiveCat(id); };

  // Category change → fade the current stage out, swap content, then play the
  // diagonal wipe-in (top-left → bottom-right, Android-unlock style).
  React.useEffect(() => {
    if (activeCat === displayCat) return;
    setTransState('out');
    const t = setTimeout(() => {
      setDisplayCat(activeCat);
      setActiveIdx(0);
      setTransState('in');
    }, 420);
    return () => clearTimeout(t);
  }, [activeCat, displayCat]);

  React.useLayoutEffect(() => {
    const bar = catbarRef.current;
    const lab = labelRefs.current[activeCat];
    if (!bar || !lab) return;
    const padX = 12, padY = 7;
    const measure = () => {
      const b = bar.getBoundingClientRect();
      const l = lab.getBoundingClientRect();
      setPill({
        left:   l.left - b.left - padX,
        top:    l.top  - b.top  - padY,
        width:  l.width  + padX * 2,
        height: l.height + padY * 2,
      });
    };
    measure();
    const raf = requestAnimationFrame(measure);
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(measure);
    window.addEventListener('resize', measure);
    return () => { cancelAnimationFrame(raf); window.removeEventListener('resize', measure); };
  }, [activeCat]);

  const goPrev = () => setActiveIdx((i) => Math.max(0, i - 1));
  const goNext = () => setActiveIdx((i) => Math.min(list.length - 1, i + 1));

  // Re-scan zaj animations after content swap so right-nav items become visible
  React.useEffect(() => {
    const id = setTimeout(() => window.__zajRescan?.(), 60);
    return () => clearTimeout(id);
  }, [displayCat]);

  return (
    <section
      id="projects"
      data-screen-label="04b Projects"
      className="section-fit relative bg-off-white py-24 md:py-32 border-t border-charcoal/10"
    >
      <div className="max-w-[1320px] mx-auto px-6 md:px-10 lg:px-16">

        {/* ---- Header ---- */}
        <div className="section-fit-header flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-12">
          <div>
            <div className="zaj-fade-up font-heading text-[11px] tracking-[0.32em] text-copper">
              SELECTED PROJECTS
            </div>
            <span className="zaj-rule-grow mt-5 mb-7 copper-rule" style={{ animation: 'none' }} />
            <h2 className="section-fit-title zaj-words font-heading font-bold text-charcoal text-3xl md:text-4xl lg:text-[44px] tracking-[-0.01em] leading-[1.08] max-w-[760px]">
              From regional ED's to CBD towers.<br/>
              <span className="text-copper">Performance proven on the ground.</span>
            </h2>
            <p className="section-fit-copy zaj-fade-up mt-6 max-w-[520px] text-[14.5px] leading-[1.7] text-charcoal/65">
              BEIGMAN operates across multiple sectors and scales — from regional
              healthcare infrastructure to CBD commercial towers.
            </p>
          </div>
        </div>

        {/* ---- Desktop category bar ---- */}
        <div className="project-fit-catbar zaj-fade-up hidden md:block mb-12">
          <div className="pj-catbar gap-8" data-active={catIdx} ref={catbarRef}>
            <span
              className="pj-pill"
              aria-hidden="true"
              style={pill
                ? { opacity: 1, left: pill.left, top: pill.top, width: pill.width, height: pill.height }
                : { opacity: 0 }}
            />
            {PROJECT_CATEGORIES.map((c) => {
              const isActive = c.id === activeCat;
              return (
                <button
                  key={c.id}
                  onClick={() => onCat(c.id)}
                  className={`pj-cat ${isActive ? 'is-active' : ''}`}
                  aria-pressed={isActive}
                >
                  <span className="pj-node" aria-hidden="true" />
                  <span className="pj-cat-label" ref={(el) => { labelRefs.current[c.id] = el; }}>
                    <CategoryIcon id={c.id} className="pj-cat-icon" />
                    {c.label}
                  </span>
                </button>
              );
            })}
          </div>
        </div>

        {/* ---- Mobile category chips ---- */}
        <div className="zaj-fade-up md:hidden mb-6 pj-chips" role="tablist">
          {PROJECT_CATEGORIES.map((c) => {
            const isActive = c.id === activeCat;
            return (
              <button
                key={c.id}
                onClick={() => onCat(c.id)}
                role="tab"
                aria-selected={isActive}
                className={`shrink-0 inline-flex items-center gap-2 px-4 py-2 r-sm border font-heading text-[10px] tracking-[0.22em] transition-colors ${isActive ? 'bg-charcoal text-off-white border-charcoal' : 'bg-off-white text-charcoal/65 border-charcoal/15'}`}
              >
                <CategoryIcon id={c.id} />
                {c.label}
              </button>
            );
          })}
        </div>

        {/* ---- DESKTOP stage ---- */}
        <div className="pj-stage-shell hidden md:block">
        <div key={displayCat} className={`project-fit-stage pj-stage-grid grid grid-cols-12 gap-10 lg:gap-14 items-start ${transState === 'out' ? 'is-blurring' : ''}`}>
          {/* Featured — Stack Shuffle */}
          <div className="col-span-7">
            <div className="project-stack-pad pj-stack-wrap relative">
              <div className="pj-stack relative aspect-[16/11]">
                {list.map((p, i) => {
                  const pos = i - activeIdx;
                  const style = pjStackStyle(pos);
                  const isFront = pos === 0;
                  const isBack  = pos > 0 && pos <= 2;
                  return (
                    <div
                      key={p.id}
                      className={`pj-stack-card ${isFront ? 'is-front' : ''} ${isBack ? 'is-back' : ''}`}
                      style={{
                        ...style,
                        cursor: isFront && activeIdx < list.length - 1 ? 'pointer' : style.cursor,
                      }}
                      onClick={() => {
                        if (isFront) { if (activeIdx < list.length - 1) goNext(); }
                        else if (pos > 0) setActiveIdx(i);
                      }}
                      role="button"
                      aria-label={isFront ? 'Next project' : p.name}
                      aria-hidden={!isFront && !isBack}
                    >
                      <img
                        src={p.img}
                        alt={p.name}
                        loading={isFront ? 'eager' : 'lazy'}
                        decoding="async"
                        onError={(e) => { e.currentTarget.style.opacity = '0'; }}
                      />
                      <div className="pj-overlay-bg" aria-hidden="true" />
                      <div className="pj-overlay">
                        <div className="font-heading text-[10px] tracking-[0.32em] text-copper">
                          {p.sector} &nbsp;·&nbsp; {p.loc}
                        </div>
                        <div className="font-heading font-bold text-2xl md:text-[28px] lg:text-[32px] tracking-[-0.01em] leading-[1.1] mt-2">
                          {p.name}
                        </div>
                        <div className="mt-2 text-[13px] text-off-white/75 max-w-[520px]">
                          {p.scope}
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>

            {/* Progression indicator + prev/next */}
            <div className="mt-2 flex items-center gap-4 text-charcoal/55 font-heading text-[10px] tracking-[0.28em]">
              <span className="shrink-0 tabular-nums">
                {String(activeIdx + 1).padStart(2, '0')}
                <span className="text-charcoal/30"> / {String(list.length).padStart(2, '0')}</span>
              </span>
              <div className="flex-1 h-px bg-charcoal/12 relative overflow-hidden">
                <span
                  className="absolute inset-y-0 left-0 bg-copper"
                  style={{ width: `${((activeIdx + 1) / list.length) * 100}%`, transition: 'width .7s var(--ease-emphasized-decel)' }}
                />
              </div>
              {/* Prev / Next */}
              <div className="flex items-center gap-1 shrink-0">
                <button
                  onClick={goPrev}
                  disabled={activeIdx === 0}
                  aria-label="Previous project"
                  className="w-8 h-8 grid place-items-center border border-charcoal/15 text-charcoal/50 hover:text-charcoal hover:border-charcoal/35 disabled:opacity-25 disabled:cursor-not-allowed transition-colors duration-300"
                >
                  <svg width="12" height="8" viewBox="0 0 14 8" fill="none">
                    <path d="M14 4 H2 M6 1 L2 4 L6 7" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </button>
                <button
                  onClick={goNext}
                  disabled={activeIdx === list.length - 1}
                  aria-label="Next project"
                  className="w-8 h-8 grid place-items-center border border-charcoal/15 text-charcoal/50 hover:text-charcoal hover:border-charcoal/35 disabled:opacity-25 disabled:cursor-not-allowed transition-colors duration-300"
                >
                  <svg width="12" height="8" viewBox="0 0 14 8" fill="none">
                    <path d="M0 4 H12 M8 1 L12 4 L8 7" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </button>
              </div>
            </div>
          </div>

          {/* Right navigator */}
          <div className="col-span-5">
            <div className="zaj-fade-up font-heading text-[10px] tracking-[0.32em] text-charcoal/45 mb-3">
              WITHIN THIS SECTOR
            </div>
            <div className="border-t border-charcoal/15">
              {list.map((p, i) => {
                const isActive = i === activeIdx;
                return (
                  <button
                    key={p.id}
                    onClick={() => setActiveIdx(i)}
                    style={{ '--i': i }}
                    className={`pj-nav-item pj-nav-enter w-full border-b border-charcoal/15 py-4 transition-colors hover:border-copper ${isActive ? 'is-active' : ''}`}
                  >
                    <span className={`pj-nav-num font-heading text-[10px] tabular-nums tracking-[0.22em] ${isActive ? 'text-copper' : 'text-charcoal/40'}`}>
                      {String(i + 1).padStart(2, '0')}
                    </span>
                    <div className="min-w-0">
                      <div className={`pj-nav-name font-heading font-semibold text-[15px] tracking-tight leading-snug truncate ${isActive ? 'text-charcoal' : 'text-charcoal/65'}`}>
                        {p.name}
                      </div>
                      <div className="text-[11.5px] text-charcoal/50 mt-0.5 truncate">{p.scope}</div>
                      <div className="font-heading text-[9.5px] tracking-[0.28em] text-charcoal/40 mt-1">{p.loc.toUpperCase()}</div>
                    </div>
                  </button>
                );
              })}
            </div>

            <a
              href="#contact"
              className="section-fit-low-secondary morph-btn mt-8 inline-flex items-center gap-3 text-charcoal/70 hover:text-copper font-heading text-[11px] tracking-[0.28em] transition-colors"
            >
              <span className="morph-label">
                <span>DISCUSS A SIMILAR SCOPE</span>
                <span>DISCUSS A SIMILAR SCOPE</span>
              </span>
              <span className="w-8 h-px bg-current transition-all duration-500 group-hover:w-12" />
            </a>
          </div>
        </div>
        </div>

        {/* ---- MOBILE rail ---- */}
        <div key={'m-' + activeCat} className="md:hidden pj-stage-wrap">
          <div className="pj-rail">
            {mobileList.map((p, i) => (
              <article key={p.id} className="pj-feature relative aspect-[4/5] r-lg overflow-hidden bg-stone">
                <img src={p.img} alt={p.name} loading="lazy" decoding="async"
                     className="absolute inset-0 w-full h-full object-cover" />
                <div className="pj-overlay-bg" aria-hidden="true" />
                <div className="pj-overlay">
                  <div className="font-heading text-[9.5px] tracking-[0.32em] text-copper">
                    {p.sector}
                  </div>
                  <div className="font-heading font-bold text-[19px] tracking-[-0.01em] leading-tight mt-1.5">
                    {p.name}
                  </div>
                  <div className="mt-1.5 text-[11.5px] text-off-white/75">{p.scope}</div>
                  <div className="font-heading text-[9px] tracking-[0.28em] text-off-white/55 mt-2">
                    {p.loc.toUpperCase()} &nbsp;·&nbsp; {String(i + 1).padStart(2, '0')} / {String(mobileList.length).padStart(2, '0')}
                  </div>
                </div>
              </article>
            ))}
          </div>
        </div>

      </div>
    </section>
  );
}

Object.assign(window, { Projects, PROJECTS, PROJECT_CATEGORIES });
