/* global React */

/* ===========================================================
   SHOWS PAGE — Gypsy Reverie
   ===========================================================
   This file owns four components:
     ShowsHero        — small brand-matching hero atop the page
     UpcomingShows    — list of upcoming shows (Bandsintown w/ fallback)
     PastHighlights   — curated 6–10 past shows w/ photos + quotes
     StickyJoinBar    — fixed-bottom Society CTA
   =========================================================== */

/* -----------------------------------------------------------
   BANDSINTOWN CONFIG
   -----------------------------------------------------------
   To pull live events from Bandsintown, set these to real
   values. Until then, the page renders from UPCOMING_FALLBACK
   below — which the band can edit by hand any time.

   To activate Bandsintown:
   1. Register the artist at https://artists.bandsintown.com/
      (free). Add shows there.
   2. Pick an app_id (anything URL-safe; convention is your
      domain): e.g. "gypsyreveriemusic.com"
   3. Set BANDSINTOWN_ARTIST to the exact artist name as it
      appears on Bandsintown (URL-encode anything fancy).
   4. The fetch happens client-side; CORS is open.

   If the request fails or returns zero events, the page
   silently falls back to UPCOMING_FALLBACK. So you can leave
   Bandsintown config off and just edit the array below.
   ----------------------------------------------------------- */
const BANDSINTOWN_ARTIST  = "";              // e.g. "Gypsy Reverie"
const BANDSINTOWN_APP_ID  = "gypsyreveriemusic.com";
const BANDSINTOWN_URL     = "https://rest.bandsintown.com/artists";

/* -----------------------------------------------------------
   UPCOMING_FALLBACK — hand-edited list, shown when Bandsintown
   is unconfigured or returns nothing.
   -----------------------------------------------------------
   status: "available" | "few-left" | "sold-out" | "past"
   price: string ("$20", "Free", "$15 / $20 door")
   set:   "Gypsy Jazz Set" | "Swing Dance" | etc.
   note:  optional short line (e.g. "with special guest …")
   url:   direct ticket link
   ----------------------------------------------------------- */
const UPCOMING_FALLBACK = [
  {
    iso: "",
    dow: "",
    venue: "Battery Park Book Exchange",
    city: "Asheville, NC",
    doors: "TBD",
    showtime: "TBD",
    price: "TBD",
    set: "",
    note: "An Evening in Lisbon: Portuguese Fado, Gypsy Jazz & Wine Pairing.",
    status: "available",
    url: "https://batteryparkbookexchange.com/",
  },
  {
    iso: "",
    dow: "",
    venue: "Antidote",
    city: "Asheville, NC",
    doors: "",
    showtime: "4–7 PM",
    price: "Free",
    set: "Gypsy Reverie Duo",
    note: "Joseph Arnold & Adam Rose play during your dining experience.",
    status: "available",
    url: "https://antidote.bar/",
  },
];

/* -----------------------------------------------------------
   PAST_HIGHLIGHTS — curated 6–10 past shows worth showing.
   Edit by hand. Photos go in /assets and the path is referenced
   below. If photo: "" the tile falls back to a brand gradient.
   ----------------------------------------------------------- */
const PAST_HIGHLIGHTS = [
  {
    year: "2025",
    venue: "City Winery",
    city: "Philadelphia, PA",
    when: "Oct 2025",
    photo: "../../assets/photo-hook-loft.png",
    quote: "The excitement was palpable. The musicians flowed from tune to tune with obvious camaraderie.",
    quoteBy: "Cecilia D.",
    soldOut: true,
  },
  {
    year: "2025",
    venue: "Avalon Theater",
    city: "Easton, MD",
    when: "Aug 2025",
    photo: "../../assets/photo-band-hero.png",
    quote: "Gypsy Reverie's musicianship was unparalleled.",
    quoteBy: "Suzy Moore",
    soldOut: false,
  },
  {
    year: "2024",
    venue: "Plein Air Festival",
    city: "Easton, MD",
    when: "Jul 2024",
    photo: "",
    quote: "Their enchanting live sounds created a relaxed yet spirited atmosphere to match the art on display.",
    quoteBy: "Talbot Spy",
    soldOut: false,
  },
];

/* =========================================================== */

function ShowsHero() {
  return (
    <section className="gr-shows-hero">
      <div className="gr-shows-hero__inner">
        <div className="gr-eyebrow gr-shows-hero__eyebrow">Shows · Asheville &amp; beyond</div>
        <h1 className="gr-shows-hero__title">Find us in a room near you.</h1>
        <p className="gr-shows-hero__sub">
          The rooms are small and the lists are long. Society members get first access to tickets before they go public.
        </p>
      </div>
    </section>
  );
}

/* =========================================================== */

function UpcomingShows() {
  const [shows, setShows] = React.useState(UPCOMING_FALLBACK);
  const [source, setSource] = React.useState("local");

  React.useEffect(() => {
    if (!BANDSINTOWN_ARTIST) return;
    const url = `${BANDSINTOWN_URL}/${encodeURIComponent(BANDSINTOWN_ARTIST)}/events?app_id=${encodeURIComponent(BANDSINTOWN_APP_ID)}`;
    fetch(url)
      .then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
      .then((data) => {
        if (!Array.isArray(data) || data.length === 0) return;
        const mapped = data.map((e) => {
          const d = new Date(e.datetime);
          const dow = d.toLocaleDateString("en-US", { weekday: "short" });
          return {
            iso: e.datetime.slice(0, 10),
            dow,
            venue: e.venue?.name || "TBA",
            city: [e.venue?.city, e.venue?.region].filter(Boolean).join(", "),
            doors: "",
            showtime: d.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }),
            price: "",
            set: "",
            note: e.description || "",
            status: (e.lineup || []).length ? "available" : "available",
            url: (e.offers || []).find((o) => o.type === "Tickets")?.url || e.url || "#",
          };
        });
        setShows(mapped);
        setSource("bandsintown");
      })
      .catch(() => {
        // Stay with fallback silently
      });
  }, []);

  return (
    <section id="upcoming" className="gr-shows-up">
      <div className="gr-shows-up__head">
        <div className="gr-eyebrow">Upcoming</div>
        <a
          className="gr-shows-up__bit"
          href="https://www.bandsintown.com/"
          target="_blank"
          rel="noopener noreferrer"
        >
          Follow on Bandsintown ↗
        </a>
      </div>

      {shows.length === 0 ? (
        <div className="gr-shows-up__empty">
          <p>No shows on the books right now. Join the Society — we'll let you know first.</p>
        </div>
      ) : (
        <ol className="gr-shows-up__list" aria-label="Upcoming shows">
          {shows.map((s, i) => <ShowRow key={s.iso + s.venue + i} show={s} />)}
        </ol>
      )}
    </section>
  );
}

function ShowRow({ show }) {
  const hasDate = !!show.iso;
  const d = hasDate ? new Date(show.iso + "T00:00:00") : null;
  const day = hasDate ? d.getDate() : null;
  const month = hasDate ? d.toLocaleDateString("en-US", { month: "short" }) : null;

  const isPast    = show.status === "past";
  const isSoldOut = show.status === "sold-out";
  const fewLeft   = show.status === "few-left";

  const cta = isSoldOut ? "Sold out" : isPast ? "Past show" : fewLeft ? "Few left · Reserve" : "Reserve";

  return (
    <li className={`gr-show ${isSoldOut ? "is-soldout" : ""} ${isPast ? "is-past" : ""} ${fewLeft ? "is-few" : ""}`}>
      <div className="gr-show__date">
        {hasDate ? (
          <React.Fragment>
            <span className="gr-show__day">{day}</span>
            <span className="gr-show__month">{month}</span>
            {show.dow && <span className="gr-show__dow">{show.dow}</span>}
          </React.Fragment>
        ) : (
          <span className="gr-show__month">TBD</span>
        )}
      </div>

      <div className="gr-show__main">
        <h3 className="gr-show__venue">{show.venue}</h3>
        <div className="gr-show__meta">
          {show.city && <span>{show.city}</span>}
          {show.doors && <span className="gr-show__sep" aria-hidden>·</span>}
          {show.doors && <span>Doors {show.doors}</span>}
          {show.showtime && <span className="gr-show__sep" aria-hidden>·</span>}
          {show.showtime && <span>Show {show.showtime}</span>}
          {show.price && <span className="gr-show__sep" aria-hidden>·</span>}
          {show.price && <span className="gr-show__price">{show.price}</span>}
          {show.set && <span className="gr-show__sep" aria-hidden>·</span>}
          {show.set && <span className="gr-show__set">{show.set}</span>}
        </div>
        {show.note && <p className="gr-show__note">{show.note}</p>}
      </div>

      <div className="gr-show__cta-wrap">
        {isSoldOut ? (
          <span className="gr-show__soldout" aria-label="Sold out">Sold out</span>
        ) : isPast ? (
          <span className="gr-show__past">—</span>
        ) : (
          <a className="gr-btn gr-btn--gold-solid gr-show__cta" href={show.url || "#"}>
            {fewLeft ? "Few left · Reserve" : "Reserve"}
          </a>
        )}
      </div>
    </li>
  );
}

/* =========================================================== */

function PastHighlights() {
  return (
    <section id="past" className="gr-shows-past">
      <header className="gr-shows-past__head">
        <div className="gr-eyebrow">Past highlights</div>
        <h2 className="gr-shows-past__title">Where we've been.</h2>
      </header>
      <ul className="gr-shows-past__grid">
        {PAST_HIGHLIGHTS.map((p, i) => (
          <li key={p.venue + i} className="gr-past-card">
            <div
              className={`gr-past-card__photo ${p.photo ? "" : "is-empty"}`}
              style={p.photo ? { backgroundImage: `url(${p.photo})` } : undefined}
              aria-hidden="true"
            />
            <div className="gr-past-card__body">
              <div className="gr-past-card__meta">
                <span className="gr-past-card__when">{p.when}</span>
                {p.soldOut && <span className="gr-past-card__tag">Sold out</span>}
              </div>
              <h3 className="gr-past-card__venue">{p.venue}</h3>
              <div className="gr-past-card__city">{p.city}</div>
              <blockquote className="gr-past-card__quote">
                <span className="mark" aria-hidden>"</span>
                <p>{p.quote}</p>
                <cite>{p.quoteBy}</cite>
              </blockquote>
            </div>
          </li>
        ))}
      </ul>
    </section>
  );
}

/* =========================================================== */

function StickyJoinBar() {
  const [dismissed, setDismissed] = React.useState(false);
  const [scrolled, setScrolled]   = React.useState(false);

  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 300);
    window.addEventListener("scroll", onScroll);
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  if (dismissed) return null;

  return (
    <div className={`gr-shows-sticky ${scrolled ? "is-visible" : ""}`} role="region" aria-label="Join the Society">
      <div className="gr-shows-sticky__inner">
        <div className="gr-shows-sticky__copy">
          <span className="gr-shows-sticky__eyebrow">Join the Society</span>
          <span className="gr-shows-sticky__line">First access to tickets, 48 hours before public release.</span>
        </div>
        <a className="gr-btn gr-btn--gold-solid gr-shows-sticky__cta" href="/#society-form">
          Join the Society
        </a>
        <button
          className="gr-shows-sticky__close"
          onClick={() => setDismissed(true)}
          aria-label="Dismiss"
        >×</button>
      </div>
    </div>
  );
}

/* =========================================================== */

function ShowsPage() {
  return (
    <React.Fragment>
      <Nav current="shows" />
      <main className="gr-shows-page">
        <ShowsHero />
        <UpcomingShows />
        <PastHighlights />
      </main>
      <Footer current="shows" />
      <StickyJoinBar />
    </React.Fragment>
  );
}

window.ShowsPage      = ShowsPage;
window.ShowsHero      = ShowsHero;
window.UpcomingShows  = UpcomingShows;
window.PastHighlights = PastHighlights;
window.StickyJoinBar  = StickyJoinBar;
