/* global React, Glyph, Icon, Modal, Calendar, addMessage, addOrder */
/* Chantelle — Fitness panel: Photos · Programs (digital files) · Book.
   Overlays the .page-main box exactly. Two layouts (tabs / rail) via `layout` prop. */
const { useState: useStateF, useEffect: useEffectF, useCallback: useCallbackF } = React;

/* ---------- format / session glyphs ---------- */
const FIcon = {
  pdf:   <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5"/></svg>,
  video: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><rect x="3" y="5.5" width="13" height="13" rx="2.5"/><path d="M16 10l5-3v10l-5-3z"/></svg>,
  bundle:<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3.5 7.5 12 3l8.5 4.5v9L12 21l-8.5-4.5z"/><path d="M3.5 7.5 12 12l8.5-4.5M12 12v9"/></svg>,
  spark: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5 18 18M18 6l-2.5 2.5M8.5 15.5 6 18"/></svg>,
  inperson: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="7" r="3.2"/><path d="M5 20c0-3.6 3.1-6 7-6s7 2.4 7 6"/></svg>,
  virtual:  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><rect x="3" y="5" width="14" height="11" rx="2"/><path d="M17 9.5 21 7v8l-4-2.5z"/></svg>,
  download: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19h14"/></svg>,
};

/* ---------- placeholder gallery tiles (used when photos are missing) ---------- */
const PH_TILES = [
  { num: "02", cap: "Strength", bg: "linear-gradient(150deg,#2c2925,#0b0b0c)" },
  { num: "03", cap: "Outdoor",  bg: "linear-gradient(150deg,var(--orange-bright),#b8330a)" },
  { num: "04", cap: "Mobility", bg: "linear-gradient(150deg,#e9e6e1,#cdc9c2)" },
  { num: "05", cap: "Form",     bg: "linear-gradient(150deg,#dbd7d1,#bcb7af)" },
];

/* ---------- Photos ---------- */
function FitPhotos({ photos, fallbackHero, video, featureImage }){
  const v = (typeof parseVideo === "function") ? parseVideo(video) : null;
  const [playing, setPlaying] = useStateF(false);
  const imgs = (photos && photos.length) ? photos : (fallbackHero ? [fallbackHero] : []);
  // hero priority: video → dedicated feature image → first gallery photo
  const heroImg = v ? null : (featureImage || imgs[0] || null);
  // tiles: if hero comes from the gallery's first photo, skip it; otherwise show all gallery photos
  const tileSrc = (!v && !featureImage) ? imgs.slice(1) : imgs;
  const tiles = PH_TILES.map((tl, k) => ({ ...tl, img: tileSrc[k] || null }));
  const playIcon = <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M8 5.2v13.6L19 12z"/></svg>;
  return (
    <div className="fit-view fit-gallery">
      <div className={"fit-hero" + (v ? " is-video" : "")} style={v ? { background: "#0b0b0c" } : (heroImg ? {} : { background: "linear-gradient(150deg,#2c2925,#0b0b0c)" })}>
        {v ? (
          playing ? (
            <iframe className="fit-hero-frame" src={v.embed + "&autoplay=1"} title="Featured video" frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
          ) : (
            <button className="fit-hero-poster" onClick={() => setPlaying(true)}
              style={v.thumb ? { backgroundImage: `url(${v.thumb})` } : { background: "linear-gradient(150deg,#2c2925,#0b0b0c)" }} aria-label="Play video">
              <span className="fit-play">{playIcon}</span>
              <span className="fit-vlabel">{v.kind === "youtube" ? "Play video" : "Play TikTok"}</span>
            </button>
          )
        ) : heroImg ? <img src={heroImg} alt="" /> : <span className="fit-tnum" style={{ position: "absolute", top: "50%", left: "50%", transform: "translate(-50%,-50%)", fontSize: 80 }}>01</span>}
        {!v && <div className="fit-shade" />}
        {!v && <div className="fit-cap"><div className="k">Featured</div><div className="t">In the gym</div></div>}
      </div>
      <div className="fit-grid2">
        {tiles.map((s, k) => (
          <div key={k} className="fit-tile" style={s.img ? {} : { background: s.bg }}>
            {s.img ? <img src={s.img} alt="" /> : <span className="fit-tnum">{s.num}</span>}
            <span className="fit-tcap">{s.cap}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Checkout (writes an order, applies promo, delivers a file) ---------- */
function Checkout({ product, promos, onClose }){
  return <Modal onClose={onClose}>{(close) => <CheckoutInner product={product} promos={promos} close={close} />}</Modal>;
}
function CheckoutInner({ product, promos, close }){
  const [form, setForm] = useStateF({ name: "", email: "" });
  const [code, setCode] = useStateF("");
  const [applied, setApplied] = useStateF(null);
  const [done, setDone] = useStateF(false);
  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && /.+@.+\..+/.test(form.email);

  const discount = applied && applied !== "bad"
    ? (applied.kind === "percent" ? Math.round(product.price * applied.value / 100) : Math.min(product.price, applied.value)) : 0;
  const total = Math.max(0, product.price - discount);
  const applyCode = () => {
    const c = (promos || []).find((p) => p.active && p.code.toLowerCase() === code.trim().toLowerCase());
    setApplied(c || "bad");
  };
  const pay = () => {
    if (!valid) return;
    addOrder({ productId: product.id, productTitle: product.title, customer: form.name.trim(), email: form.email.trim().toLowerCase(), amount: total });
    setDone(true);
  };
  const download = () => {
    const blob = new Blob(["Thank you for buying " + product.title + "!\n\nThis is your placeholder download. Replace it with your real file."], { type: "text/plain" });
    const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = product.title.replace(/\s+/g, "-") + ".txt"; a.click();
    setTimeout(() => URL.revokeObjectURL(a.href), 1000);
  };

  if (done) return (
    <div className="cw-sent">
      <span className="cw-seal">{Icon.check}</span>
      <h2 className="cw-modal-title" style={{ fontSize: 36 }}>You're all set</h2>
      <p className="cw-modal-sub" style={{ margin: "14px auto 0" }}>
        <b style={{ color: "var(--ink)", fontWeight: 400 }}>{product.title}</b> is ready. A copy of your receipt is on the way to {form.email.trim()}.
      </p>
      <button className="cw-submit" style={{ maxWidth: 280, margin: "28px auto 0" }} onClick={download}>{FIcon.download} Download now</button>
      <button className="cw-back" style={{ margin: "18px auto 0", justifyContent: "center" }} onClick={close}>Back to programs</button>
    </div>
  );

  return (
    <div className="cw-modal-pad">
      <p className="cw-modal-kicker">Checkout</p>
      <h2 className="cw-modal-title" style={{ fontSize: 34 }}>{product.title}</h2>
      <div className="co-prod">
        <span className="co-fmt">{FIcon[product.fmt] || FIcon.pdf} {product.fmtLabel}</span>
        <span className="co-price">${product.price}</span>
      </div>
      <div className="cw-field"><label>Your name</label><input value={form.name} onChange={set("name")} placeholder="Full name" /></div>
      <div className="cw-field"><label>Email — where your file is sent</label><input type="email" value={form.email} onChange={set("email")} placeholder="you@email.com" /></div>
      <div className="cw-field"><label>Promo code <span style={{ textTransform: "none", letterSpacing: 0, opacity: .6 }}>(optional)</span></label>
        <div className="co-promo">
          <input value={code} onChange={(e) => { setCode(e.target.value); setApplied(null); }} placeholder="e.g. WELCOME10" />
          <button className="co-apply" onClick={applyCode}>Apply</button>
        </div>
        {applied === "bad" && <p className="co-msg bad">That code isn't valid.</p>}
        {applied && applied !== "bad" && <p className="co-msg ok">{applied.code} applied — {applied.kind === "percent" ? applied.value + "% off" : "$" + applied.value + " off"}.</p>}
      </div>
      <div className="co-total"><span>Total</span><span className="amt">{discount > 0 && <s>${product.price}</s>} ${total}</span></div>
      <button className="cw-submit" disabled={!valid} style={!valid ? { opacity: .4, cursor: "default" } : {}} onClick={pay}>
        Pay ${total} {Icon.go}
      </button>
      <p style={{ fontFamily: "var(--sans)", fontWeight: 300, fontSize: 12, color: "var(--mid)", textAlign: "center", margin: "14px 0 0" }}>Instant download · yours to keep on any device.</p>
    </div>
  );
}

/* ---------- Programs (digital files) ---------- */
function FitPrograms({ products, promos }){
  const [checkout, setCheckout] = useStateF(null);
  const list = products && products.length ? products : [];
  return (
    <div className="fit-view">
      <div className="fit-progs">
        {list.map((p) => (
          <div key={p.id} className="fit-prog">
            <div className="fit-prog-thumb" style={p.image ? { backgroundImage: `url(${p.image})` } : { background: p.color || p.bg }}>
              <span className="fit-prog-fmt">{FIcon[p.fmt] || FIcon.pdf} {p.fmtLabel}</span>
            </div>
            <div className="fit-prog-body">
              <h4>{p.title}</h4>
              <p>{p.desc}</p>
              <div className="fit-prog-foot">
                <span className="fit-price"><span className="cur">$</span>{p.price}</span>
                <button className="fit-buy" onClick={() => setCheckout(p)}>Buy</button>
              </div>
            </div>
          </div>
        ))}
      </div>
      <div className="fit-note-row">{FIcon.download} Instant download after checkout — yours to keep, on any device.</div>
      {checkout && <Checkout product={checkout} promos={promos} onClose={() => setCheckout(null)} />}
    </div>
  );
}

/* ---------- Book (reuses Calendar + inbox) ---------- */
function FitBook({ sessions, slots, openDays }){
  const sList = sessions && sessions.length ? sessions : [];
  const slotList = slots && slots.length ? slots : [];
  const [sess, setSess] = useStateF(sList[0] ? sList[0].id : null);
  const [date, setDate] = useStateF(null);
  const [time, setTime] = useStateF(null);
  const [form, setForm] = useStateF({ name: "", email: "", goal: "" });
  const [sent, setSent] = useStateF(false);
  const set = (key) => (e) => setForm((f) => ({ ...f, [key]: e.target.value }));

  const session = sList.find((s) => s.id === sess) || sList[0];
  const ready = session && date && time && form.name.trim() && form.email.trim();
  const dateLabel = date && date.toLocaleDateString([], { weekday: "long", month: "long", day: "numeric" });
  const kindOf = (s) => (s.mode === "virtual" ? "Virtual training" : "In-person training");

  if (sent && session) return (
    <div className="fit-view fit-confirm">
      <span className="cw-seal">{Icon.check}</span>
      <h2 className="cw-modal-title" style={{ fontSize: 36 }}>Request sent</h2>
      <p className="cw-modal-sub" style={{ margin: "14px auto 0" }}>
        Your <b style={{ color: "var(--ink)", fontWeight: 400 }}>{session.title}</b> request for <b style={{ color: "var(--ink)", fontWeight: 400 }}>{dateLabel}, {time}</b> is in Chantelle's inbox. She confirms within 24 hours.
      </p>
    </div>
  );

  return (
    <div className="fit-view fit-book">
      <div>
        <p className="fit-book-eyebrow">Session type</p>
        <div className="fit-sess">
          {sList.map((s) => (
            <button key={s.id} className={"fit-sess-card" + (sess === s.id ? " is-sel" : "")} onClick={() => setSess(s.id)}>
              <span className="fit-sess-ic">{s.mode === "virtual" ? FIcon.virtual : FIcon.inperson}</span>
              <span><h4>{s.title}</h4><p>{s.dur} · 1-on-1 with Chantelle</p></span>
              <span className="fit-sess-price">${s.price}</span>
            </button>
          ))}
        </div>
        <div className="cw-field"><label>Your name</label><input value={form.name} onChange={set("name")} placeholder="Full name" /></div>
        <div className="cw-field"><label>Email</label><input type="email" value={form.email} onChange={set("email")} placeholder="you@email.com" /></div>
        <div className="cw-field"><label>Your goal <span style={{ textTransform: "none", letterSpacing: 0, opacity: .6 }}>(optional)</span></label><textarea value={form.goal} onChange={set("goal")} placeholder="What are you training for?" style={{ minHeight: 64 }} /></div>
      </div>

      <div className="fit-book-right">
        <p className="fit-book-eyebrow">Choose a date &amp; time</p>
        <Calendar selected={date} onSelect={setDate} openDays={openDays} />
        <div className="slots">
          {slotList.map((s) => (
            <button key={s} className={"slot" + (time === s ? " is-sel" : "")} onClick={() => setTime(s)}>{s}</button>
          ))}
        </div>
        <div className="book-cta">
          <button className="book-confirm" disabled={!ready}
            onClick={() => {
              if (!ready) return;
              addMessage({
                kind: kindOf(session), name: form.name.trim(), email: form.email.trim(),
                reqISO: date.toISOString(), reqTime: time, session: session.title,
                body: "Session: " + session.title + " (" + session.dur + ")\nRequested: " + dateLabel + " · " + time + (form.goal.trim() ? "\n\nGoal: " + form.goal.trim() : ""),
              });
              setSent(true);
            }}>
            {ready ? "Request this session" : "Pick a date, time & details"} {ready && Icon.go}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Panel shell ---------- */
const FIT_TABS = [
  { id: "photos",   label: "Photos" },
  { id: "programs", label: "Programs" },
  { id: "book",     label: "Book" },
];

function FitnessPanel({ onClose, site, layout = "tabs" }){
  const [tab, setTab] = useStateF("photos");
  const [closing, setClosing] = useStateF(false);
  const close = useCallbackF(() => { setClosing(true); setTimeout(onClose, 230); }, [onClose]);

  useEffectF(() => {
    const h = (e) => { if (e.key === "Escape") close(); };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [close]);

  const fp = (site && site.text && site.text.fitnessPanel) || { kicker: "Training", title: "Fitness", lede: "" };
  const photos = site && site.photos ? site.photos : {};
  const products = site ? site.products : [];
  const sessions = site ? site.sessions : [];
  const av = (site && site.availability) || { slots: [], days: [true,true,true,true,true,true,true] };

  const Body = (
    <div className="fit-body">
      {tab === "photos"   && <FitPhotos photos={photos.fitness} fallbackHero={photos.home && photos.home[0]} video={photos.fitnessVideo} featureImage={photos.fitnessFeature} />}
      {tab === "programs" && <FitPrograms products={products} promos={site.promos} />}
      {tab === "book"     && <FitBook sessions={sessions} slots={av.slots} openDays={av.days} />}
    </div>
  );

  const titles = (
    <div className="fit-titles">
      <p className="fit-kicker">{fp.kicker}</p>
      <h2 className="fit-title">{fp.title}</h2>
      <p className="fit-lede">{fp.lede}</p>
    </div>
  );

  return (
    <>
      <div className={"fit-scrim" + (closing ? " closing" : "")} onMouseDown={close} />
      <div className={"fit-panel" + (layout === "rail" ? " rail" : "") + (closing ? " closing" : "")}
           role="dialog" aria-modal="true" aria-label="Fitness">
        <button className="fit-x" onClick={close} aria-label="Close">{Icon.x}</button>

        {layout === "rail" ? (
          <>
            <aside className="fit-rail">
              {titles}
              <nav className="fit-railnav">
                {FIT_TABS.map((t) => (
                  <button key={t.id} className={tab === t.id ? "is-on" : ""} onClick={() => setTab(t.id)}>
                    <span className="rn-dot" />{t.label}
                  </button>
                ))}
              </nav>
            </aside>
            <div className="fit-railmain">{Body}</div>
          </>
        ) : (
          <>
            <div className="fit-head">{titles}</div>
            <div className="fit-tabbar">
              <div className="fit-tabs">
                {FIT_TABS.map((t) => (
                  <button key={t.id} className={"fit-tab" + (tab === t.id ? " is-on" : "")} onClick={() => setTab(t.id)}>{t.label}</button>
                ))}
              </div>
            </div>
            {Body}
          </>
        )}
      </div>
    </>
  );
}

Object.assign(window, { FitnessPanel });
