// screens-today.jsx — landing screen for returning members
//
// Goal: in under 30 seconds a member should be able to (a) see/cancel their
// next booked class, (b) book the next available class on the schedule, or
// (c) re-book something they've taken before.

const { fmtIDR, findClass, findCoach, findFriend, minutesUntil, fmtCountdown,
        DAYS_SHORT, DAYS_LONG, DATES_THIS_WEEK, TODAY_DAY } = window.NADI_HELPERS;

function TodayScreen({ user, setUser, openClassSheet, setTab, openCheckout, showToast, onCancelBooking, upcomingBookings }) {
  const getAppToday = window.NADI_HELPERS.getAppToday;
  const parseLocalDate = window.NADI_HELPERS.parseLocalDate;
  const parseLocalDateTime = (dateStr, timeStr) => {
    if (!dateStr || !timeStr) return null;
    const [year, month, day] = dateStr.split('-').map(Number);
    const [hours, minutes] = timeStr.split(':').map(Number);
    return new Date(year, month - 1, day, hours, minutes);
  };

  // Their booked sessions mapped to session details and sorted by actual date-time
  const bookedSessions = (upcomingBookings || [])
    .map(b => {
      const s = window.NADI.SCHEDULE.find(x => x.id === b.session_id);
      if (!s) return null;
      return {
        ...s,
        bookingId: b.id,
        date: b.date,
      };
    })
    .filter(Boolean)
    .filter(s => {
      const d = parseLocalDateTime(s.date, s.time);
      return d && d >= getAppToday();
    })
    .sort((a, b) => parseLocalDateTime(a.date, a.time) - parseLocalDateTime(b.date, b.time));

  const next = bookedSessions[0];

  // "Next available" — first class after simulated now
  const nextAvailable = window.NADI.SCHEDULE
    .filter((s) => {
      if (user.booked.includes(s.id)) return false;
      if (s.capacity - s.booked <= 0) return false;
      const d = parseLocalDateTime(s.date, s.time);
      return d && d >= getAppToday();
    })
    .sort((a, b) => parseLocalDateTime(a.date, a.time) - parseLocalDateTime(b.date, b.time))[0];

  // Quick rebook: distinct class+coach combos from last 3 history items
  const quickRebook = (user.history || []).slice(0, 3).map((h) => ({
    classId: h.classId, coachId: h.coachId,
  }));

  // Pack about to expire (urgent if <= 15 days)
  const packs = (user.creditPacks || []).slice().sort((a, b) => new Date(a.expires) - new Date(b.expires));
  const urgentPack = packs.find((p) => {
    const getStartOfDay = (dateObj) => new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
    const expiryDate = parseLocalDate(p.expires);
    const todayDate = getStartOfDay(getAppToday());
    const days = Math.max(0, Math.round((expiryDate - todayDate) / 86400000));
    return days <= 15 && p.credits > 0;
  });

  return (
    <PullToRefresh>
      <div style={{ paddingBottom: 24 }}>
        {/* Greeting */}
        <section style={{ padding: "8px 22px 24px" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
            <Mono>{DAYS_LONG[TODAY_DAY].toLowerCase()} · {String(DATES_THIS_WEEK[TODAY_DAY]).padStart(2, "0")} {new Date().toLocaleDateString("en-GB", { month: "short" }).toLowerCase()}</Mono>
            <Mono>{String(window.NADI_HELPERS.TODAY_HOUR).padStart(2, "0")}:{String(window.NADI_HELPERS.TODAY_MIN).padStart(2, "0")} · jakarta</Mono>
          </div>
          <StretchHeadline size={48} style={{ marginTop: 18 }}>
            Hello, <em style={{ fontStyle: "italic", color: "var(--primary)" }}>{user ? user.name.split(" ")[0] : "Member"}</em>.
          </StretchHeadline>
          <p style={{
            marginTop: 14, fontFamily: "Newsreader, serif", fontSize: 17, lineHeight: 1.45,
            color: "var(--ink-soft)", fontWeight: 300, maxWidth: 320,
          }}>
            {next
              ? `You're on the mat ${fmtCountdown(minutesUntil(next))}.`
              : nextAvailable
              ? `Nothing booked yet — the next class is ${fmtCountdown(minutesUntil(nextAvailable))}.`
              : "All quiet on the schedule."}
          </p>
        </section>

        {/* Hero: the next class (booked OR suggested next) */}
        {next ? <NextBookedHero s={next} user={user} setUser={setUser} showToast={showToast} setTab={setTab} onCancel={onCancelBooking} /> : nextAvailable
          ? <NextSuggestedHero s={nextAvailable} openClassSheet={openClassSheet} />
          : null}

        {/* Credits / pack rail */}
        <CreditsRail user={user} setTab={setTab} urgentPack={urgentPack} openCheckout={openCheckout} />

        {/* Quick rebook */}
        {quickRebook.length > 0 && (
          <section style={{ padding: "0 22px 24px" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 14 }}>
              <Eyebrow>book again</Eyebrow>
              <button onClick={() => setTab("book")} className="press" style={{ background: "transparent", border: 0 }}>
                <Mono color="var(--primary)">browse all →</Mono>
              </button>
            </div>
            <div style={{ display: "flex", gap: 10, overflowX: "auto", paddingBottom: 8, margin: "0 -22px", padding: "0 22px 8px" }} className="scroll">
              {quickRebook.map((q, i) => {
                const c = findClass(q.classId), co = findCoach(q.coachId);
                const matching = window.NADI.SCHEDULE.find((s) => s.classId === q.classId && s.coachId === q.coachId && minutesUntil(s) > 0);
                return (
                  <button key={i} onClick={() => matching && openClassSheet(matching)} className="press" style={{
                    flexShrink: 0, width: 180,
                    textAlign: "left", padding: 16,
                    background: "var(--bg)", border: "1px solid var(--rule)",
                    display: "flex", flexDirection: "column", justifyContent: "space-between",
                    minHeight: 150,
                  }}>
                    <div>
                      <Mono>{String(i + 1).padStart(2, "0")} · {c.duration}m</Mono>
                      <h3 style={{ fontFamily: "Newsreader, serif", fontSize: 22, fontWeight: 400, marginTop: 8, color: "var(--ink)", lineHeight: 1 }}>
                        {c.name}
                      </h3>
                    </div>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <Avatar name={co.name} initials={co.initials} tone={co.tone} size={22} />
                      <Mono>{co.firstName.toLowerCase()}</Mono>
                    </div>
                  </button>
                );
              })}
            </div>
          </section>
        )}

        {/* This week peek */}
        <ThisWeekPeek setTab={setTab} openClassSheet={openClassSheet} user={user} />

        {/* Friends going */}
        <FriendsThisWeek openClassSheet={openClassSheet} user={user} />

        {/* Streak / breath signature */}
        <BreathStrip user={user} />
      </div>
    </PullToRefresh>
  );
}

// ── Hero: a booked class ─────────────────────────────────────────────
function NextBookedHero({ s, user, setUser, showToast, setTab, onCancel }) {
  const c = findClass(s.classId), co = findCoach(s.coachId);
  const mins = minutesUntil(s);
  const friends = (s.friends || []).map(findFriend).filter(Boolean);
  const canCancel = mins > 60;
  const privacy = (user.bookingPrivacy && user.bookingPrivacy[s.id])
    || (user.visibleByDefault ? "self" : "anon");
  const isAnon = privacy === "anon";
  const flipPrivacy = () => {
    if (!setUser) return;
    const next = isAnon ? "self" : "anon";
    setUser({ ...user, bookingPrivacy: { ...(user.bookingPrivacy || {}), [s.id]: next } });
    showToast && showToast(next === "anon" ? "Going anonymously." : "Visible to your circle.");
  };

  const dateStr = s.date ? window.NADI_HELPERS.parseLocalDate(s.date).toLocaleDateString("en-GB", { weekday: "short", day: "2-digit", month: "short" }).toLowerCase() : DAYS_LONG[s.day].toLowerCase();

  return (
    <section style={{ padding: "0 22px 28px" }}>
      <div style={{
        position: "relative",
        background: "var(--ink)", color: "var(--bg)",
        padding: "26px 24px 24px",
        overflow: "hidden",
      }}>
        {/* Background breath dot — subtle */}
        <span aria-hidden style={{
          position: "absolute", right: -50, top: -50,
          width: 220, height: 220, borderRadius: "50%",
          background: "var(--primary)", opacity: 0.16,
          filter: "blur(6px)",
          animation: "nadi-breath 8s ease-in-out infinite",
        }} />
        <div style={{ position: "relative" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 }}>
            <Mono color="rgba(248,241,225,0.7)">your next class</Mono>
            <span style={{
              padding: "5px 10px",
              border: "1px solid rgba(248,241,225,0.35)",
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 10.5, letterSpacing: "0.08em",
              color: "var(--bg)",
              display: "inline-flex", alignItems: "center", gap: 6,
            }}>
              <span className="breath" style={{ width: 6, height: 6, background: "var(--primary)" }} />
              {fmtCountdown(mins).toLowerCase()}
            </span>
          </div>

          <h2 className="display" style={{ fontSize: 56, color: "var(--bg)", letterSpacing: "-0.03em", lineHeight: 0.92 }}>
            <em style={{ fontStyle: "italic", color: "#E8A07F" }}>{c.name}</em>
          </h2>
          <div style={{ marginTop: 14, fontFamily: "Newsreader, serif", fontSize: 16, color: "rgba(248,241,225,0.78)", fontWeight: 300, lineHeight: 1.45 }}>
            {dateStr} · {s.time} · with {co.name} · {s.roomShort}
          </div>

          <div style={{ marginTop: 22, paddingTop: 18, borderTop: "1px solid rgba(248,241,225,0.18)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12 }}>
            <button onClick={flipPrivacy} className="press" aria-label={isAnon ? "Going anonymously, tap to make visible" : "Visible, tap to go anonymous"} style={{
              display: "inline-flex", alignItems: "center", gap: 10,
              padding: "8px 12px 8px 8px",
              border: `1px solid ${isAnon ? "rgba(248,241,225,0.35)" : "var(--primary)"}`,
              background: isAnon ? "transparent" : "rgba(181,86,60,0.18)",
              color: "var(--bg)",
              borderRadius: 999,
            }}>
              <Avatar size={24} initials={user.initials} tone="var(--primary)" anon={isAnon} border="var(--ink)" />
              <span style={{
                display: "inline-flex", flexDirection: "column", alignItems: "flex-start", gap: 1, lineHeight: 1,
              }}>
                <span style={{
                  fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.1em",
                  textTransform: "uppercase", color: isAnon ? "rgba(248,241,225,0.55)" : "#E8A07F",
                }}>{isAnon ? "anon" : "visible"}</span>
                <span style={{
                  fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: "0.04em",
                  textTransform: "lowercase", color: "rgba(248,241,225,0.5)",
                }}>tap to flip</span>
              </span>
            </button>
            {friends.length > 0 && (
              <div style={{ textAlign: "right" }}>
                <Mono color="rgba(248,241,225,0.55)">going</Mono>
                <div style={{ marginTop: 6 }}>
                  <FriendStack friends={friends} anonCount={s?.anonCount || 0} border="var(--ink)" size={26} max={3} />
                </div>
              </div>
            )}
          </div>

          <div style={{ display: "flex", gap: 8, marginTop: 22 }}>
            <button className="press" style={{
              flex: 1, padding: "14px 16px", background: "var(--primary)", color: "var(--primary-ink)",
              border: 0, fontFamily: "Geist, sans-serif", fontSize: 12,
              letterSpacing: "0.1em", textTransform: "uppercase", fontWeight: 500,
            }} onClick={() => showToast("Calendar invite sent.")}>Add to calendar</button>
            <button className="press" disabled={!canCancel} style={{
              flex: 1, padding: "14px 16px",
              background: "transparent", color: "var(--bg)",
              border: "1px solid rgba(248,241,225,0.4)",
              fontFamily: "Geist, sans-serif", fontSize: 12,
              letterSpacing: "0.1em", textTransform: "uppercase", fontWeight: 500,
              opacity: canCancel ? 1 : 0.4,
            }} onClick={() => {
              if (canCancel) {
                if (onCancel) {
                  onCancel(s);
                } else {
                  showToast("Booking cancelled — credit refunded.");
                }
              }
            }}>
              {canCancel ? "Cancel" : "Locked"}
            </button>
          </div>
        </div>
      </div>
    </section>
  );
}

// ── Hero: a suggested-next class (no booking yet) ────────────────────
function NextSuggestedHero({ s, openClassSheet }) {
  const c = findClass(s.classId), co = findCoach(s.coachId);
  const mins = minutesUntil(s);
  return (
    <section style={{ padding: "0 22px 28px" }}>
      <button onClick={() => openClassSheet(s)} className="press" style={{
        width: "100%", textAlign: "left", display: "block",
        background: "var(--surface)", border: "1px solid var(--rule)",
        padding: "22px 22px 18px",
      }}>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <Mono color="var(--primary)">next on the mat · {fmtCountdown(mins).toLowerCase()}</Mono>
          <Mono>{s.capacity - s.booked} left</Mono>
        </div>
        <h2 className="display" style={{ fontSize: 44, marginTop: 14 }}>
          {c.name}
        </h2>
        <div style={{ marginTop: 10, fontFamily: "Newsreader, serif", fontSize: 16, color: "var(--ink-soft)", fontWeight: 300 }}>
          with {co.name} · {s.roomShort}
        </div>
      </button>
    </section>
  );
}

// ── Credits Rail ─────────────────────────────────────────────────────
function CreditsRail({ user, setTab, urgentPack, openCheckout }) {
  const total = user.credits != null ? user.credits : (user.creditPacks || []).reduce((s, p) => s + p.credits, 0);
  const nextPack = (user.creditPacks || []).slice().sort((a, b) => new Date(a.expires) - new Date(b.expires))[0];
  
  const getStartOfDay = (dateObj) => new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
  const expiryDate = nextPack ? window.NADI_HELPERS.parseLocalDate(nextPack.expires) : null;
  const todayDate = getStartOfDay(window.NADI_HELPERS.getAppToday());
  const daysLeft = nextPack ? Math.max(0, Math.round((expiryDate - todayDate) / 86400000)) : 0;

  return (
    <section style={{ padding: "0 22px 28px" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1.2fr 1fr", gap: 1, background: "var(--rule)", border: "1px solid var(--rule)" }}>
        <button onClick={() => setTab("me")} className="press" style={{
          background: "var(--bg)", padding: "18px 18px 16px", textAlign: "left",
        }}>
          <Mono>credits remaining</Mono>
          <div style={{ fontFamily: "Newsreader, serif", fontSize: 56, fontWeight: 400, lineHeight: 1, marginTop: 8, letterSpacing: "-0.02em", color: "var(--primary)" }}>
            {total}
          </div>
          <Mono style={{ marginTop: 6 }}>across {user.creditPacks.length} pack{user.creditPacks.length > 1 ? "s" : ""}</Mono>
        </button>
        <button onClick={() => openCheckout()} className="press" style={{
          background: "var(--bg)", padding: "18px 18px 16px", textAlign: "left",
          display: "flex", flexDirection: "column", justifyContent: "space-between",
        }}>
          <div>
            <Mono>next to expire</Mono>
            {nextPack ? (
              <>
                <div style={{ fontFamily: "Newsreader, serif", fontSize: 28, fontWeight: 400, marginTop: 8, color: "var(--ink)", lineHeight: 1 }}>
                  {nextPack.packageName}
                </div>
                <Mono color={daysLeft <= 10 ? "var(--primary)" : "var(--ink-soft)"} style={{ marginTop: 6 }}>
                  {daysLeft} days left
                </Mono>
              </>
            ) : (
              <div style={{ fontFamily: "Newsreader, serif", fontSize: 18, marginTop: 8, color: "var(--ink-soft)" }}>—</div>
            )}
          </div>
          <Mono color="var(--primary)" style={{ marginTop: 12 }}>+ buy pack</Mono>
        </button>
      </div>
    </section>
  );
}

// ── This week peek (compact day strip) ───────────────────────────────
function ThisWeekPeek({ setTab, openClassSheet, user }) {
  // Today onward, max 5 sessions across next 3 days
  const sessions = window.NADI.SCHEDULE
    .filter((s) => minutesUntil(s) > 0 && !user.booked.includes(s.id))
    .sort((a, b) => minutesUntil(a) - minutesUntil(b))
    .slice(0, 4);

  return (
    <section style={{ padding: "0 22px 28px" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 14 }}>
        <Eyebrow>this week</Eyebrow>
        <button onClick={() => setTab("book")} className="press" style={{ background: "transparent" }}>
          <Mono color="var(--primary)">full schedule →</Mono>
        </button>
      </div>
      <div style={{ borderTop: "1px solid var(--rule)" }}>
        {sessions.map((s, i) => {
          const c = findClass(s.classId), co = findCoach(s.coachId);
          const left = s.capacity - s.booked;
          const friends = s.friends.map(findFriend).filter(Boolean);
          return (
            <button key={s.id} onClick={() => openClassSheet(s)} className="press" style={{
              width: "100%", display: "grid", gridTemplateColumns: "62px 1fr auto",
              alignItems: "center", gap: 14,
              padding: "16px 0",
              borderBottom: "1px solid var(--rule)",
              textAlign: "left",
            }}>
              <div>
                <div style={{ fontFamily: "Newsreader, serif", fontSize: 24, fontWeight: 400, lineHeight: 1, color: "var(--ink)" }}>{s.time}</div>
                <Mono style={{ marginTop: 4 }}>{DAYS_SHORT[s.day].toLowerCase()}</Mono>
              </div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontFamily: "Newsreader, serif", fontSize: 20, fontWeight: 400, color: "var(--ink)", lineHeight: 1.1 }}>{c.name}</div>
                <div style={{ marginTop: 4, display: "flex", alignItems: "center", gap: 8 }}>
                  <Mono>{co.firstName.toLowerCase()} · {s.roomShort.toLowerCase()}</Mono>
                </div>
              </div>
              <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 6 }}>
                {friends.length > 0 && <FriendStack friends={friends} anonCount={s?.anonCount || 0} size={20} max={3} border="var(--bg)" />}
                <Mono color={left < 3 ? "var(--primary)" : "var(--ink-soft)"}>{left === 0 ? "full" : `${left} left`}</Mono>
              </div>
            </button>
          );
        })}
      </div>
    </section>
  );
}

// ── Friends going this week ─────────────────────────────────────────
function FriendsThisWeek({ openClassSheet, user }) {
  // Sessions with ≥ 2 friends going
  const popular = window.NADI.SCHEDULE
    .filter((s) => s.friends.length >= 3 && minutesUntil(s) > 0 && !user.booked.includes(s.id))
    .sort((a, b) => b.friends.length - a.friends.length)
    .slice(0, 3);
  if (popular.length === 0) return null;
  return (
    <section style={{ padding: "0 22px 32px" }}>
      <Eyebrow>your circle</Eyebrow>
      <h3 style={{ fontFamily: "Newsreader, serif", fontSize: 28, fontWeight: 400, marginTop: 10, marginBottom: 16, color: "var(--ink)", letterSpacing: "-0.015em" }}>
        Where they're <em style={{ fontStyle: "italic", color: "var(--primary)" }}>going</em>.
      </h3>
      <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
        {popular.map((s) => {
          const c = findClass(s.classId), co = findCoach(s.coachId);
          const friends = s.friends.map(findFriend).filter(Boolean);
          return (
            <button key={s.id} onClick={() => openClassSheet(s)} className="press" style={{
              background: "var(--surface)", border: "1px solid var(--rule)",
              padding: "16px 18px", textAlign: "left",
              display: "flex", alignItems: "center", gap: 14,
            }}>
              <FriendStack friends={friends} anonCount={s?.anonCount || 0} size={32} max={4} border="var(--surface)" />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: "Newsreader, serif", fontSize: 18, fontWeight: 400, color: "var(--ink)" }}>{c.name}</div>
                <Mono>{DAYS_SHORT[s.day].toLowerCase()} · {s.time} · {co.firstName.toLowerCase()}</Mono>
              </div>
              <Mono color="var(--primary)">{friends.length} going</Mono>
            </button>
          );
        })}
      </div>
    </section>
  );
}

// ── Breath strip (streak + brand signature) ─────────────────────────
function BreathStrip({ user }) {
  return (
    <section style={{ padding: "20px 22px 12px", textAlign: "center" }}>
      <div style={{ display: "inline-flex", flexDirection: "column", alignItems: "center", gap: 14 }}>
        <BreathDot size={48} duration={8} />
        <div>
          <div className="display" style={{ fontSize: 36, color: "var(--ink)", letterSpacing: "-0.02em", lineHeight: 1 }}>
            {user.streak} <em style={{ fontStyle: "italic", color: "var(--primary)" }}>weeks</em>
          </div>
          <Mono style={{ marginTop: 6, display: "block" }}>your steady rhythm</Mono>
        </div>
        <p style={{ marginTop: 8, fontFamily: "Newsreader, serif", fontSize: 14, color: "var(--ink-soft)", fontWeight: 300, lineHeight: 1.5, maxWidth: 280 }}>
          breathe in, four counts.<br/>breathe out, four counts. the mat will wait.
        </p>
      </div>
    </section>
  );
}

Object.assign(window, { TodayScreen });
