/* global React, ART, WL_RM, wlClamp, useScrollP, LeafGlyph, growWillow */

/* ============================================================
   Page openings. Each page gets its own first moment instead
   of a shared template: a branch accordion, a swinging badge,
   a fanned hand of portraits, a ring of faces, a letter out of
   an envelope, words cut from a painting, a willow that grows
   with your gift, and a circle that breathes with you.
   ============================================================ */

function useMounted(delay = 40) {
  const [on, setOn] = React.useState(WL_RM);
  React.useEffect(() => {
    if (WL_RM) return;
    const t = setTimeout(() => setOn(true), delay);
    return () => clearTimeout(t);
  }, []);
  return on;
}

/* Words that rise into place one by one. */
function RiseWords({ text, base = 120, step = 60, className = "" }) {
  return (
    <span className={`rw ${className}`}>
      {text.split(" ").map((w, i) => (
        <span className="rw-w" key={i}><span style={{ transitionDelay: `${base + i * step}ms` }}>{w}</span></span>
      ))}
    </span>
  );
}

/* ============================================================
   Our Work: four branches as an accordion of dithered panels
   ============================================================ */
const WORK_PANELS = [
  { name: "Research",    img: "images/art/d-research.png", line: "Every program we run has to survive a citation." },
  { name: "Engineering", img: "images/art/d-eng.png",      line: "The tools students actually reach for at 2am." },
  { name: "Hospitals",   img: "images/art/d-medical.png",  line: "Clinicians see the ending. We want the beginning." },
  { name: "Law",         img: "images/art/d-law.png",      line: "Students in the room where the rules are written." },
];

function WorkHero() {
  const on = useMounted();
  const [open, setOpen] = React.useState(0);
  const held = React.useRef(false);
  React.useEffect(() => {
    if (WL_RM) return;
    const t = setInterval(() => { if (!held.current) setOpen((o) => (o + 1) % WORK_PANELS.length); }, 3800);
    return () => clearInterval(t);
  }, []);
  return (
    <header className={`wh ${on ? "on" : ""}`}>
      <div className="wh-head">
        <span className="kicker">Our work</span>
        <h1><RiseWords text="Built by students." /> <em><RiseWords text="Felt by communities." base={360} /></em></h1>
      </div>
      <div className="wh-panels" onMouseLeave={() => { held.current = false; }}>
        {WORK_PANELS.map((p, i) => (
          <button
            key={p.name}
            className={`wh-p ${open === i ? "open" : ""}`}
            style={{ "--i": i }}
            onMouseEnter={() => { held.current = true; setOpen(i); }}
            onFocus={() => { held.current = true; setOpen(i); }}
            onClick={() => setOpen(i)}
            aria-expanded={open === i}
          >
            <img src={p.img} alt="" />
            <span className="wh-tab"><span className="n">0{i + 1}</span>{p.name}</span>
            <span className="wh-card">
              <span className="n">Branch 0{i + 1}</span>
              <span className="t">{p.name}</span>
              <span className="l">{p.line}</span>
            </span>
          </button>
        ))}
      </div>
    </header>
  );
}

/* ============================================================
   Ambassador: a badge on a lanyard. Type your name, it swings.
   ============================================================ */
function BadgeHero({ onPrimary, onSecondary }) {
  const on = useMounted();
  const [name, setName] = React.useState("");
  const [school, setSchool] = React.useState("");
  const stageRef = React.useRef(null);
  const swingRef = React.useRef(null);

  React.useEffect(() => {
    const el = swingRef.current, st = stageRef.current;
    if (!el || !st) return;
    if (WL_RM) { el.style.transform = "rotate(0deg)"; return; }
    let a = 22, v = 0, target = 0, lastX = null, raf;
    const tick = (t) => {
      const idle = Math.sin(t / 1400) * 1.2;
      v += (target + idle - a) * 0.035;
      v *= 0.94;
      a += v;
      target *= 0.96;
      el.style.transform = `rotate(${a.toFixed(3)}deg)`;
      raf = requestAnimationFrame(tick);
    };
    const move = (e) => {
      if (lastX !== null) target = Math.max(-16, Math.min(16, target + (e.clientX - lastX) * 0.12));
      lastX = e.clientX;
    };
    const leave = () => { lastX = null; };
    raf = requestAnimationFrame(tick);
    st.addEventListener("pointermove", move);
    st.addEventListener("pointerleave", leave);
    return () => { cancelAnimationFrame(raf); st.removeEventListener("pointermove", move); st.removeEventListener("pointerleave", leave); };
  }, []);

  const initials = (name.trim() || "You").split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase();

  return (
    <header className={`bh ${on ? "on" : ""}`} ref={stageRef}>
      <div className="bh-text">
        <span className="kicker">Ambassador program</span>
        <h1><RiseWords text="Advocates at" /> <em><RiseWords text="every school." base={300} /></em></h1>
        <p className="bh-lede">Ambassadors lead awareness campaigns, connect friends with real help, and build support from inside their own schools. Try the badge on.</p>
        <div className="bh-inputs">
          <label><span>Your name</span><input value={name} onChange={(e) => setName(e.target.value.slice(0, 28))} placeholder="Jordan Lee" /></label>
          <label><span>Your school</span><input value={school} onChange={(e) => setSchool(e.target.value.slice(0, 34))} placeholder="Frisco High School" /></label>
        </div>
        <div className="bh-actions">
          <button className="pill-btn" onClick={onPrimary}>Make it real <span aria-hidden="true">→</span></button>
          <button className="pill-btn ghost" onClick={onSecondary}>Open a chapter</button>
        </div>
      </div>
      <div className="bh-stage" aria-hidden="true">
        <div className="bh-swing" ref={swingRef}>
          <div className="bh-strap" />
          <div className="bh-clip" />
          <div className="badge">
            <div className="badge-top"><span className="badge-hole" /></div>
            <div className="badge-brand">WILLOW<LeafGlyph size={14} /></div>
            <div className="badge-photo grain">
              <img src={ART.green} alt="" />
              <span>{initials}</span>
            </div>
            <div className="badge-name">{name.trim() || "Your name"}</div>
            <div className="badge-role">Ambassador</div>
            <div className="badge-school">{school.trim() || "Your school"}</div>
            <div className="badge-foot">
              <span>Chapter member</span>
              <span className="badge-bars">{Array.from({ length: 22 }).map((_, i) => <i key={i} style={{ width: [1, 2, 1, 3, 1, 1, 2][i % 7] }} />)}</span>
            </div>
          </div>
        </div>
      </div>
    </header>
  );
}

/* ============================================================
   Professors: a hand of portrait cards fanning open
   ============================================================ */
function FanHero({ people }) {
  const on = useMounted(80);
  const [hot, setHot] = React.useState(-1);
  const n = people.length;
  return (
    <header className={`fh ${on ? "on" : ""}`}>
      <div className="fh-text">
        <span className="kicker">Expert voices</span>
        <h1><RiseWords text="Researchers who've" /> <em><RiseWords text="shaped our thinking." base={300} /></em></h1>
        <p className="fh-lede">Six people whose work sits underneath everything we build. Hover the cards.</p>
      </div>
      <div className="fh-hand" onMouseLeave={() => setHot(-1)}>
        {people.map((p, i) => {
          const spread = (i - (n - 1) / 2);
          return (
            <div
              key={p.name}
              className={`fh-card ${hot === i ? "hot" : ""}`}
              style={{ "--r": `${spread * 9}deg`, "--x": `${spread * 5.5}vw`, "--d": `${i * 70}ms`, zIndex: hot === i ? 20 : i + 1 }}
              onMouseEnter={() => setHot(i)}
            >
              <img src={p.photo} alt={p.name} />
              <span className="fh-cap"><b>{p.name}</b>{p.abbr}</span>
            </div>
          );
        })}
      </div>
    </header>
  );
}

/* ============================================================
   Officers: thirteen faces circling the headline
   ============================================================ */
function RingHero({ people }) {
  const on = useMounted(60);
  const n = people.length;
  return (
    <header className={`rh ${on ? "on" : ""}`}>
      <div className="rh-ring" aria-hidden="true">
        {people.map((p, i) => (
          <div key={p.name} className="rh-slot" style={{ "--a": `${(i / n) * 360}deg`, "--d": `${i * 60}ms` }}>
            <div className="rh-face">
              <img src={p.photo} alt="" />
              <span>{p.name}</span>
            </div>
          </div>
        ))}
      </div>
      <div className="rh-center">
        <span className="kicker">The team</span>
        <h1><RiseWords text="13 students." /> <em><RiseWords text="One mission." base={260} /></em></h1>
        <p>Every officer is a student running real programs, on top of school.</p>
      </div>
    </header>
  );
}

/* ============================================================
   Apply: a letter slides out of its envelope
   ============================================================ */
function LetterHero({ onPrimary, onSecondary }) {
  const on = useMounted(120);
  return (
    <header className={`lh ${on ? "on" : ""}`}>
      <div className="lh-scene">
        <div className="env env-back" aria-hidden="true" />
        <article className="letter">
          <span className="letter-date">Frisco, Texas</span>
          <span className="letter-dear">Dear future member,</span>
          <h1>Be part of something <em>bigger than your school.</em></h1>
          <p>We are active across 5 states and 3 countries. Pick a role and apply. We onboard every week, and a real student will write back within 72 hours.</p>
          <div className="letter-sign">
            <span>With love,</span>
            <b>The students of Willow <LeafGlyph size={16} /></b>
          </div>
          <div className="letter-actions">
            <button className="pill-btn" onClick={onPrimary}>Become an ambassador <span aria-hidden="true">→</span></button>
            <button className="pill-btn ghost" onClick={onSecondary}>Open a chapter</button>
          </div>
        </article>
        <div className="env env-front" aria-hidden="true"><span className="env-stamp">Willow<br />2025</span></div>
        <div className="env env-flap" aria-hidden="true" />
      </div>
    </header>
  );
}

/* ============================================================
   About: words cut out of a painting, sliding apart as you scroll
   ============================================================ */
function CutoutHero() {
  const on = useMounted();
  const ref = React.useRef(null);
  const l1 = React.useRef(null);
  const l2 = React.useRef(null);
  useScrollP(ref, (p, r, vh) => {
    if (WL_RM) return;
    const q = wlClamp(-r.top / vh);
    if (l1.current) l1.current.style.transform = `translate3d(${-q * 18}vw, 0, 0)`;
    if (l2.current) {
      l2.current.style.transform = `translate3d(${q * 14}vw, 0, 0)`;
      l2.current.style.backgroundPosition = `${30 + q * 40}% ${40 + q * 30}%`;
    }
  });
  return (
    <header className={`ch ${on ? "on" : ""}`} ref={ref}>
      <span className="kicker ch-kick">About us</span>
      <h1 className="ch-title">
        <span className="ch-l1" ref={l1}>A movement,</span>
        <span className="ch-l2" ref={l2} style={{ backgroundImage: `url(${ART.willow})` }}>not a charity.</span>
      </h1>
      <div className="ch-foot">
        <p>Students who refused to wait for someone else to fix it. 360 members, 4 departments, 7 universities, and we are just getting started.</p>
        <svg className="ch-seal" viewBox="0 0 200 200" aria-hidden="true">
          <defs><path id="chCircle" d="M100,100 m-78,0 a78,78 0 1,1 156,0 a78,78 0 1,1 -156,0" /></defs>
          <text><textPath href="#chCircle">STUDENT-LED · EST. 2025 · FRISCO, TEXAS · ONE TOWN AT A TIME · </textPath></text>
        </svg>
      </div>
    </header>
  );
}

/* ============================================================
   Donate: the title and amounts centred, then a row of trees
   seen from below. The bigger the gift, the more of the row
   comes into full colour.
   ============================================================ */
const GIFT_LEVELS = [
  { min: 0,    lit: 1, say: "Pick an amount" },
  { min: 25,   lit: 2, say: "One student, one workshop seat" },
  { min: 100,  lit: 3, say: "A full workshop, about 20 students" },
  { min: 500,  lit: 4, say: "A new chapter's first semester" },
  { min: 2500, lit: 5, say: "A state-level campaign" },
];
const CANOPY = [1, 2, 3, 4, 5].map((n) => `images/art/canopy-${n}.jpg`);

function GrowHero({ amount, setAmount, presets }) {
  const on = useMounted();
  const ref = React.useRef(null);
  const imgs = React.useRef([]);
  const level = GIFT_LEVELS.reduce((acc, l) => (amount >= l.min ? l : acc), GIFT_LEVELS[0]);
  useScrollP(ref, (p, r, vh) => {
    if (WL_RM) return;
    const q = wlClamp(-r.top / vh);
    imgs.current.forEach((el, i) => { if (el) el.style.transform = `translate3d(0, ${q * [8, 14, 6, 12, 9][i]}%, 0) scale(1.12)`; });
  });
  return (
    <header className={`dh ${on ? "on" : ""}`} ref={ref}>
      <div className="dh-head">
        <span className="kicker">Donate</span>
        <h1><RiseWords text="Help something" /> <em><RiseWords text="grow here." base={280} /></em></h1>
        <p className="dh-lede">Every dollar funds ambassador training, research and new chapters.</p>
        <div className="dh-chips" role="group" aria-label="Donation amount">
          {presets.map((a) => (
            <button key={a.v} className={amount === a.v ? "on" : ""} onClick={() => setAmount(a.v)}>
              <span className="v">${a.v.toLocaleString()}</span>
              <span className="l">{a.l}</span>
            </button>
          ))}
        </div>
        <p className="dh-say" key={level.say}>{amount > 0 && <b>${amount.toLocaleString()}</b>}{amount > 0 && " · "}{level.say}</p>
      </div>
      <div className="dh-row">
        {CANOPY.map((src, i) => (
          <div key={src} className={`dh-cell ${i < level.lit ? "lit" : ""}`} style={{ "--i": i }}>
            <img ref={(el) => (imgs.current[i] = el)} src={src} alt="" />
          </div>
        ))}
      </div>
    </header>
  );
}

/* ============================================================
   Get Help: a circle that breathes, four seconds in, four out
   ============================================================ */
function BreatheHero() {
  const on = useMounted();
  const [phase, setPhase] = React.useState("out");
  React.useEffect(() => {
    if (WL_RM) return;
    let t;
    const first = setTimeout(() => {
      setPhase("in");
      t = setInterval(() => setPhase((p) => (p === "in" ? "out" : "in")), 4000);
    }, 400);
    return () => { clearTimeout(first); clearInterval(t); };
  }, []);
  return (
    <header className={`bre ${on ? "on" : ""}`}>
      <div className="bre-text">
        <span className="kicker">Get help · 24/7 · Free · Confidential</span>
        <h1><RiseWords text="You don't have" /> <em><RiseWords text="to face this alone." base={260} /></em></h1>
        <p className="bre-lede">If you or someone you know is struggling, these lines are free and answered right now, by people who will not judge you.</p>
        <div className="bre-actions">
          <a className="pill-btn" href="tel:988">Call or text 988 <span aria-hidden="true">→</span></a>
          <a className="pill-btn ghost" href="tel:18006624357">SAMHSA 1-800-662-4357</a>
        </div>
      </div>
      <div className={`bre-orb ${phase}`} aria-hidden="true">
        <div className="bre-glow" />
        <div className="bre-disc grain"><img src={ART.calanque} alt="" /></div>
        <span className="bre-say">{WL_RM ? "Breathe" : phase === "in" ? "Breathe in" : "Breathe out"}</span>
      </div>
    </header>
  );
}

Object.assign(window, { RiseWords, WorkHero, BadgeHero, FanHero, RingHero, LetterHero, CutoutHero, GrowHero, BreatheHero });
