// Curator Bookings — pages

const { useState: useStateP, useEffect: useEffectP, useRef: useRefP, useMemo: useMemoP } = React;

/* ============ ROSTER (home) ============ */
function RosterPage({ go, openArtist }) {
  const [hoverId, setHoverId] = useStateP(null);
  const mediaRef = useRefP(null);
  const hovered = window.ROSTER.find((r) => r.id === hoverId);

  const hoveredRowRef = useRefP(null);
  const mousePos = useRefP({ x: 0, y: 0 });

  const placeMedia = (x, y) => {
    if (!mediaRef.current) return;
    mediaRef.current.style.left = x + "px";
    mediaRef.current.style.top = y + "px";
  };

  useEffectP(() => {
    const move = (e) => {
      mousePos.current = { x: e.clientX, y: e.clientY };
      if (!hoveredRowRef.current) placeMedia(e.clientX, e.clientY);
    };
    window.addEventListener("mousemove", move);

    let raf;
    const tick = () => {
      if (hoveredRowRef.current && mediaRef.current) {
        const rect = hoveredRowRef.current.getBoundingClientRect();
        const nameEl = hoveredRowRef.current.querySelector(".name");
        const nameRect = nameEl ? nameEl.getBoundingClientRect() : rect;
        placeMedia(nameRect.right + 40, rect.top + rect.height / 2);
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    return () => {
      window.removeEventListener("mousemove", move);
      cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <div className="page-content">
      <section className="masthead">
        <div className="mast-lede">
          <p className="mast-statement">
            An independent agency representing a small, considered roster of
            <em> musicians and DJs </em>
            across South Africa.
          </p>
          <div className="mast-foot">
            <div className="mast-foot-cell">
              <span className="mast-foot-k">Office</span>
              <span className="mast-foot-v">Cape Town</span>
            </div>
            <div className="mast-foot-cell">
              <span className="mast-foot-k">Established</span>
              <span className="mast-foot-v">2022</span>
            </div>
            <div className="mast-foot-cell">
              <span className="mast-foot-k">Roster</span>
              <span className="mast-foot-v">{String(window.ROSTER.length).padStart(2,"0")} artists</span>
            </div>
            <div className="mast-foot-cell">
              <span className="mast-foot-k">Territories</span>
              <span className="mast-foot-v">SA · EU · US · UAE</span>
            </div>
          </div>
        </div>
      </section>

      <section className="roster" data-hover={hoverId ? "1" : "0"}>
        <div className="roster-head">
          <div>№</div>
          <div>Artist</div>
          <div className="dh-disc">Discipline</div>
          <div style={{textAlign:"right"}}>View</div>
        </div>
        <div className={"roster" + (hoverId ? " has-hover" : "")}>
          {window.ROSTER.map((a, i) => (
            <div
              key={a.id}
              className={"roster-row" + (hoverId === a.id ? " is-hover" : "")}
              onMouseEnter={(e) => { hoveredRowRef.current = e.currentTarget; placeMedia(e.clientX, e.clientY); setHoverId(a.id); }}
              onMouseLeave={() => { hoveredRowRef.current = null; setHoverId((h) => (h === a.id ? null : h)); }}
              onClick={() => openArtist(a.id)}
              data-cursor="View →"
              data-cursor-grow=""
            >
              <div className="idx">({String(i + 1).padStart(2, "0")})</div>
              <div className="name">
                <span className="name-text">{a.first} <em>{a.last}</em>{a.tag ? <span className="name-tag">{a.tag}</span> : null}</span>
              </div>
              <div className="disc">{a.discipline} · {a.base}</div>
              <div className="arrow">↗</div>
            </div>
          ))}
        </div>

        <div className="marquee">
          <div className="marquee-track">
            {Array.from({length: 2}).flatMap((_, k) => [
              <span key={"a"+k}>+27 · Cape Town · Worldwide</span>,
              <span key={"b"+k} className="dot"></span>,
              <span key={"c"+k}>Open for bookings</span>,
              <span key={"d"+k} className="dot"></span>,
            ])}
          </div>
        </div>
      </section>

      <div
        className={"hover-media" + (hoverId ? " show" : "")}
        ref={mediaRef}
      >
        {hovered && (
          hovered.media && hovered.media[0] ? (
            <img src={(window.IMG && window.IMG[hovered.media[0].src]) || hovered.media[0].src} alt={hovered.media[0].alt || `${hovered.first} ${hovered.last}`} />
          ) : (
            <div className="placeholder">
              {hovered.first} {hovered.last} · Photo
            </div>
          )
        )}
      </div>
    </div>
  );
}

/* ============ ARTIST DETAIL ============ */
function ArtistPage({ artistId, go, openBook }) {
  const a = window.ROSTER.find((r) => r.id === artistId) || window.ROSTER[0];
  return (
    <div className="page-content">
      <section className="artist-head">
        <div>
          <div className="num">Artist № {String(window.ROSTER.findIndex(r=>r.id===a.id)+1).padStart(2,"0")} / {String(window.ROSTER.length).padStart(2,"0")}</div>
          <h1>{a.first}<br/><em>{a.last}</em>{a.tag ? <span className="name-tag name-tag--lg">{a.tag}</span> : null}</h1>
        </div>
        <div className="blurb">
          {a.blurb}
          <div className="tags">
            {a.genres.map((g) => <span key={g}>{g}</span>)}
            <span>{a.base}</span>
          </div>
        </div>
      </section>

      <section className="artist-media">
        {(() => {
          const fallback = ["Press", "Live", "Studio", "Portrait"];
          const imgs = a.media || [];
          const count = Math.max(4, imgs.length);
          return Array.from({ length: count }).map((_, i) => {
            const m = imgs[i];
            const lbl = (m && m.label) || fallback[i] || "Image";
            return (
              <div className={"tile" + (m && m.wide ? " tile--wide" : "")} key={i}>
                {m ? (
                  <img src={(window.IMG && window.IMG[m.src]) || m.src} alt={m.alt || `${a.first} ${a.last} — ${lbl}`} />
                ) : (
                  <div className="ph">{a.first} {a.last} — {lbl}</div>
                )}
              </div>
            );
          });
        })()}
      </section>

      <section className="artist-body">
        <div className="col">
          <h3>Biography</h3>
          {a.bio ? (
            <>
              {a.bio.map((para, i) => (
                <p key={i} style={i > 0 ? {marginTop: "1em"} : null}>{para}</p>
              ))}
              <p style={{marginTop: "1em"}}>Represented worldwide by Curator Bookings since {a.years.replace("Est. ","")}. Available for select club dates, festival slots, and long-form residencies.</p>
            </>
          ) : (
            <p>{a.blurb} Represented worldwide by Curator Bookings since {a.years.replace("Est. ","")}. Available for festival headline slots, long-form residencies, and selected brand commissions.</p>
          )}
          {a.video ? (
            <div className="artist-video">
              <iframe src={`https://www.youtube.com/embed/${a.video}?rel=0&playsinline=1`} title={`${a.first} ${a.last} — video`} frameBorder="0" referrerPolicy="strict-origin-when-cross-origin" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowFullScreen></iframe>
            </div>
          ) : null}
          {a.video ? <a className="press-link video-link" href={`https://www.youtube.com/watch?v=${a.video}`} target="_blank" rel="noopener">Watch on YouTube <span className="press-arrow">↗</span></a> : null}
        </div>
        <div className="col">
          <h3>Socials</h3>
          <ul>
            {(() => {
              const s = a.socials || {};
              const items = [
                ["Instagram", s.instagram],
                ["SoundCloud", s.soundcloud || (a.soundcloud && (typeof a.soundcloud === "string" ? a.soundcloud : a.soundcloud.url))],
                ["Spotify", s.spotify],
              ];
              return items.map(([label, url]) => (
                <li key={label}>
                  <span className="d">—</span>
                  {url ? (
                    <a className="press-link" href={url} target="_blank" rel="noopener">{label} <span className="press-arrow">↗</span></a>
                  ) : (
                    <span>{label}</span>
                  )}
                </li>
              ));
            })()}
          </ul>
        </div>
        <div className="col">
          <h3>Details</h3>
          <ul>
            <li><span className="d">Base</span><span>{a.base}</span></li>
            <li><span className="d">Regions</span><span>{a.territories}</span></li>
            <li><span className="d">Format</span><span>{a.discipline}</span></li>
            <li><span className="d">Since</span><span>{a.years}</span></li>
          </ul>
        </div>
      </section>

      <section className="artist-listen">
        <h3 className="al-cap">Listening</h3>
        <BandcampPlayer artist={a} />
      </section>

      <section className="artist-cta">
        <h2>Enquire about<br/><em>{a.first} {a.last}</em> —</h2>
        <button className="submit-btn" onClick={() => openBook(a.id)} data-cursor="Book →" data-cursor-grow="">
          Book <em>{a.first}</em> →
        </button>
      </section>
    </div>
  );
}

/* ============ BOOKING FORM ============ */
function BookPage({ preselectedId, go, setPreselectedId }) {
  const [state, setState] = useStateP({
    name: "",
    org: "",
    email: "",
    phone: "",
    event: "",
    venue: "",
    city: "",
    date: "",
    attendance: "",
    budget: "",
    message: "",
    services: [],
    artistId: preselectedId || "",
  });
  const [submitted, setSubmitted] = useStateP(false);
  const [ref, setRef] = useStateP("");
  const [errors, setErrors] = useStateP({});
  const [sending, setSending] = useStateP(false);
  const [sendError, setSendError] = useStateP("");

  useEffectP(() => {
    setState((s) => ({ ...s, artistId: preselectedId || s.artistId }));
  }, [preselectedId]);

  const artist = window.ROSTER.find((r) => r.id === state.artistId);

  const set = (k) => (e) => setState((s) => ({ ...s, [k]: e.target.value }));
  const toggleSvc = (s) =>
    setState((st) => ({
      ...st,
      services: st.services.includes(s)
        ? st.services.filter((x) => x !== s)
        : [...st.services, s],
    }));

  const submit = (e) => {
    e.preventDefault();
    const errs = {};
    if (!state.name) errs.name = "Required";
    if (!state.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(state.email)) errs.email = "Valid email required";
    if (!state.event) errs.event = "Required";
    if (!state.date) errs.date = "Required";
    if (!state.message) errs.message = "Tell us a little";
    setErrors(errs);
    if (Object.keys(errs).length) return;
    const r = "CB-" + Math.random().toString(36).slice(2, 8).toUpperCase();
    const payload = {
      _subject: `Booking enquiry ${r}${artist ? " — " + [artist.first, artist.last].filter(Boolean).join(" ") : ""}`,
      _replyto: state.email,
      _template: "table",
      _captcha: "false",
      Reference: r,
      Artist: artist ? [artist.first, artist.last].filter(Boolean).join(" ") : "Not specified",
      Name: state.name,
      Organisation: state.org,
      Email: state.email,
      Phone: state.phone,
      Event: state.event,
      Venue: state.venue,
      City: state.city,
      Date: state.date,
      Attendance: state.attendance,
      Budget: state.budget,
      Requirements: state.services.join(", "),
      Message: state.message,
    };
    setSending(true);
    setSendError("");
    fetch("https://formsubmit.co/ajax/riley@curatoragency.co.za", {
      method: "POST",
      headers: { "Content-Type": "application/json", Accept: "application/json" },
      body: JSON.stringify(payload),
    })
      .then((res) => res.json().then((j) => ({ ok: res.ok, j })))
      .then(({ ok, j }) => {
        if (!ok || j.success === "false" || j.success === false) throw new Error(j.message || "Send failed");
        setRef(r);
        setSubmitted(true);
        window.scrollTo({ top: 0 });
      })
      .catch(() => {
        setSendError("Couldn't send — please email riley@curatoragency.co.za directly.");
      })
      .finally(() => setSending(false));
  };

  if (submitted) {
    return (
      <div className="page-content">
        <section className="success">
          <h2>Thank <em>you</em>.</h2>
          <p>We've received your enquiry{artist ? <> for <em>{artist.first} {artist.last}</em></> : null}.<br/>An agent will respond within two working days.</p>
          <div className="ref">Ref. {ref}</div>
          <div style={{marginTop: 40}}>
            <button className="submit-btn" onClick={() => { setSubmitted(false); setState({ name:"",org:"",email:"",phone:"",event:"",venue:"",city:"",date:"",attendance:"",budget:"",message:"",services:[],artistId:"" }); setPreselectedId(null); }} data-cursor="Reset" data-cursor-grow="">
              New <em>enquiry</em>
            </button>
          </div>
        </section>
      </div>
    );
  }

  return (
    <div className="page-content">
      <section className="form-head">
        <div>
          <div style={{fontFamily:"var(--mono)", fontSize:11, letterSpacing:".16em", textTransform:"uppercase", color:"var(--mute)", marginBottom:18}}>
            Enquiry Form — 01 / 01
          </div>
          <h1>Book<br/>an <em>artist</em>.</h1>
        </div>
        <div className="side">
          <p>A short form. We'll come back to you within two working days with availability, fees, and a routing proposal.</p>
          {artist ? (
            <div className="artist-pill">
              <span className="dotb"></span>
              <span>Booking: {artist.first} {artist.last}</span>
              <button onClick={() => { setState((s) => ({...s, artistId: ""})); setPreselectedId(null); }} data-cursor="Change">Change</button>
            </div>
          ) : (
            <div className="artist-pill">
              <span className="dotb"></span>
              <span>General enquiry — no artist selected</span>
            </div>
          )}
        </div>
      </section>

      <form onSubmit={submit}>
        <div className="form">
          <div className="lbl">01 — Artist</div>
          <div className="fields">
            <div className="field">
              <div className="sub">Select artist (or leave blank)</div>
              <select value={state.artistId} onChange={set("artistId")} data-cursor="">
                <option value="">— General enquiry —</option>
                {window.ROSTER.map((r) => (
                  <option key={r.id} value={r.id}>{r.first} {r.last} · {r.discipline}</option>
                ))}
              </select>
            </div>
          </div>
        </div>

        <div className="form">
          <div className="lbl">02 — You</div>
          <div className="fields">
            <div className="grid2">
              <div className={"field" + (errors.name ? " error" : "")}>
                <div className="sub">Full name</div>
                <input value={state.name} onChange={set("name")} placeholder="Jane Doe" />
                <div className="err">{errors.name}</div>
              </div>
              <div className="field">
                <div className="sub">Organisation</div>
                <input value={state.org} onChange={set("org")} placeholder="Festival, venue, brand" />
              </div>
            </div>
            <div className="grid2">
              <div className={"field" + (errors.email ? " error" : "")}>
                <div className="sub">Email</div>
                <input value={state.email} onChange={set("email")} placeholder="you@domain.com" />
                <div className="err">{errors.email}</div>
              </div>
              <div className="field">
                <div className="sub">Phone (optional)</div>
                <input value={state.phone} onChange={set("phone")} placeholder="+27…" />
              </div>
            </div>
          </div>
        </div>

        <div className="form">
          <div className="lbl">03 — Event</div>
          <div className="fields">
            <div className={"field" + (errors.event ? " error" : "")}>
              <div className="sub">Event name</div>
              <input value={state.event} onChange={set("event")} placeholder="Summer Sessions, Afro Nation…" />
              <div className="err">{errors.event}</div>
            </div>
            <div className="grid2">
              <div className="field">
                <div className="sub">Venue</div>
                <input value={state.venue} onChange={set("venue")} placeholder="Kirstenbosch, etc." />
              </div>
              <div className="field">
                <div className="sub">City / country</div>
                <input value={state.city} onChange={set("city")} placeholder="Cape Town, ZA" />
              </div>
            </div>
            <div className="grid2">
              <div className={"field" + (errors.date ? " error" : "")}>
                <div className="sub">Date</div>
                <input value={state.date} onChange={set("date")} placeholder="DD / MM / YYYY" />
                <div className="err">{errors.date}</div>
              </div>
              <div className="field">
                <div className="sub">Expected attendance</div>
                <input value={state.attendance} onChange={set("attendance")} placeholder="500 / 2,000 / 10,000…" />
              </div>
            </div>
            <div className="field">
              <div className="sub">Set fee offer — Budget (Rands)</div>
              <input value={state.budget} onChange={set("budget")} placeholder="Budget In Rands" />
            </div>
            <div>
              <div className="sub" style={{fontFamily:"var(--mono)", fontSize:10, letterSpacing:".14em", textTransform:"uppercase", color:"var(--mute)"}}>Requirements</div>
              <div className="chips">
                {["DJ set", "Live performance", "Interview / press"].map((s) => (
                  <div
                    key={s}
                    className={"chip" + (state.services.includes(s) ? " on" : "")}
                    onClick={() => toggleSvc(s)}
                    data-cursor=""
                  >{s}</div>
                ))}
              </div>
            </div>
          </div>
        </div>

        <div className="form">
          <div className="lbl">04 — Brief</div>
          <div className="fields">
            <div className={"field" + (errors.message ? " error" : "")}>
              <div className="sub">Tell us about the event</div>
              <textarea value={state.message} onChange={set("message")} placeholder="A few sentences on the event, audience, other artists on the bill…" />
              <div className="err">{errors.message}</div>
            </div>
          </div>
        </div>

        <div className="submit-row">
          <div className="submit-meta">
            By sending, you agree to our standard<br/>enquiry terms. Replies within 2 working days.
          </div>
          <button className="submit-btn" type="submit" disabled={sending} data-cursor="Send →" data-cursor-grow="">
            {sending ? <>Sending<em>…</em></> : <>Send <em>enquiry</em> →</>}
          </button>
          {sendError ? <div className="send-error">{sendError}</div> : null}
        </div>
      </form>
    </div>
  );
}

/* ============ ABOUT ============ */
function AboutPage({ go }) {
  return (
    <div className="page-content">
      <section className="section-head">
        <div>
          <div style={{fontFamily:"var(--mono)", fontSize:11, letterSpacing:".16em", textTransform:"uppercase", color:"var(--mute)", marginBottom:18}}>
            About — Est. 2022
          </div>
          <h1>Carefully<br/><em>Curated</em>.</h1>
        </div>
        <div className="side">
          <p>A Cape Town-based artist booking and event curation agency — representing a carefully selected roster of DJs, live acts and cultural talent. Rooted in South Africa's underground music culture, routed to the world.</p>
        </div>
      </section>

      <div className="prose">
        <div className="lbl">Manifesto</div>
        <div className="body">
          <p><span className="drop">F</span>ounded in 2022, Curator Bookings is a Cape Town-based artist booking and event curation agency representing a carefully selected roster of DJs, live acts and cultural talent. Working across clubs, festivals, brands and independent spaces, we develop thoughtful programming that prioritises artistic integrity, audience experience and long-term relationships.</p>
          <p>Beyond artist representation, we curate line-ups, consult on event strategy and produce distinctive cultural experiences that connect music with place and community.</p>
          <p>Rooted in South Africa's underground music culture, Curator Bookings exists to champion exceptional artists while delivering memorable events with purpose, personality and seamless execution.</p>
        </div>
      </div>

      <div className="prose">
        <div className="lbl">The Team</div>
        <div className="body">
          <ul style={{listStyle:"none"}}>
            {[
              ["Riley Pam-Grant", "Head Booker"],
              ["Jed Cohen", "Agency Director"],
            ].map(([n, r]) => (
              <li key={n} style={{display:"grid", gridTemplateColumns:"1fr 1fr", padding:"14px 0", borderBottom:"1px solid var(--rule)", fontFamily:"var(--serif)", fontSize:26, lineHeight:1.1}}>
                <span>{n}</span>
                <span style={{fontFamily:"var(--mono)", fontSize:11, letterSpacing:".14em", textTransform:"uppercase", color:"var(--mute-strong)", alignSelf:"center"}}>{r}</span>
              </li>
            ))}
          </ul>
        </div>
      </div>
    </div>
  );
}

/* ============ SERVICES ============ */
function ServicesPage({ go }) {
  return (
    <div className="page-content">
      <section className="section-head">
        <div>
          <div style={{fontFamily:"var(--mono)", fontSize:11, letterSpacing:".16em", textTransform:"uppercase", color:"var(--mute)", marginBottom:18}}>
            Services — what we do
          </div>
          <h1>Four<br/>disciplines,<br/><em>one roof</em>.</h1>
        </div>
        <div className="side">
          <p>We run a full-service agency: booking, tour management, creative direction, and brand partnerships. Every artist on the roster has access to all four — though most work begins with the first.</p>
        </div>
      </section>

      <section className="services">
        {window.SERVICES.map((s) => (
          <div key={s.num} className="svc">
            <div className="num">{s.num} / 04</div>
            <div>
              <h3>{s.title}<br/><em>{s.em}</em></h3>
              <p>{s.copy}</p>
            </div>
          </div>
        ))}
      </section>

      <div className="prose special-projects-section">
        <div style={{fontFamily:"var(--mono)", fontSize:11, letterSpacing:".16em", textTransform:"uppercase", color:"var(--mute)", paddingTop:4, marginBottom:18}}>Special projects</div>
        <div className="special-projects-grid">
          {window.SPECIAL_PROJECTS.map((p) => (
            <div key={p.num} className="sp-card">
              <div className="sp-img">
                {p.img ? <img src={window.IMG && window.IMG[p.img] ? window.IMG[p.img] : p.img} alt={p.title} /> : <div className="sp-placeholder"><span>{p.num}</span></div>}
              </div>
              <div className="sp-body">
                <div className="sp-num">{p.num} / 08</div>
                <div className="sp-title">{p.title}</div>
                <p className="sp-blurb">{p.blurb}</p>
                <a className="sp-link" href={p.instagram} target="_blank" rel="noopener noreferrer" aria-label="Instagram">↗</a>
              </div>
            </div>
          ))}
        </div>
      </div>

      <section style={{padding:"80px 0 40px", borderBottom:"1px solid var(--rule)", display:"grid", gridTemplateColumns:"1fr auto", alignItems:"end", gap:40}}>
        <div style={{fontFamily:"var(--serif)", fontSize:"clamp(48px, 7vw, 104px)", lineHeight:0.92, letterSpacing:"-0.02em"}}>
          Start an<br/><em>enquiry</em> —
        </div>
        <button className="submit-btn" onClick={() => go("book")} data-cursor="Book →" data-cursor-grow="">
          Open the <em>form</em> →
        </button>
      </section>
    </div>
  );
}

Object.assign(window, { RosterPage, ArtistPage, BookPage, AboutPage, ServicesPage });
