// booking.jsx — Google Calendar-connected booking flow
// Pulls a mentor's live availability, lets user request an appointment,
// then continues to payment for the session.

const { useState: useStateB, useMemo: useMemoB, useEffect: useEffectB } = React;
const { Card, DisplayHeading } = window.LAUNCH_SCREENS_1;
const { MENTORS, MentorAvatar } = window.LAUNCH_MENTORS;

const DOW_SHORT = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
const MONTH_SHORT = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'];

// Seed a deterministic 14-day availability board for each mentor.
// Real product would call Google Calendar FreeBusy API and overlay events.
// Seeds off the coach id (string) so every coach — including ones added in
// Supabase — gets a stable, distinct board.
function hashSeed(str) {
  let h = 0;
  const s = String(str || 'coach');
  for (let i = 0; i < s.length; i++) h = ((h << 5) - h + s.charCodeAt(i)) | 0;
  return (Math.abs(h) % 233000) + 7;
}
// Does a [start,end) slot overlap any real busy interval ([{start,end}] ISO)?
function overlapsBusy(slotStart, slotEnd, busy) {
  for (let i = 0; i < busy.length; i++) {
    const bs = new Date(busy[i].start).getTime();
    const be = new Date(busy[i].end).getTime();
    if (slotStart.getTime() < be && slotEnd.getTime() > bs) return true;
  }
  return false;
}
// Build a 14-day availability board anchored on TODAY.
//   busyIntervals = array → use real Google Calendar freebusy
//   busyIntervals = null  → deterministic simulated busy (demo / not connected)
function buildSchedule(mentorId, busyIntervals) {
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const now = new Date();

  let seed = hashSeed(mentorId);
  const rand = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };

  const BUSY = [
    'Studio · Sky Blue Sessions', 'Co-writing · K. Halsey',
    'A&R review · Vintage', 'Mix bus revisions', 'Family · blocked',
    'Internal · A&R sync', 'Tracking · D. Mason',
    'Tracking · Hour One', 'Logic session', 'Sync placement call',
    'Pre-production', 'Lunch', 'Mentor calls (other)', 'Mastering · pickup',
  ];
  const useReal = Array.isArray(busyIntervals);
  const busyChance = 0.30 + (seed % 20) / 100; // 0.30–0.49, stable per coach

  const days = [];
  for (let i = 0; i < 14; i++) {
    const d = new Date(today);
    d.setDate(today.getDate() + i);
    const dow = d.getDay();
    const isWeekend = dow === 0 || dow === 6;
    const hours = isWeekend ? [10, 11] : [9, 10, 11, 13, 14, 15, 16, 17];

    const slots = hours.map(h => {
      const slotStart = new Date(d); slotStart.setHours(h, 0, 0, 0);
      const slotEnd = new Date(slotStart.getTime() + 60 * 60 * 1000);
      // Past times are never bookable.
      if (slotStart < now) return { hour: h, busy: true, label: 'Earlier' };
      if (useReal) {
        const isBusy = overlapsBusy(slotStart, slotEnd, busyIntervals);
        return { hour: h, busy: isBusy, label: isBusy ? 'Busy · Google Calendar' : null };
      }
      const isBusy = rand() < busyChance;
      return { hour: h, busy: isBusy, label: isBusy ? BUSY[Math.floor(rand() * BUSY.length)] : null };
    });

    days.push({
      date: d,
      dow,
      slots,
      isToday: i === 0,
      isPast: false,
    });
  }
  return days;
}

function formatHour(h) {
  const ampm = h >= 12 ? 'PM' : 'AM';
  const hh = h % 12 === 0 ? 12 : h % 12;
  return `${hh}:00 ${ampm}`;
}
function formatHourRange(h, mins) {
  const end = h + mins / 60;
  const fmt = (x) => {
    const m = Math.round((x % 1) * 60);
    const hh = Math.floor(x) % 12 === 0 ? 12 : Math.floor(x) % 12;
    const ampm = Math.floor(x) >= 12 ? 'PM' : 'AM';
    return `${hh}:${m.toString().padStart(2, '0')} ${ampm}`;
  };
  return `${fmt(h)} – ${fmt(end)}`;
}

// Tiny Google "G" mark
function GoogleMark({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 48 48" style={{ display: 'block' }}>
      <path fill="#FFC107" d="M43.6 20.5H42V20H24v8h11.3c-1.6 4.7-6.1 8-11.3 8-6.6 0-12-5.4-12-12s5.4-12 12-12c3.1 0 5.8 1.1 8 3l5.7-5.7C34.3 6.1 29.4 4 24 4 12.9 4 4 12.9 4 24s8.9 20 20 20 20-8.9 20-20c0-1.3-.1-2.4-.4-3.5z"/>
      <path fill="#FF3D00" d="M6.3 14.7l6.6 4.8C14.7 16 19 13 24 13c3.1 0 5.8 1.1 8 3l5.7-5.7C34.3 6.1 29.4 4 24 4 16.3 4 9.7 8.3 6.3 14.7z"/>
      <path fill="#4CAF50" d="M24 44c5.3 0 10.1-2 13.7-5.3l-6.3-5.3c-2 1.4-4.6 2.6-7.4 2.6-5.2 0-9.6-3.3-11.3-7.9l-6.5 5C9.6 39.6 16.2 44 24 44z"/>
      <path fill="#1976D2" d="M43.6 20.5H42V20H24v8h11.3c-.8 2.3-2.3 4.3-4.2 5.7l6.3 5.3C41.6 35.9 44 30.4 44 24c0-1.3-.1-2.4-.4-3.5z"/>
    </svg>
  );
}

function BookingScreen({ theme, mentorId, onBack, onConfirm, classMode = false }) {
  // Roster from the Supabase `coaches` table (falls back to the built-in list).
  const [mentors, setMentors] = useStateB(MENTORS);
  useEffectB(() => {
    let alive = true;
    if (window.LAUNCH_USER && window.LAUNCH_USER.fetchCoaches) {
      window.LAUNCH_USER.fetchCoaches().then((list) => {
        if (alive && list && list.length) setMentors(list);
      });
    }
    return () => { alive = false; };
  }, []);

  const wantedId = (mentorId || '').replace(/^mentor-/, '');
  const mentor = mentors.find(m => String(m.id) === wantedId) || mentors[0];
  const palette = (mentor.palette && mentor.palette.length >= 2)
    ? mentor.palette
    : [mentor.color || '#C72820', '#0A0A0A'];

  // Real Google Calendar busy times (null = simulated until/unless they load).
  const [busy, setBusy] = useStateB(null);
  useEffectB(() => {
    let alive = true;
    setBusy(null);
    if (window.LAUNCH_USER && window.LAUNCH_USER.fetchCoachAvailability && mentor && mentor.id) {
      const tMin = new Date(); tMin.setHours(0, 0, 0, 0);
      const tMax = new Date(tMin); tMax.setDate(tMax.getDate() + 14);
      window.LAUNCH_USER.fetchCoachAvailability(mentor.id, tMin.toISOString(), tMax.toISOString())
        .then(list => { if (alive) setBusy(list); });
    }
    return () => { alive = false; };
  }, [mentor.id]);

  const schedule = useMemoB(() => buildSchedule(mentor.id, busy), [mentor.id, busy]);
  const liveAvail = Array.isArray(busy);

  const todayIdx = schedule.findIndex(d => d.isToday);
  const [weekOffset, setWeekOffset] = useStateB(0); // 0 = current week, 1 = next
  const [selectedDayIdx, setSelectedDayIdx] = useStateB(todayIdx >= 0 ? todayIdx : 0);
  const [selectedSlot, setSelectedSlot] = useStateB(null); // { dayIdx, hour }
  const [duration, setDuration] = useStateB(classMode ? 20 : 60);
  const [topic, setTopic] = useStateB('');
  const [scheduling, setScheduling] = useStateB(false);
  const [bookingErr, setBookingErr] = useStateB(null);

  const weekDays = schedule.slice(weekOffset * 7, weekOffset * 7 + 7);
  const selectedDay = schedule[selectedDayIdx] || schedule[0];
  const isCurrent = selectedSlot && selectedSlot.dayIdx === selectedDayIdx;

  // Animate the "synced" timestamp counter
  const [syncedSec, setSyncedSec] = useStateB(124);
  useEffectB(() => {
    const t = setInterval(() => setSyncedSec(s => s + 1), 1000);
    return () => clearInterval(t);
  }, []);
  const syncedAgo = syncedSec < 60 ? `${syncedSec}S` : `${Math.floor(syncedSec / 60)}M ${syncedSec % 60}S`;

  // Pick day from weekDays, mapping back to global index
  const pickDay = (dayInWeek) => {
    const idx = schedule.findIndex(d => d.date.getTime() === dayInWeek.date.getTime());
    setSelectedDayIdx(idx);
  };

  const confirm = async () => {
    if (!selectedSlot || isCurrent === false || scheduling) return;
    setScheduling(true); setBookingErr(null);
    // Reserve the slot (pending booking). The Google Calendar event is created
    // only after payment is confirmed (confirm-checkout → schedule-session).
    const start = new Date(selectedDay.date);
    start.setHours(selectedSlot.hour, 0, 0, 0);

    // VIP free 20-min class → book directly with the plan benefit (no payment).
    if (classMode) {
      const r = await window.LAUNCH_USER.bookFreeClass(mentor.id, start.toISOString(), 'Music class · 20 min');
      setScheduling(false);
      if (!r || !r.ok) { setBookingErr((r && r.error) || 'Could not book the class.'); return; }
      onConfirm && onConfirm({
        mentorId: 'mentor-' + mentor.id, date: selectedDay.date, hour: selectedSlot.hour,
        duration: 20, topic: 'Music class · 20 min', classMode: true, bookingId: r.bookingId,
      });
      return;
    }

    const res = await window.LAUNCH_USER.requestBooking({
      coachId: mentor.id,
      startsAt: start.toISOString(),
      durationMin: duration,
      topic,
    });
    setScheduling(false);
    if (res && res.error) { setBookingErr(res.error); return; }
    onConfirm && onConfirm({
      mentorId: 'mentor-' + mentor.id,
      date: selectedDay.date,
      hour: selectedSlot.hour,
      duration,
      topic,
      bookingId: res && res.booking && res.booking.id,
    });
  };

  const price = (duration / 60) * mentor.rate;
  const canConfirm = !!selectedSlot && isCurrent;

  return (
    <div style={{ paddingBottom: 140, position: 'relative' }}>
      {classMode &&
      <div style={{
        background: '#CAFF33', color: '#0A0A0A', padding: '9px 14px', textAlign: 'center',
        fontFamily: theme.fontMono, fontSize: 10, fontWeight: 700, letterSpacing: 0.8,
      }}>🎓 MUSIC CLASS · 20 MIN · FREE WITH VIP</div>
      }
      {/* ─── Hero with deep field + mentor ─── */}
      <div style={{ position: 'relative', overflow: 'hidden', background: '#0A0A0A' }}>
        <div style={{
          position: 'absolute', inset: 0,
          backgroundImage: 'url(assets/deep-field.png)',
          backgroundSize: 'cover', backgroundPosition: 'center',
          opacity: 0.55,
        }} />
        <div style={{
          position: 'absolute', inset: 0,
          background: `linear-gradient(160deg, ${palette[0]}99 0%, rgba(10,10,10,0.6) 55%, rgba(10,10,10,0.96) 100%)`,
        }} />

        {/* Top bar */}
        <div style={{
          position: 'relative', zIndex: 2,
          paddingTop: 58, paddingLeft: theme.pad, paddingRight: theme.pad,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        }}>
          <button onClick={onBack} style={{
            width: 38, height: 38, borderRadius: 12,
            background: 'rgba(10,10,10,0.7)', backdropFilter: 'blur(20px)',
            border: 'none', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
              <path d="M9 2L4 7l5 5" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
          <div style={{
            padding: '7px 10px 7px 10px', borderRadius: 99,
            background: 'rgba(10,10,10,0.7)', backdropFilter: 'blur(20px)',
            border: '1px solid rgba(255,255,255,0.12)',
            display: 'flex', alignItems: 'center', gap: 8,
          }}>
            <GoogleMark size={13} />
            <span style={{
              fontFamily: theme.fontMono, fontSize: 9, color: '#fff',
              letterSpacing: 1, fontWeight: 700,
            }}>{liveAvail ? `CALENDAR SYNCED · ${syncedAgo} AGO` : 'PREVIEW AVAILABILITY'}</span>
            <span style={{
              width: 6, height: 6, borderRadius: 99,
              background: liveAvail ? '#22C55E' : '#FBBF24',
              boxShadow: `0 0 8px ${liveAvail ? '#22C55E' : '#FBBF24'}`,
            }} />
          </div>
        </div>

        {/* Title block */}
        <div style={{
          position: 'relative', zIndex: 2,
          padding: `28px ${theme.pad}px 22px`,
          display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <MentorAvatar mentor={mentor} size={60} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{
              fontFamily: theme.fontMono, fontSize: 9, color: 'rgba(255,255,255,0.75)',
              letterSpacing: 1, fontWeight: 700,
            }}>BOOK 1:1 · ${mentor.rate}/HR</div>
            <div style={{
              fontFamily: theme.fontDisplay, fontSize: 30, color: '#fff',
              lineHeight: 0.95, letterSpacing: 0.3, marginTop: 4,
              textTransform: 'uppercase',
            }}>{mentor.name}</div>
            <div style={{
              fontFamily: theme.fontMono, fontSize: 9, color: 'rgba(255,255,255,0.6)',
              letterSpacing: 0.8, fontWeight: 600, marginTop: 4,
            }}>{mentor.role}</div>
          </div>
        </div>
      </div>

      {/* ─── Week navigator ─── */}
      <div style={{ padding: `${theme.gap + 6}px ${theme.pad}px 0` }}>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          marginBottom: 10,
        }}>
          <span style={{
            fontFamily: theme.fontMono, fontSize: 11, color: theme.muted,
            letterSpacing: 1, fontWeight: 600,
          }}>{weekOffset === 0 ? 'THIS WEEK' : 'NEXT WEEK'} · {MONTH_SHORT[weekDays[0].date.getMonth()]} {weekDays[0].date.getDate()}–{weekDays[6].date.getDate()}</span>
          <div style={{ display: 'flex', gap: 4 }}>
            <button onClick={() => setWeekOffset(0)} disabled={weekOffset === 0} style={{
              width: 28, height: 28, borderRadius: 8,
              background: weekOffset === 0 ? theme.surface2 : 'transparent',
              border: `1px solid ${theme.border}`,
              cursor: weekOffset === 0 ? 'not-allowed' : 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              opacity: weekOffset === 0 ? 0.4 : 1,
            }}>
              <svg width="10" height="10" viewBox="0 0 14 14" fill="none">
                <path d="M9 2L4 7l5 5" stroke={theme.text} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>
            <button onClick={() => setWeekOffset(1)} disabled={weekOffset === 1} style={{
              width: 28, height: 28, borderRadius: 8,
              background: weekOffset === 1 ? theme.surface2 : 'transparent',
              border: `1px solid ${theme.border}`,
              cursor: weekOffset === 1 ? 'not-allowed' : 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              opacity: weekOffset === 1 ? 0.4 : 1,
            }}>
              <svg width="10" height="10" viewBox="0 0 14 14" fill="none">
                <path d="M5 2l5 5-5 5" stroke={theme.text} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>
          </div>
        </div>

        {/* Day chips */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4 }}>
          {weekDays.map(d => {
            const idx = schedule.findIndex(x => x.date.getTime() === d.date.getTime());
            const isSel = idx === selectedDayIdx;
            const freeCount = d.slots.filter(s => !s.busy).length;
            const isUnavail = d.isPast || freeCount === 0;
            return (
              <button key={d.date.toISOString()} onClick={() => !isUnavail && pickDay(d)}
                disabled={isUnavail}
                style={{
                  padding: '10px 4px', borderRadius: 10,
                  background: isSel ? theme.accent : (isUnavail ? 'transparent' : theme.surface),
                  border: isSel ? 'none' : `1px solid ${theme.border}`,
                  cursor: isUnavail ? 'not-allowed' : 'pointer',
                  opacity: isUnavail ? 0.35 : 1,
                  display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                  position: 'relative',
                }}>
                <span style={{
                  fontFamily: theme.fontMono, fontSize: 9, fontWeight: 700,
                  letterSpacing: 0.8,
                  color: isSel ? theme.onAccent : theme.muted,
                }}>{DOW_SHORT[d.dow]}</span>
                <span style={{
                  fontFamily: theme.fontDisplay, fontSize: 18,
                  color: isSel ? theme.onAccent : theme.text,
                  lineHeight: 1, letterSpacing: -0.3,
                }}>{d.date.getDate()}</span>
                <span style={{
                  fontFamily: theme.fontMono, fontSize: 8, fontWeight: 700,
                  letterSpacing: 0.5,
                  color: isSel ? theme.onAccent : (freeCount > 0 ? '#22C55E' : theme.faint),
                }}>{isUnavail ? '—' : `${freeCount} OPEN`}</span>
                {d.isToday && !isSel && (
                  <span style={{
                    position: 'absolute', top: 4, right: 4,
                    width: 5, height: 5, borderRadius: 99, background: theme.accent,
                  }} />
                )}
              </button>
            );
          })}
        </div>
      </div>

      {/* ─── Day timeline ─── */}
      <div style={{ padding: `${theme.gap + 6}px ${theme.pad}px 0` }}>
        <div style={{
          display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
          marginBottom: 10,
        }}>
          <span style={{
            fontFamily: theme.fontMono, fontSize: 11, color: theme.muted,
            letterSpacing: 1, fontWeight: 600,
          }}>
            {DOW_SHORT[selectedDay.dow]} · {MONTH_SHORT[selectedDay.date.getMonth()]} {selectedDay.date.getDate()}
          </span>
          <span style={{
            fontFamily: theme.fontMono, fontSize: 10, color: theme.accent,
            letterSpacing: 0.8, fontWeight: 700,
          }}>NASHVILLE · CST</span>
        </div>

        {/* Legend */}
        <div style={{
          display: 'flex', gap: 14, marginBottom: 10,
        }}>
          {[
            { c: '#22C55E', l: 'AVAILABLE' },
            { c: theme.accent, l: 'SELECTED' },
            { c: theme.muted, l: 'BUSY · GCAL' },
          ].map(x => (
            <div key={x.l} style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: x.c }} />
              <span style={{
                fontFamily: theme.fontMono, fontSize: 8, color: theme.muted,
                letterSpacing: 0.8, fontWeight: 700,
              }}>{x.l}</span>
            </div>
          ))}
        </div>

        <Card theme={theme} style={{ padding: 4 }}>
          {selectedDay.slots.map((s, i) => {
            const isSel = selectedSlot && selectedSlot.dayIdx === selectedDayIdx && selectedSlot.hour === s.hour;
            return (
              <button key={s.hour}
                onClick={() => !s.busy && setSelectedSlot({ dayIdx: selectedDayIdx, hour: s.hour })}
                disabled={s.busy}
                style={{
                  width: '100%', textAlign: 'left',
                  padding: '12px 14px',
                  borderRadius: 10,
                  background: isSel ? `${theme.accent}1f` : 'transparent',
                  border: `1px solid ${isSel ? theme.accent : 'transparent'}`,
                  borderBottom: i < selectedDay.slots.length - 1 && !isSel
                    ? `1px solid ${theme.border}` : `1px solid ${isSel ? theme.accent : 'transparent'}`,
                  cursor: s.busy ? 'not-allowed' : 'pointer',
                  display: 'flex', alignItems: 'center', gap: 12,
                  position: 'relative',
                }}>
                {/* Time column */}
                <div style={{
                  width: 64, flexShrink: 0,
                  fontFamily: theme.fontMono, fontSize: 11, fontWeight: 700,
                  letterSpacing: 0.5,
                  color: s.busy ? theme.faint : theme.text,
                }}>{formatHour(s.hour)}</div>

                {/* Bar / status */}
                <div style={{ flex: 1, minWidth: 0 }}>
                  {s.busy ? (
                    <div style={{
                      padding: '6px 10px', borderRadius: 6,
                      background: `repeating-linear-gradient(45deg, ${theme.surface2}, ${theme.surface2} 4px, transparent 4px, transparent 8px)`,
                      border: `1px dashed ${theme.border}`,
                      fontFamily: theme.fontMono, fontSize: 10, fontWeight: 600,
                      color: theme.faint, letterSpacing: 0.3,
                      overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                    }}>★ {s.label}</div>
                  ) : (
                    <div style={{
                      display: 'flex', alignItems: 'center', gap: 8,
                    }}>
                      <div style={{
                        height: 6, width: 60, borderRadius: 99,
                        background: isSel ? theme.accent : '#22C55E',
                      }} />
                      <span style={{
                        fontFamily: theme.fontMono, fontSize: 10, fontWeight: 700,
                        letterSpacing: 0.5,
                        color: isSel ? theme.accent : '#22C55E',
                      }}>{isSel ? 'SELECTED' : 'OPEN'}</span>
                    </div>
                  )}
                </div>

                {/* Right indicator */}
                <div style={{
                  width: 22, height: 22, borderRadius: 99,
                  border: `1.5px solid ${isSel ? theme.accent : (s.busy ? theme.border : theme.muted)}`,
                  background: isSel ? theme.accent : 'transparent',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  flexShrink: 0,
                }}>
                  {isSel && (
                    <svg width="11" height="11" viewBox="0 0 12 12" fill="none">
                      <path d="M2.5 6l2.5 2.5L9.5 3.5" stroke={theme.onAccent}
                            strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  )}
                </div>
              </button>
            );
          })}
        </Card>
      </div>

      {/* ─── Session details (visible once a slot is picked) ─── */}
      {selectedSlot && isCurrent && (
        <div style={{ padding: `${theme.gap + 6}px ${theme.pad}px 0` }}>
          <div style={{
            fontFamily: theme.fontMono, fontSize: 11, color: theme.muted,
            letterSpacing: 1, fontWeight: 600, marginBottom: 10,
          }}>SESSION LENGTH</div>
          <div style={{ display: 'flex', gap: 6, marginBottom: 14 }}>
            {[30, 60, 90].map(m => (
              <button key={m} onClick={() => setDuration(m)} style={{
                flex: 1, padding: '12px 8px', borderRadius: 12, cursor: 'pointer',
                background: duration === m ? theme.text : 'transparent',
                color: duration === m ? theme.bg : theme.text,
                border: duration === m ? 'none' : `1px solid ${theme.border}`,
                fontFamily: theme.fontDisplay, fontSize: 14, letterSpacing: 0.5,
                textTransform: 'uppercase',
              }}>{m} MIN<br/>
                <span style={{
                  fontFamily: theme.fontMono, fontSize: 9, fontWeight: 700,
                  letterSpacing: 0.5,
                  color: duration === m ? theme.bg : theme.muted, opacity: 0.7,
                }}>${(m / 60) * mentor.rate}</span>
              </button>
            ))}
          </div>

          <div style={{
            fontFamily: theme.fontMono, fontSize: 11, color: theme.muted,
            letterSpacing: 1, fontWeight: 600, marginBottom: 10,
          }}>WHAT DO YOU WANT TO COVER?</div>
          <textarea
            value={topic}
            onChange={e => setTopic(e.target.value)}
            placeholder="One or two sentences. Jay reads this before the call."
            rows={3}
            style={{
              width: '100%', padding: '12px 14px', borderRadius: 12,
              border: `1px solid ${theme.border}`,
              fontFamily: theme.fontBody, fontSize: 13, lineHeight: 1.45,
              outline: 'none', resize: 'none', boxSizing: 'border-box',
            }}
          />

          {/* Summary card */}
          <Card theme={theme} style={{ padding: 14, marginTop: 14, borderColor: theme.accent }}>
            <div style={{
              fontFamily: theme.fontMono, fontSize: 9, color: theme.accent,
              letterSpacing: 1, fontWeight: 700,
            }}>★ REQUEST SUMMARY</div>
            <div style={{
              display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10,
              marginTop: 10,
            }}>
              <div>
                <div style={{ fontFamily: theme.fontMono, fontSize: 9, color: theme.muted, letterSpacing: 0.8, fontWeight: 700 }}>WITH</div>
                <div style={{ fontFamily: theme.fontDisplay, fontSize: 14, color: theme.text, marginTop: 2, letterSpacing: 0.3, textTransform: 'uppercase' }}>{mentor.name}</div>
              </div>
              <div>
                <div style={{ fontFamily: theme.fontMono, fontSize: 9, color: theme.muted, letterSpacing: 0.8, fontWeight: 700 }}>DURATION</div>
                <div style={{ fontFamily: theme.fontDisplay, fontSize: 14, color: theme.text, marginTop: 2, letterSpacing: 0.3 }}>{duration} MIN</div>
              </div>
              <div>
                <div style={{ fontFamily: theme.fontMono, fontSize: 9, color: theme.muted, letterSpacing: 0.8, fontWeight: 700 }}>DATE</div>
                <div style={{ fontFamily: theme.fontDisplay, fontSize: 14, color: theme.text, marginTop: 2, letterSpacing: 0.3, textTransform: 'uppercase' }}>
                  {DOW_SHORT[selectedDay.dow]} · {MONTH_SHORT[selectedDay.date.getMonth()]} {selectedDay.date.getDate()}
                </div>
              </div>
              <div>
                <div style={{ fontFamily: theme.fontMono, fontSize: 9, color: theme.muted, letterSpacing: 0.8, fontWeight: 700 }}>TIME · CST</div>
                <div style={{ fontFamily: theme.fontDisplay, fontSize: 14, color: theme.text, marginTop: 2, letterSpacing: 0.3 }}>
                  {formatHourRange(selectedSlot.hour, duration)}
                </div>
              </div>
            </div>
            <div style={{
              marginTop: 12, paddingTop: 10, borderTop: `1px solid ${theme.border}`,
              display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <GoogleMark size={12} />
              <span style={{
                fontFamily: theme.fontMono, fontSize: 9, color: theme.muted,
                letterSpacing: 0.6, fontWeight: 600, lineHeight: 1.4,
              }}>
                ON CONFIRM: HOLDS THE SLOT FOR 15 MIN · INVITE LANDS IN YOUR GMAIL ON PAYMENT
              </span>
            </div>
          </Card>
        </div>
      )}

      {/* ─── Sticky request bar ─── */}
      <div style={{
        position: 'sticky', bottom: 0, marginTop: 18,
        background: `linear-gradient(180deg, transparent 0, ${theme.bg} 30%)`,
        padding: `14px ${theme.pad}px`,
      }}>
        {bookingErr && (
          <div style={{
            marginBottom: 10, padding: '10px 12px', borderRadius: 10,
            background: `${theme.accent}1a`, border: `1px solid ${theme.accent}`,
            fontFamily: theme.fontMono, fontSize: 10, color: theme.accent,
            letterSpacing: 0.5, fontWeight: 700, lineHeight: 1.4,
          }}>⚠ {bookingErr}</div>
        )}
        <button onClick={confirm} disabled={!canConfirm || scheduling} style={{
          width: '100%', padding: '16px', borderRadius: 14,
          background: canConfirm ? theme.accent : theme.surface2,
          color: canConfirm ? theme.onAccent : theme.faint,
          border: 'none', cursor: (canConfirm && !scheduling) ? 'pointer' : 'not-allowed',
          opacity: scheduling ? 0.7 : 1,
          fontFamily: theme.fontDisplay, fontSize: 15, letterSpacing: 1,
          textTransform: 'uppercase',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '16px 18px',
        }}>
          <span>{scheduling ? 'RESERVING…' : (canConfirm ? 'REQUEST APPOINTMENT' : 'SELECT A TIME →')}</span>
          {canConfirm && !scheduling && <span>${price} →</span>}
        </button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// MySessionsScreen — the member's booked 1:1 sessions
// ─────────────────────────────────────────────────────────────
function fmtSessionDate(iso) {
  const d = new Date(iso);
  return `${DOW_SHORT[d.getDay()]} · ${MONTH_SHORT[d.getMonth()]} ${d.getDate()}`;
}
function fmtSessionTime(iso, durationMin) {
  const d = new Date(iso);
  const h = d.getHours();
  return formatHourRange(h + d.getMinutes() / 60, durationMin || 60);
}

// Demo sample so the preview isn't empty when there's no backend.
function demoSessions() {
  const mk = (daysFromNow, hour, coach, color, lbl, status) => {
    const d = new Date(); d.setHours(0, 0, 0, 0);
    d.setDate(d.getDate() + daysFromNow); d.setHours(hour);
    return {
      id: 's-' + daysFromNow + '-' + hour,
      starts_at: d.toISOString(), duration_min: 60, status,
      topic: 'Mix feedback + arrangement notes',
      meet_link: 'https://meet.google.com/demo-launch-session',
      coaches: { name: coach, lbl, color },
    };
  };
  return [
    mk(2, 14, 'Jay Brunswick', '#C72820', 'JB', 'confirmed'),
    mk(6, 11, 'PG Banker', '#7A5AE0', 'PG', 'confirmed'),
  ];
}

const CANCEL_CUTOFF_MS = 24 * 60 * 60 * 1000; // must cancel ≥24h before

function MySessionsScreen({ theme, onBack, onOpenBooking }) {
  const [bookings, setBookings] = useStateB(undefined); // undefined=loading
  const [isDemo, setIsDemo] = useStateB(false);
  const [cancelingId, setCancelingId] = useStateB(null);
  const [cancelErr, setCancelErr] = useStateB(null);
  const [choosingId, setChoosingId] = useStateB(null); // booking showing refund/credit choice
  const [cancelMsg, setCancelMsg] = useStateB(null);
  const [credit, setCredit] = useStateB(0); // account credit, cents
  useEffectB(() => {
    let alive = true;
    window.LAUNCH_USER.fetchMyBookings().then(list => {
      if (!alive) return;
      if (list === null) { setIsDemo(true); setBookings(demoSessions()); }
      else setBookings(list);
    });
    if (window.LAUNCH_USER.fetchMyCredit) {
      window.LAUNCH_USER.fetchMyCredit().then(c => { if (alive) setCredit(c || 0); });
    }
    return () => { alive = false; };
  }, []);

  const dollars = (c) => '$' + Math.round((c || 0) / 100);
  const doCancel = async (b, resolution) => {
    setCancelErr(null); setCancelMsg(null);
    setCancelingId(b.id);
    const res = await window.LAUNCH_USER.cancelBooking(b.id, resolution);
    setCancelingId(null);
    if (res && res.error) { setCancelErr(res.error); return; }
    setChoosingId(null);
    setBookings(prev => (prev || []).map(x => x.id === b.id ? { ...x, status: 'cancelled' } : x));
    if (window.LAUNCH_USER.fetchMyCredit) {
      window.LAUNCH_USER.fetchMyCredit().then(c => setCredit(c || 0));
    }
    if (resolution === 'credit') {
      setCancelMsg('Session cancelled · ' + (res.credited ? dollars(res.credited) + ' added as account credit' : 'credit added to your account'));
    } else {
      setCancelMsg('Session cancelled · ' + (res.refunded ? dollars(res.refunded) + ' refunded to your card' : 'refund processed'));
    }
  };

  const list = bookings || [];
  const now = Date.now();
  const upcoming = list.filter(b => new Date(b.starts_at).getTime() >= now && b.status !== 'cancelled');
  const past = list.filter(b => new Date(b.starts_at).getTime() < now || b.status === 'cancelled');

  const Row = ({ b }) => {
    const c = b.coaches || {};
    const isUpcoming = new Date(b.starts_at).getTime() >= now && b.status !== 'cancelled';
    const msUntil = new Date(b.starts_at).getTime() - now;
    const canCancel = isUpcoming && msUntil >= CANCEL_CUTOFF_MS;
    const tooLateToCancel = isUpcoming && msUntil < CANCEL_CUTOFF_MS;
    const canceling = cancelingId === b.id;
    return (
      <Card theme={theme} style={{ padding: 14, borderColor: isUpcoming ? theme.accent : theme.border }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{
            width: 40, height: 40, borderRadius: 99, background: c.color || theme.accent,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: theme.fontDisplay, color: '#0A0A0A', fontSize: 14, flexShrink: 0,
          }}>{c.lbl || (c.name ? c.name.slice(0, 2).toUpperCase() : '★')}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: theme.fontDisplay, fontSize: 17, color: theme.text, letterSpacing: 0.2, textTransform: 'uppercase', lineHeight: 1 }}>
              {c.name || 'COACH'}
            </div>
            <div style={{ fontFamily: theme.fontMono, fontSize: 10, color: theme.muted, letterSpacing: 0.5, marginTop: 4 }}>
              {fmtSessionDate(b.starts_at)} · {fmtSessionTime(b.starts_at, b.duration_min)}
            </div>
          </div>
          <span style={{
            fontFamily: theme.fontMono, fontSize: 9, fontWeight: 700, letterSpacing: 0.8,
            padding: '5px 9px', borderRadius: 99,
            color: b.status === 'cancelled' ? theme.muted : (isUpcoming ? theme.onAccent : theme.muted),
            background: b.status === 'cancelled' ? theme.surface2 : (isUpcoming ? theme.accent : theme.surface2),
          }}>{(b.status || 'confirmed').toUpperCase()}</span>
        </div>
        {b.topic && (
          <div style={{
            fontFamily: theme.fontBody, fontSize: 12, color: theme.muted, lineHeight: 1.45,
            marginTop: 10, paddingTop: 10, borderTop: `1px solid ${theme.border}`,
          }}>“{b.topic}”</div>
        )}
        {isUpcoming && b.meet_link && (
          <a href={b.meet_link} target="_blank" rel="noopener noreferrer" style={{
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            marginTop: 12, padding: '12px', borderRadius: 12, textDecoration: 'none',
            background: theme.accent, color: theme.onAccent,
            fontFamily: theme.fontDisplay, fontSize: 13, letterSpacing: 1, textTransform: 'uppercase',
          }}>
            <GoogleMark size={14} /> JOIN GOOGLE MEET →
          </a>
        )}
        {canCancel && choosingId !== b.id && (
          <button onClick={() => { setChoosingId(b.id); setCancelErr(null); setCancelMsg(null); }} disabled={canceling} style={{
            width: '100%', marginTop: 8, padding: '11px', borderRadius: 12,
            background: 'transparent', border: `1px solid ${theme.border}`,
            color: theme.text, cursor: 'pointer',
            fontFamily: theme.fontMono, fontSize: 11, fontWeight: 700, letterSpacing: 1,
            textTransform: 'uppercase',
          }}>CANCEL SESSION</button>
        )}
        {canCancel && choosingId === b.id && (
          <div style={{ marginTop: 10, paddingTop: 10, borderTop: `1px solid ${theme.border}` }}>
            <div style={{
              fontFamily: theme.fontMono, fontSize: 9, color: theme.muted, letterSpacing: 0.5,
              fontWeight: 700, marginBottom: 8, textAlign: 'center',
            }}>HOW DO YOU WANT YOUR MONEY BACK?</div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={() => doCancel(b, 'refund')} disabled={canceling} style={{
                flex: 1, padding: '11px 8px', borderRadius: 12,
                background: theme.surface, border: `1px solid ${theme.border}`,
                color: theme.text, cursor: canceling ? 'wait' : 'pointer',
                fontFamily: theme.fontMono, fontSize: 10, fontWeight: 700, letterSpacing: 0.5,
                textTransform: 'uppercase',
              }}>{canceling ? '…' : '↩ REFUND TO CARD'}</button>
              <button onClick={() => doCancel(b, 'credit')} disabled={canceling} style={{
                flex: 1, padding: '11px 8px', borderRadius: 12,
                background: theme.accent, border: 'none',
                color: theme.onAccent, cursor: canceling ? 'wait' : 'pointer',
                fontFamily: theme.fontMono, fontSize: 10, fontWeight: 700, letterSpacing: 0.5,
                textTransform: 'uppercase',
              }}>{canceling ? '…' : '★ ACCOUNT CREDIT'}</button>
            </div>
            <button onClick={() => setChoosingId(null)} disabled={canceling} style={{
              width: '100%', marginTop: 8, padding: '8px', borderRadius: 10,
              background: 'transparent', border: 'none', color: theme.muted, cursor: 'pointer',
              fontFamily: theme.fontMono, fontSize: 9, fontWeight: 700, letterSpacing: 1,
              textTransform: 'uppercase',
            }}>KEEP MY SESSION</button>
          </div>
        )}
        {tooLateToCancel && (
          <div style={{
            marginTop: 8, fontFamily: theme.fontMono, fontSize: 9, color: theme.muted,
            letterSpacing: 0.5, fontWeight: 600, textAlign: 'center', lineHeight: 1.4,
          }}>CANCELLATION CLOSED · LESS THAN 24H AWAY</div>
        )}
      </Card>
    );
  };

  return (
    <div style={{ paddingBottom: 130 }}>
      {/* Top bar */}
      <div style={{
        paddingTop: 58, paddingBottom: 8, paddingLeft: theme.pad, paddingRight: theme.pad,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <button onClick={onBack} style={{
          width: 38, height: 38, borderRadius: 12,
          background: theme.surface, border: `1px solid ${theme.border}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
            <path d="M9 2L4 7l5 5" stroke={theme.text} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
        {isDemo && (
          <span style={{
            fontFamily: theme.fontMono, fontSize: 9, color: '#FBBF24', letterSpacing: 1, fontWeight: 700,
          }}>PREVIEW DATA</span>
        )}
      </div>

      {/* Hero */}
      <div style={{ padding: `4px ${theme.pad}px 0` }}>
        <div style={{ fontFamily: theme.fontMono, fontSize: 10, color: theme.accent, letterSpacing: 1, fontWeight: 700, marginBottom: 6 }}>
          ★ BOOKED 1:1s
        </div>
        <DisplayHeading theme={theme} size={36}>MY <span style={{ color: theme.accent }}>SESSIONS</span></DisplayHeading>
      </div>

      {credit > 0 && (
        <div style={{ padding: `${theme.gap}px ${theme.pad}px 0` }}>
          <div style={{
            padding: '12px 14px', borderRadius: 12,
            background: `${theme.accent}14`, border: `1px solid ${theme.accent}55`,
            display: 'flex', alignItems: 'center', gap: 10,
          }}>
            <span style={{ fontSize: 18 }}>★</span>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 18, color: theme.text, letterSpacing: 0.2 }}>
                ${Math.round(credit / 100)} ACCOUNT CREDIT
              </div>
              <div style={{ fontFamily: theme.fontMono, fontSize: 9, color: theme.muted, letterSpacing: 0.5, marginTop: 2 }}>
                APPLIED AUTOMATICALLY ON YOUR NEXT SESSION
              </div>
            </div>
          </div>
        </div>
      )}

      {cancelErr && (
        <div style={{ padding: `${theme.gap}px ${theme.pad}px 0` }}>
          <div style={{
            padding: '10px 12px', borderRadius: 10,
            background: `${theme.accent}1a`, border: `1px solid ${theme.accent}`,
            fontFamily: theme.fontMono, fontSize: 10, color: theme.accent,
            letterSpacing: 0.5, fontWeight: 700, lineHeight: 1.4,
          }}>⚠ {cancelErr}</div>
        </div>
      )}
      {cancelMsg && (
        <div style={{ padding: `${theme.gap}px ${theme.pad}px 0` }}>
          <div style={{
            padding: '10px 12px', borderRadius: 10,
            background: '#22C55E1a', border: '1px solid #22C55E',
            fontFamily: theme.fontMono, fontSize: 10, color: '#22C55E',
            letterSpacing: 0.5, fontWeight: 700, lineHeight: 1.4,
          }}>✓ {cancelMsg}</div>
        </div>
      )}

      {bookings === undefined ? (
        <div style={{ padding: `${theme.gap + 10}px ${theme.pad}px`, fontFamily: theme.fontMono, fontSize: 11, color: theme.muted, letterSpacing: 0.5 }}>
          LOADING…
        </div>
      ) : list.length === 0 ? (
        <div style={{ padding: `${theme.gap + 6}px ${theme.pad}px 0` }}>
          <Card theme={theme} style={{ padding: 24, textAlign: 'center', borderStyle: 'dashed', borderColor: theme.border }}>
            <div style={{ fontSize: 30, marginBottom: 8 }}>📅</div>
            <div style={{ fontFamily: theme.fontDisplay, fontSize: 18, color: theme.text, textTransform: 'uppercase' }}>NO SESSIONS YET</div>
            <div style={{ fontFamily: theme.fontBody, fontSize: 13, color: theme.muted, marginTop: 6, lineHeight: 1.45 }}>
              Book a 1:1 with a coach and it'll show up here with the Google Meet link.
            </div>
            {onOpenBooking && (
              <button onClick={() => onOpenBooking()} style={{
                marginTop: 14, padding: '12px 18px', borderRadius: 12,
                background: theme.accent, color: theme.onAccent, border: 'none', cursor: 'pointer',
                fontFamily: theme.fontDisplay, fontSize: 13, letterSpacing: 1, textTransform: 'uppercase',
              }}>BOOK A SESSION →</button>
            )}
          </Card>
        </div>
      ) : (
        <>
          {upcoming.length > 0 && (
            <div style={{ padding: `${theme.gap + 6}px ${theme.pad}px 0` }}>
              <div style={{ fontFamily: theme.fontMono, fontSize: 11, color: theme.muted, letterSpacing: 1, fontWeight: 600, marginBottom: 10 }}>
                UPCOMING · {upcoming.length}
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {upcoming.map(b => <Row key={b.id} b={b} />)}
              </div>
            </div>
          )}
          {past.length > 0 && (
            <div style={{ padding: `${theme.gap + 6}px ${theme.pad}px 0` }}>
              <div style={{ fontFamily: theme.fontMono, fontSize: 11, color: theme.muted, letterSpacing: 1, fontWeight: 600, marginBottom: 10 }}>
                PAST · {past.length}
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {past.map(b => <Row key={b.id} b={b} />)}
              </div>
            </div>
          )}
        </>
      )}
    </div>
  );
}

window.LAUNCH_BOOKING = { BookingScreen, MySessionsScreen };
