// Molara — Booking flow (multi-step, stateful)

// Dental-care grouped reasons. Keys (k) match DOCTORS[i].k so we can shortlist matching dentists.
const REASON_GROUPS = [
  { k: 'emergency', label: 'Emergency 24/7',       icon: 'shield',   reasons: ['Severe tooth ache', 'Swelling or abscess', 'Broken or chipped tooth', 'Wisdom tooth flare-up', 'Bleeding after dental work', 'Other issue'] },
  { k: 'toothache', label: 'Tooth ache',           icon: 'tooth',    reasons: ['Cold sensitivity', 'Pain while chewing', 'Cavity concern', 'Root canal second opinion', 'Gum bleeding', 'Other issue'] },
  { k: 'kids',      label: 'Kids tooth care',      icon: 'baby',     reasons: ['Child tooth pain', 'Milk tooth concern', 'Cavity prevention', 'Teething advice', 'Dental anxiety', 'Other issue'] },
  { k: 'aligners',  label: 'Aligners & braces',   icon: 'settings', reasons: ['Clear aligner opinion', 'Braces consultation', 'Retainer concern', 'Bite correction', 'Mid-treatment review', 'Other issue'] },
  { k: 'cosmetic',  label: 'Whitening & cosmetic',icon: 'sparkle',  reasons: ['Teeth whitening', 'Smile design', 'Veneers opinion', 'Chipped tooth bonding', 'Stain or discoloration', 'Other issue'] },
];

const BOOKING_SLOTS = {
  Morning: ['9:00a','9:30a','10:00a','10:30a','11:00a','11:30a'],
  Afternoon: ['12:00p','12:30p','1:00p','1:30p','2:00p','2:30p','3:00p','3:30p'],
  Evening: ['4:00p','4:30p','5:00p','5:30p','6:00p'],
};

function slotToMinutes(slot) {
  const m = /^(\d{1,2}):(\d{2})(a|p)$/i.exec(String(slot || '').trim());
  if (!m) return 0;
  let h = Number(m[1]);
  const min = Number(m[2]);
  const mer = m[3].toLowerCase();
  if (mer === 'p' && h !== 12) h += 12;
  if (mer === 'a' && h === 12) h = 0;
  return h * 60 + min;
}

function formatBookingDay(offset) {
  const d = new Date();
  d.setDate(d.getDate() + offset);
  const month = d.toLocaleDateString('en-IN', { month: 'short' });
  const day = d.getDate();
  if (offset === 0) return `Today · ${month} ${day}`;
  if (offset === 1) return `Tomorrow · ${month} ${day}`;
  const weekday = d.toLocaleDateString('en-IN', { weekday: 'short' });
  return `${weekday} · ${month} ${day}`;
}

function bookingDaysFromToday() {
  return [0, 1, 2, 3].map(formatBookingDay);
}

function nextBookingSlot() {
  const now = new Date();
  const currentMinutes = now.getHours() * 60 + now.getMinutes();
  const allSlots = Object.values(BOOKING_SLOTS).flat();
  const future = allSlots.find((s) => slotToMinutes(s) > currentMinutes + 30);
  return future || allSlots[0];
}

function bookingCurrentMinutes() {
  const now = new Date();
  return now.getHours() * 60 + now.getMinutes();
}

function slotIsPastForDay(dayOffset, slot) {
  return Number(dayOffset) === 0 && slotToMinutes(slot) <= bookingCurrentMinutes();
}

function firstAvailableSlotForDay(dayOffset) {
  return Object.values(BOOKING_SLOTS).flat().find((slot) => !slotIsPastForDay(dayOffset, slot)) || '';
}

function dayHasAvailableSlots(dayOffset) {
  return !!firstAvailableSlotForDay(dayOffset);
}

function bookingRouteParams(route) {
  const q = (route || window.location.hash.replace(/^#/, '') || '').split('?')[1] || '';
  return new URLSearchParams(q);
}

const BOOKING_MODE_OPTIONS = [
  { k: 'video', label: 'Video consult', short: 'Video', icon: 'video' },
  { k: 'audio', label: 'Audio consult', short: 'Audio', icon: 'mic' },
  { k: 'chat', label: 'Chat consult', short: 'Chat', icon: 'chat' },
];
const BOOKING_MODE_RANK = { chat: 1, audio: 2, video: 3, whatsapp: 3 };

function bookingModeKey(mode) {
  const m = String(mode || '').trim().toLowerCase();
  if (m === 'chat') return 'chat';
  if (m === 'audio' || m === 'voice') return 'audio';
  return 'video';
}

function bookingModeLabel(mode) {
  const key = bookingModeKey(mode);
  return key === 'video' ? 'WhatsApp video'
    : key === 'audio' ? 'WhatsApp audio'
    : 'WhatsApp chat';
}

function bookingModeFee(doc, mode) {
  const base = Number(doc?.fee || 499);
  const key = bookingModeKey(mode);
  if (key === 'chat') return Math.min(349, base);
  if (key === 'audio') return Math.min(Math.max(399, Math.round(base * 0.8)), base);
  return base;
}

function bookingModeUpgradeCharge(doc, fromMode, toMode) {
  return Math.max(0, bookingModeFee(doc, toMode) - bookingModeFee(doc, fromMode));
}

function bookingFreeFollowupRule(mode) {
  const key = bookingModeKey(mode);
  if (key === 'video') return '1 free follow-up can be video, audio, or chat.';
  if (key === 'audio') return '1 free follow-up can be audio or chat. Video upgrade is charged as the difference.';
  return '1 free follow-up is chat only. Audio or video upgrade is charged as the difference.';
}

function consultSpecKey(consult) {
  const care = String(consult?.careType || '').toLowerCase();
  const reason = String(consult?.reason || '').toLowerCase();
  const byLabel = REASON_GROUPS.find((g) => care === g.label.toLowerCase());
  if (byLabel) return byLabel.k;
  if (care.includes('emergency') || reason.includes('emergency')) return 'emergency';
  if (care.includes('tooth') || reason.includes('ache') || reason.includes('sensitivity')) return 'toothache';
  if (care.includes('kids') || care.includes('child') || reason.includes('child')) return 'kids';
  if (care.includes('aligner') || care.includes('brace') || reason.includes('brace')) return 'aligners';
  if (care.includes('whitening') || care.includes('cosmetic') || reason.includes('smile')) return 'cosmetic';
  return '';
}

function BookingFlow({ tone = 'warm', route = '' }) {
  const { user } = useAuth();
  useDoctorReviews();
  const consults = useConsults();
  const routeParams = bookingRouteParams(route);
  const hasRequestedDoctor = routeParams.has('doctor');
  const requestedDocId = Number(routeParams.get('doctor'));
  const requestedFollowup = routeParams.get('followup') === '1';
  const requestedFollowupFor = routeParams.get('from') || null;
  const requestedEmergencyParam = routeParams.get('emergency') === '1';
  const requestedSpecParam = routeParams.get('spec') || '';
  const requestedSpec = REASON_GROUPS.some((g) => g.k === requestedSpecParam) ? requestedSpecParam : '';
  const directRequestedDoc = hasRequestedDoctor && Number.isFinite(requestedDocId) ? DOCTORS.find((d) => d.id === requestedDocId) : null;
  const requestedEmergency = requestedEmergencyParam;
  const requestedDoc = directRequestedDoc || (requestedEmergency ? DOC_BY_ID(1) : null);
  const sourceFollowupConsult = requestedFollowupFor ? consults.find((c) => String(c.id) === String(requestedFollowupFor)) : null;
  const sourceFollowupSpec = requestedFollowup ? consultSpecKey(sourceFollowupConsult) : '';
  const doctorLocked = !!requestedDoc;
  const requestedSpecLocked = !!(requestedSpec && requestedDoc && doctorMatchesSpec(requestedDoc, requestedSpec));
  const onlineDoctors = usePresence();
  const [step, setStep] = React.useState((requestedFollowup && requestedDoc) || requestedEmergency ? 3 : 1);
  const [specK, setSpecK] = React.useState(sourceFollowupSpec || (requestedSpecLocked ? requestedSpec : (requestedDoc?.k || 'emergency')));
  const [reason, setReason] = React.useState(requestedFollowup ? 'Follow-up consultation' : 'Severe tooth ache');
  const [severity, setSev] = React.useState(requestedEmergency ? 8 : 2);
  const [slot, setSlot] = React.useState(() => nextBookingSlot());
  const [day, setDay] = React.useState(() => dayHasAvailableSlots(0) ? 0 : 1);
  const [docId, setDocId] = React.useState(requestedDoc?.id || 1);
  const [mode, setMode] = React.useState('video');
  const [note, setNote] = React.useState('');
  const doc = DOC_BY_ID(docId);
  const selectedDoctorOnline = onlineDoctors.has(doc.id);
  const BOOKING_DAYS = React.useMemo(() => bookingDaysFromToday(), []);
  const [bookedSlotsByDay, setBookedSlotsByDay] = React.useState({});
  const selectedDay = BOOKING_DAYS[day] || BOOKING_DAYS[0];
  const selectedTime = formatSlot(slot);
  const slotBookedFor = React.useCallback((dayOffset, rawSlot) => {
    const dayLabel = BOOKING_DAYS[dayOffset] || formatBookingDay(dayOffset);
    const booked = bookedSlotsByDay[dayLabel] || [];
    const label = formatSlot(rawSlot);
    return booked.some((t) => String(t).trim().toLowerCase() === String(label).trim().toLowerCase());
  }, [bookedSlotsByDay, BOOKING_DAYS]);
  const slotUnavailableFor = React.useCallback((dayOffset, rawSlot) => {
    return slotIsPastForDay(dayOffset, rawSlot) || slotBookedFor(dayOffset, rawSlot);
  }, [slotBookedFor]);
  const firstAvailableSlotFor = React.useCallback((dayOffset) => {
    return Object.values(BOOKING_SLOTS).flat().find((rawSlot) => !slotUnavailableFor(dayOffset, rawSlot)) || '';
  }, [slotUnavailableFor]);
  const bookingDayHasSlots = React.useCallback((dayOffset) => !!firstAvailableSlotFor(dayOffset), [firstAvailableSlotFor]);
  const emergencyCareSelected = requestedEmergency || (doctorLocked && specK === 'emergency');
  const selectedSlotUnavailable = !emergencyCareSelected && slotUnavailableFor(day, slot);
  const bookingDayLabel = emergencyCareSelected ? 'Today' : selectedDay;
  const bookingTimeLabel = emergencyCareSelected ? 'Immediate' : selectedTime;
  const bookingSlot = emergencyCareSelected ? 'Immediate' : slot;
  const [followupEligibility, setFollowupEligibility] = React.useState(null);
  const isFreeFollowup = requestedFollowup && !!followupEligibility?.eligible;
  const paidFollowupAfterFreeUsed = !!(requestedFollowup && followupEligibility && !followupEligibility.eligible);
  const sourceFollowupMode = bookingModeKey(sourceFollowupConsult?.mode || 'video');
  const selectedModeFee = bookingModeFee(doc, mode);
  const followupUpgradeCharge = requestedFollowup && isFreeFollowup ? bookingModeUpgradeCharge(doc, sourceFollowupMode, mode) : 0;
  const displayedFee = isFreeFollowup ? followupUpgradeCharge : selectedModeFee;
  const modeOptions = BOOKING_MODE_OPTIONS.map((opt) => {
    const included = !requestedFollowup || BOOKING_MODE_RANK[opt.k] <= BOOKING_MODE_RANK[sourceFollowupMode];
    const upgradeFee = requestedFollowup && isFreeFollowup ? bookingModeUpgradeCharge(doc, sourceFollowupMode, opt.k) : 0;
    return { ...opt, included, upgradeFee };
  });
  const activeGroup = REASON_GROUPS.find(g => g.k === specK) || REASON_GROUPS[0];
  const availableReasonGroups = doctorLocked
    ? (requestedEmergency ? REASON_GROUPS.filter((g) => g.k === 'emergency') : requestedSpecLocked ? REASON_GROUPS.filter((g) => g.k === requestedSpec) : REASON_GROUPS.filter((g) => doctorMatchesSpec(requestedDoc, g.k)))
    : REASON_GROUPS;
  const flowSteps = doctorLocked
    ? (requestedFollowup || requestedEmergency ? [{ key: 3, label: emergencyCareSelected ? 'WhatsApp details' : 'Date & Time' }, { key: 4, label: 'Confirm' }] : [{ key: 1, label: 'Symptoms' }, { key: 3, label: emergencyCareSelected ? 'WhatsApp details' : 'Date & Time' }, { key: 4, label: 'Confirm' }])
    : [{ key: 1, label: 'Symptoms' }, { key: 2, label: 'Dentist' }, { key: 3, label: 'Date & Time' }, { key: 4, label: 'Confirm' }];
  const currentStepIndex = Math.max(0, flowSteps.findIndex((s) => s.key === step));
  const goPrev = () => setStep(flowSteps[Math.max(0, currentStepIndex - 1)].key);
  const goNext = () => setStep(flowSteps[Math.min(flowSteps.length - 1, currentStepIndex + 1)].key);
  const isFinalStep = step === flowSteps[flowSteps.length - 1].key;
  // Shortlist: prefer dentists for the chosen care type, then top-rated online others.
  const shortlist = React.useMemo(() => {
    const matched = DOCTORS.filter(d => d.online && doctorMatchesSpec(d, specK));
    const others  = DOCTORS.filter(d => d.online && !doctorMatchesSpec(d, specK)).sort((a,b) => Number(doctorStats(b).rating) - Number(doctorStats(a).rating));
    return [...matched, ...others].slice(0, 4);
  }, [specK]);
  React.useEffect(() => {
    if (!requestedDoc) return;
    setDocId(requestedDoc.id);
    const nextSpec = requestedFollowup && sourceFollowupSpec ? sourceFollowupSpec : (requestedSpecLocked ? requestedSpec : requestedDoc.k);
    setSpecK(nextSpec);
    const group = REASON_GROUPS.find(g => g.k === nextSpec) || REASON_GROUPS[0];
    setReason(requestedFollowup ? 'Follow-up consultation' : group.reasons[0]);
    setStep((s) => (s === 2 || requestedEmergency) ? 3 : s);
  }, [requestedDoc?.id, requestedEmergency, requestedFollowup, requestedSpecLocked, requestedSpec, sourceFollowupSpec]);
  React.useEffect(() => {
    if (!requestedFollowup || !docId || !window.checkFollowupEligible) return;
    window.checkFollowupEligible(docId, requestedFollowupFor).then((elig) => setFollowupEligibility(elig || { eligible: false }));
  }, [requestedFollowup, docId, requestedFollowupFor]);
  React.useEffect(() => {
    setMode(requestedFollowup ? sourceFollowupMode : 'video');
  }, [requestedFollowup, sourceFollowupConsult?.mode]);
  React.useEffect(() => {
    let active = true;
    if (emergencyCareSelected || !window.getBookedSlotsForDoctor) {
      setBookedSlotsByDay({});
      return () => { active = false; };
    }
    window.getBookedSlotsForDoctor(docId, BOOKING_DAYS).then((booked) => {
      if (active) setBookedSlotsByDay(booked || {});
    });
    return () => { active = false; };
  }, [docId, emergencyCareSelected, BOOKING_DAYS.join('|'), consults.length]);
  React.useEffect(() => {
    if (emergencyCareSelected) return;
    if (!slotUnavailableFor(day, slot)) return;
    const next = firstAvailableSlotFor(day);
    if (next) {
      setSlot(next);
    } else {
      const nextDay = [0, 1, 2, 3].find((d) => d !== day && bookingDayHasSlots(d));
      if (nextDay != null) {
        setDay(nextDay);
        setSlot(firstAvailableSlotFor(nextDay) || BOOKING_SLOTS.Morning[0]);
      }
    }
  }, [day, slot, emergencyCareSelected, slotUnavailableFor, firstAvailableSlotFor, bookingDayHasSlots]);
  // Follow-ups still go through a short booking screen so the patient can add
  // notes for the dentist. Emergency follow-ups skip date/time, but not notes.
  // When care type changes, default-pick the first matched dentist so step 2 makes sense.
  React.useEffect(() => {
    if (doctorLocked) return;
    if (shortlist[0] && !shortlist.some(d => d.id === docId)) setDocId(shortlist[0].id);
  }, [specK, doctorLocked]);

  return (
    <div className="ml-root" style={{ height: '100%', overflow: 'hidden', display: 'grid', gridTemplateColumns: '1fr 420px' }}>
      {/* Left: form */}
      <div style={{ padding: '32px 56px 32px', overflowY: 'auto' }}>
        {/* Top bar */}
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: 32 }}>
          <Logo size={20}/>
          <div style={{ marginLeft: 'auto', fontSize: 12, color: 'var(--ink-3)', display: 'inline-flex', alignItems: 'center', gap: 6 }}>
            <I.shield size={13}/> Encrypted · HIPAA
          </div>
        </div>

        {/* Stepper */}
        <div style={{ display: 'flex', gap: 10, marginBottom: 32 }}>
          {flowSteps.map((s, i) => {
            const active = s.key === step;
            const done = i < currentStepIndex;
            return (
              <div key={s.key} style={{ flex: 1 }}>
                <div style={{ height: 3, borderRadius: 2, background: done || active ? 'var(--blue)' : 'var(--line)' }}/>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginTop: 8, fontSize: 12, color: active ? 'var(--ink)' : 'var(--ink-3)' }}>
                  <span style={{ width: 18, height: 18, borderRadius: 9, fontSize: 10, display: 'grid', placeItems: 'center', background: done ? 'var(--blue)' : active ? 'var(--ink)' : 'var(--line-2)', color: done || active ? '#fff' : 'var(--ink-3)', fontFamily: 'var(--mono)' }}>
                    {done ? <I.check size={10}/> : i + 1}
                  </span>
                  {s.label}
                </div>
              </div>
            );
          })}
        </div>

        {step === 1 && (
          <section>
            <h1 style={{ fontSize: 40, marginBottom: 8 }}>
              {requestedEmergency ? 'What kind of emergency dental help do you need?' : (tone === 'warm' ? 'What dental issue brings you in today?' : 'Describe your dental concern.')}
            </h1>
            <p style={{ color: 'var(--ink-3)', marginBottom: 28 }}>
              {requestedEmergency ? 'Choose the closest emergency concern and pain level first. Dr. Shivani is available 24/7 after this intake.' : (tone === 'warm' ? 'Pick what sounds closest — you can explain more in a minute.' : 'Select the dental category that best matches. Additional details collected next.')}
            </p>
            <div className="ml-label" style={{ marginBottom: 10 }}>{requestedEmergency ? 'Emergency type' : 'Dental care type'}</div>

            {/* Dental care tabs */}
            <div style={{ display: 'flex', gap: 6, marginBottom: 16, flexWrap: 'wrap' }}>
              {availableReasonGroups.map((g) => {
                const Ic = I[g.icon];
                const active = g.k === specK;
                return (
                  <button key={g.k}
                    onClick={() => { setSpecK(g.k); setReason(g.reasons[0]); }}
                    style={{
                      display: 'inline-flex', alignItems: 'center', gap: 6,
                      padding: '8px 12px', borderRadius: 999, fontSize: 12, fontWeight: 500,
                      border: '1px solid ' + (active ? 'var(--ink)' : 'var(--line)'),
                      background: active ? 'var(--ink)' : '#fff',
                      color: active ? '#fff' : 'var(--ink-2)',
                      cursor: 'pointer', whiteSpace: 'nowrap',
                    }}>
                    {Ic && <Ic size={13}/>}
                    {g.label}
                  </button>
                );
              })}
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 10, marginBottom: 28 }}>
              {activeGroup.reasons.map((r) => (
                <button key={r} onClick={() => setReason(r)}
                  className="ml-card"
                  style={{ padding: 16, textAlign: 'left', border: '1px solid ' + (reason === r ? 'var(--blue)' : 'var(--line)'),
                    background: reason === r ? 'var(--blue-tint)' : '#fff', cursor: 'pointer', fontWeight: 500, fontSize: 14, display: 'flex', alignItems: 'center', gap: 10 }}>
                  <span style={{ width: 16, height: 16, borderRadius: 8, border: '1.5px solid ' + (reason === r ? 'var(--blue)' : 'var(--ink-4)'),
                    background: reason === r ? 'var(--blue)' : 'transparent', display: 'grid', placeItems: 'center' }}>
                    {reason === r && <span style={{ width: 6, height: 6, borderRadius: 3, background: '#fff' }}/>}
                  </span>
                  {r}
                </button>
              ))}
            </div>

            <div className="ml-label" style={{ marginBottom: 10 }}>Pain level (if applicable)</div>
            <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
              {[0,1,2,3,4,5,6,7,8,9,10].map((n) => (
                <button key={n} onClick={() => setSev(n)}
                  style={{ flex: 1, padding: '10px 0', border: '1px solid var(--line)', background: n === severity ? 'var(--ink)' : '#fff',
                    color: n === severity ? '#fff' : 'var(--ink)', borderRadius: 6, fontFamily: 'var(--mono)', fontSize: 13, cursor: 'pointer' }}>
                  {n}
                </button>
              ))}
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginBottom: 40 }}>
              <span>NONE</span><span>TOLERABLE</span><span>SEVERE</span>
            </div>

            {doctorLocked && (
              <>
                <div className="ml-card" style={{ padding: 16, display: 'grid', gridTemplateColumns: '52px 1fr auto', gap: 14, alignItems: 'center', marginBottom: 20 }}>
                  <div className="ml-avatar" style={{ width: 52, height: 52, borderRadius: 12, fontSize: 16,
                    background: TONE_BG[doc.tone], color: TONE_FG[doc.tone] }}>{doc.avatar}</div>
                  <div>
                    <div className="ml-label" style={{ marginBottom: 4 }}>Selected dentist</div>
                    <div style={{ fontFamily: 'var(--display)', fontSize: 20, fontWeight: 500 }}>{doc.n}</div>
                    <div style={{ fontSize: 13, color: 'var(--ink-3)' }}>
                      {doc.spec} · {requestedEmergency ? 'Available 24/7 for emergencies' : (doc.wait || '5 min wait')}
                    </div>
                  </div>
                  {requestedEmergency
                    ? <span className="ml-pill ml-pill--mint"><I.shield size={12}/> 24/7 emergency</span>
                    : selectedDoctorOnline && <span className="ml-pill ml-pill--mint"><span className="ml-live"/> Online</span>}
                </div>

                <div className="ml-label" style={{ marginBottom: 10 }}>Anything else {doc.n} should know? (optional)</div>
                <textarea className="ml-input" rows={3} placeholder="Sharp pain on my upper right tooth when I drink cold water. Started Tuesday..."
                  value={note} onChange={(e) => setNote(e.target.value)}
                  style={{ resize: 'none', marginBottom: 32, fontFamily: 'var(--sans)' }}/>
              </>
            )}
          </section>
        )}

        {!doctorLocked && step === 2 && (
          <section>
            <h1 style={{ fontSize: 40, marginBottom: 8 }}>
              {tone === 'warm' ? 'Choose your dentist.' : 'Select dentist.'}
            </h1>
            <p style={{ color: 'var(--ink-3)', marginBottom: 28 }}>
              {tone === 'warm' ? `These dentists are online now — matched for ${activeGroup.label.toLowerCase()}.` : `Dentists available now — filtered by ${activeGroup.label}.`}
            </p>

            <div style={{ display: 'grid', gap: 14, marginBottom: 28 }}>
              {shortlist.map((d) => {
                const active = d.id === docId;
                const stats = doctorStats(d);
                return (
                  <button key={d.id} onClick={() => setDocId(d.id)}
                    className="ml-card"
                    style={{ padding: 20, textAlign: 'left', border: '1px solid ' + (active ? 'var(--blue)' : 'var(--line)'),
                      background: active ? 'var(--blue-tint)' : '#fff', cursor: 'pointer',
                      boxShadow: active ? '0 0 0 3px oklch(92% 0.05 240)' : 'none',
                      display: 'grid', gridTemplateColumns: '72px 1fr auto', gap: 18, alignItems: 'center' }}>
                    <div className="ml-avatar" style={{ width: 72, height: 72, borderRadius: 12, fontSize: 22,
                      background: TONE_BG[d.tone], color: TONE_FG[d.tone] }}>{d.avatar}</div>
                    <div>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                        <span style={{ fontFamily: 'var(--display)', fontSize: 22, fontWeight: 500 }}>{d.n}</span>
                        <span className="ml-pill ml-pill--ghost" style={{ fontFamily: 'var(--mono)', fontSize: 10 }}>{d.creds}</span>
                        <span className="ml-pill ml-pill--mint"><span className="ml-live"/> Online</span>
                      </div>
                      <div style={{ fontSize: 13, color: 'var(--ink-3)', marginBottom: 8 }}>
                        {d.spec} · {d.y} yrs experience · {d.loc}
                      </div>
                      <div style={{ fontSize: 12, color: 'var(--ink-2)', display: 'flex', gap: 14 }}>
                        <span style={bookingInline}><I.star size={12}/> <b>{stats.rating}</b> <span className="ml-quiet">({stats.reviews} reviews)</span></span>
                        <span>{d.bio}</span>
                      </div>
                    </div>
                    <span style={{ width: 20, height: 20, borderRadius: 10, border: '1.5px solid ' + (active ? 'var(--blue)' : 'var(--ink-4)'),
                      background: active ? 'var(--blue)' : 'transparent', display: 'grid', placeItems: 'center' }}>
                      {active && <I.check size={11} style={{ color: '#fff' }}/>}
                    </span>
                  </button>
                );
              })}
            </div>

            <div className="ml-label" style={{ marginBottom: 10 }}>Anything else {doc.n} should know? (optional)</div>
            <textarea className="ml-input" rows={3} placeholder="Sharp pain on my upper right tooth when I drink cold water. Started Tuesday..."
              value={note} onChange={(e) => setNote(e.target.value)}
              style={{ resize: 'none', marginBottom: 32, fontFamily: 'var(--sans)' }}/>
          </section>
        )}

        {step === 3 && (
          <section>
            <h1 style={{ fontSize: 40, marginBottom: 8 }}>
              {requestedFollowup ? 'Add follow-up notes.' : (emergencyCareSelected ? 'Confirm WhatsApp consultation.' : (tone === 'warm' ? 'Choose date and time.' : 'Select consultation window.'))}
            </h1>
            <p style={{ color: 'var(--ink-3)', marginBottom: 24 }}>
              {requestedFollowup
                ? (isFreeFollowup
                  ? (followupUpgradeCharge > 0
                    ? `One follow-up is included free within 7 days. Because this is an upgraded ${bookingModeLabel(mode).replace('WhatsApp ', '')} follow-up, only the ₹${followupUpgradeCharge} difference is payable.`
                    : 'This follow-up is included free within 7 days. One free follow-up is allowed for this treatment.')
                  : 'Add what the dentist should know. Payment is needed because the free 7-day follow-up has ended or has already been used.')
                : emergencyCareSelected
                ? (requestedEmergency ? `${doc.n} handles emergency consults around the clock. Add the emergency details, then confirm. The WhatsApp link will be sent by email.` : `${doc.n} handles emergency consults around the clock, so no date or time selection is needed. The WhatsApp link will be sent by email.`)
                : doc.wait === 'No waiting time'
                ? `${doc.n} is available now. The WhatsApp link will be sent by email after confirmation.`
                : `${doc.n} has 14 openings across the next 3 days.`}
            </p>

            {requestedEmergency && (
              <div className="ml-card" style={{ padding: 18, marginBottom: 24, borderColor: 'var(--line)' }}>
                <div className="ml-label" style={{ marginBottom: 10 }}>Type of emergency</div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 10, marginBottom: 22 }}>
                  {activeGroup.reasons.map((r) => (
                    <button key={r} onClick={() => setReason(r)}
                      className="ml-card"
                      style={{ padding: 14, textAlign: 'left', border: '1px solid ' + (reason === r ? 'var(--blue)' : 'var(--line)'),
                        background: reason === r ? 'var(--blue-tint)' : '#fff', cursor: 'pointer', fontWeight: 500, fontSize: 13.5, display: 'flex', alignItems: 'center', gap: 10, boxShadow: 'none' }}>
                      <span style={{ width: 16, height: 16, borderRadius: 8, border: '1.5px solid ' + (reason === r ? 'var(--blue)' : 'var(--ink-4)'),
                        background: reason === r ? 'var(--blue)' : 'transparent', display: 'grid', placeItems: 'center', flex: '0 0 auto' }}>
                        {reason === r && <span style={{ width: 6, height: 6, borderRadius: 3, background: '#fff' }}/>}
                      </span>
                      {r}
                    </button>
                  ))}
                </div>

                <div className="ml-label" style={{ marginBottom: 10 }}>Pain level</div>
                <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
                  {[0,1,2,3,4,5,6,7,8,9,10].map((n) => (
                    <button key={n} onClick={() => setSev(n)}
                      style={{ flex: 1, padding: '10px 0', border: '1px solid var(--line)', background: n === severity ? 'var(--ink)' : '#fff',
                        color: n === severity ? '#fff' : 'var(--ink)', borderRadius: 6, fontFamily: 'var(--mono)', fontSize: 13, cursor: 'pointer' }}>
                      {n}
                    </button>
                  ))}
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginBottom: 20 }}>
                  <span>NONE</span><span>TOLERABLE</span><span>SEVERE</span>
                </div>

                <div className="ml-label" style={{ marginBottom: 10 }}>Additional notes for {doc.n} (optional)</div>
                <textarea className="ml-input" rows={3} placeholder="Sharp pain on my upper right tooth when I drink cold water. Started Tuesday..."
                  value={note} onChange={(e) => setNote(e.target.value)}
                  style={{ resize: 'none', fontFamily: 'var(--sans)' }}/>
              </div>
            )}

            {requestedFollowup && !requestedEmergency && (
              <div className="ml-card" style={{ padding: 18, marginBottom: 24, borderColor: 'var(--line)' }}>
                <div className="ml-label" style={{ marginBottom: 10 }}>Patient notes for {doc.n}</div>
                <textarea className="ml-input" rows={4} placeholder="Tell the dentist what changed since the last consult, any pain, swelling, medicine response, or questions you want answered."
                  value={note} onChange={(e) => setNote(e.target.value)}
                  style={{ resize: 'none', fontFamily: 'var(--sans)' }}/>
              </div>
            )}

            <div className="ml-card" style={{ padding: 18, marginBottom: 28, background: 'oklch(98% 0.02 165)' }}>
              <div className="ml-label" style={{ marginBottom: 8 }}>Consult mode on WhatsApp</div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 8 }}>
                {modeOptions.map((opt) => {
                  const Icon = I[opt.icon] || I.chat;
                  const active = mode === opt.k;
                  const upgrade = requestedFollowup && isFreeFollowup && opt.upgradeFee > 0;
                  return (
                    <button key={opt.k} onClick={() => setMode(opt.k)}
                      style={{
                        padding: 13,
                        borderRadius: 10,
                        border: '1.5px solid ' + (active ? 'var(--blue)' : 'var(--line)'),
                        background: active ? 'var(--blue-tint)' : '#fff',
                        color: 'var(--ink)',
                        cursor: 'pointer',
                        textAlign: 'left',
                        fontFamily: 'var(--sans)',
                      }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, fontWeight: 700, marginBottom: 5 }}>
                        <Icon size={15}/> {opt.short}
                      </div>
                      <div style={{ fontSize: 11.5, color: upgrade ? 'oklch(42% 0.12 80)' : 'var(--ink-3)' }}>
                        {requestedFollowup && isFreeFollowup
                          ? (upgrade ? `Upgrade +₹${opt.upgradeFee}` : 'Included')
                          : `₹${bookingModeFee(doc, opt.k)}`}
                      </div>
                      {(isFreeFollowup || !requestedFollowup) && (
                        <div style={{ fontSize: 10.5, color: 'var(--ink-4)', lineHeight: 1.35, marginTop: 6 }}>
                          {isFreeFollowup
                            ? (opt.included ? 'Allowed under the free follow-up rule.' : 'Upgrade difference applies for this follow-up.')
                            : bookingFreeFollowupRule(opt.k)}
                        </div>
                      )}
                    </button>
                  );
                })}
              </div>
              <div className="ml-muted" style={{ fontSize: 12.5, marginTop: 10 }}>
                The confirmation email will include the dentist's WhatsApp Business link.
                {requestedFollowup && isFreeFollowup && ` Original consult mode: ${bookingModeLabel(sourceFollowupMode)}. ${bookingFreeFollowupRule(sourceFollowupMode)}`}
                {paidFollowupAfterFreeUsed && ' This follow-up is charged like a regular consult because the free follow-up has already been used or has expired.'}
              </div>
            </div>

            {!emergencyCareSelected && (
              <>
                <div className="ml-label" style={{ marginBottom: 10 }}>Day</div>
                <div style={{ display: 'flex', gap: 8, marginBottom: 20 }}>
                  {BOOKING_DAYS.map((d, i) => {
                    const noSlotsLeft = !bookingDayHasSlots(i);
                    return (
                    <button key={d} disabled={noSlotsLeft} onClick={() => { if (!noSlotsLeft) { setDay(i); setSlot(firstAvailableSlotFor(i) || BOOKING_SLOTS.Morning[0]); } }}
                      style={{ padding: '12px 16px', borderRadius: 10, border: '1px solid ' + (day === i ? 'var(--ink)' : 'var(--line)'),
                        background: noSlotsLeft ? 'var(--paper-2)' : day === i ? 'var(--ink)' : '#fff',
                        color: noSlotsLeft ? 'var(--ink-4)' : day === i ? '#fff' : 'var(--ink)',
                        cursor: noSlotsLeft ? 'not-allowed' : 'pointer', fontSize: 13, fontWeight: 500, opacity: noSlotsLeft ? 0.62 : 1 }}>
                      {d}
                    </button>
                  );})}
                </div>

                {Object.entries(BOOKING_SLOTS).map(([period, times]) => {
                  return (
                    <div key={period} style={{ marginBottom: 22 }}>
                      <div className="ml-label" style={{ marginBottom: 10 }}>{period}</div>
                      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6,1fr)', gap: 8 }}>
                        {times.map((t) => {
                          const past = slotIsPastForDay(day, t);
                          const booked = slotBookedFor(day, t);
                          const unavailable = past || booked;
                          return (
                          <button key={t} disabled={unavailable} onClick={() => !unavailable && setSlot(t)}
                            style={{ padding: '12px 0', borderRadius: 8, border: '1px solid ' + (slot === t ? 'var(--blue)' : 'var(--line)'),
                              background: unavailable ? 'var(--paper-2)' : slot === t ? 'var(--blue)' : '#fff',
                              color: unavailable ? 'var(--ink-4)' : slot === t ? '#fff' : 'var(--ink)', fontFamily: 'var(--mono)', fontSize: 13, cursor: unavailable ? 'not-allowed' : 'pointer', opacity: unavailable ? 0.55 : 1 }}>
                            <span>{t}</span>
                            {booked && <span style={{ display: 'block', fontSize: 9, marginTop: 2, fontFamily: 'var(--sans)' }}>Booked</span>}
                          </button>
                        );})}
                      </div>
                    </div>
                  );
                })}
              </>
            )}
          </section>
        )}

        {step === 4 && (
          <section>
            <h1 style={{ fontSize: 40, marginBottom: 8 }}>
              {tone === 'warm' ? 'All set — review & confirm.' : 'Confirm appointment details.'}
            </h1>
            <p style={{ color: 'var(--ink-3)', marginBottom: 28 }}>
              {emergencyCareSelected
                ? 'After payment, your emergency consultation is booked immediately. The dentist WhatsApp link will be sent to your registered email.'
                : 'Your confirmation email will include the dentist WhatsApp link. You can reschedule free until 1 hour prior.'}
            </p>

            <div className="ml-card" style={{ padding: 24, marginBottom: 16 }}>
              <div style={{ display: 'flex', gap: 16 }}>
                <div className="ml-photo" data-caption="DR" style={{ width: 84, height: 84, borderRadius: 10 }}/>
                <div style={{ flex: 1 }}>
                  <div style={{ fontFamily: 'var(--display)', fontSize: 22, fontWeight: 500 }}>{doc.n}, {doc.creds}</div>
                  <div style={{ color: 'var(--ink-3)', fontSize: 13 }}>{doc.spec} · {doc.loc} · ⭐ {doctorStats(doc).rating}</div>
                  <div style={{ marginTop: 10, display: 'flex', gap: 18, fontSize: 13, color: 'var(--ink-2)' }}>
                    <span style={bookingInline}>
                      {emergencyCareSelected ? <I.shield size={13}/> : <I.calendar size={13}/>}
                      {emergencyCareSelected ? ' Emergency consult · immediate after payment' : ` ${bookingDayLabel} · ${bookingTimeLabel}`}
                    </span>
                    <span style={bookingInline}>
                      <I.chat size={13}/> {bookingModeLabel(mode)} · 15 min
                    </span>
                  </div>
                </div>
              </div>
              <hr className="ml-hr" style={{ margin: '20px 0' }}/>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 16, fontSize: 13 }}>
                <div>
                  <div className="ml-label" style={{ marginBottom: 6 }}>Reason</div>
                  <div>{reason}</div>
                </div>
                <div>
                  <div className="ml-label" style={{ marginBottom: 6 }}>Pain level</div>
                  <div>{severity} / 10</div>
                </div>
                <div>
                  <div className="ml-label" style={{ marginBottom: 6 }}>Experience</div>
                  <div>{doc.y} years · {doc.creds}</div>
                </div>
                <div>
                  <div className="ml-label" style={{ marginBottom: 6 }}>Pay now</div>
	                  <div style={{ fontFamily: 'var(--display)', fontSize: 22 }}>{displayedFee === 0 ? 'Free' : `₹${displayedFee}`}<span style={{ fontSize: 12, color: 'var(--ink-3)', marginLeft: 6 }}>· {bookingModeLabel(mode)}</span></div>
                </div>
              </div>
            </div>

            <label style={{ display: 'flex', gap: 10, fontSize: 13, color: 'var(--ink-2)', marginBottom: 10 }}>
              <input type="checkbox" defaultChecked/>
              I consent to a telehealth visit and acknowledge the privacy policy.
            </label>
          </section>
        )}

        {/* Nav */}
        <div style={{ display: 'flex', gap: 10, borderTop: '1px solid var(--line)', paddingTop: 20, marginTop: 20 }}>
          <button className="ml-btn ml-btn--ghost" onClick={goPrev} disabled={currentStepIndex === 0}>
            <I.chevronL size={13}/> Back
          </button>
          <div style={{ flex: 1 }}/>
          {!isFinalStep ? (
            <button className="ml-btn ml-btn--primary" onClick={goNext} disabled={selectedSlotUnavailable} style={{ opacity: selectedSlotUnavailable ? 0.6 : 1 }}>
              Continue <I.arrowR size={13}/>
            </button>
          ) : (
            <button onClick={async () => {
              if (selectedSlotUnavailable) {
                window.alert && window.alert('Please choose an available consultation slot.');
                return;
              }
              const elig = requestedFollowup && window.checkFollowupEligible
                ? await window.checkFollowupEligible(docId, requestedFollowupFor)
                : null;
              const followupFree = requestedFollowup && !!elig?.eligible;
              const finalUpgradeCharge = followupFree ? bookingModeUpgradeCharge(doc, sourceFollowupMode, mode) : 0;
              const finalFee = followupFree ? finalUpgradeCharge : bookingModeFee(doc, mode);
              const noPaymentNeeded = followupFree && finalFee === 0;
              const created = await (window.createConsult && window.createConsult({
                docId,
                reason,
                severity,
                mode,
                selectedDay: bookingDayLabel,
                slot: bookingSlot,
                time: bookingTimeLabel,
                fee: finalFee,
                originalMode: requestedFollowup ? sourceFollowupMode : undefined,
                followUpCoveredByFree: followupFree,
                followUpUpgradeAmount: finalUpgradeCharge,
                paymentStatus: noPaymentNeeded ? 'paid' : 'pending',
                paidAmount: noPaymentNeeded ? 0 : undefined,
                paidMethod: noPaymentNeeded ? 'free-followup' : undefined,
                paidAt: noPaymentNeeded ? new Date().toISOString() : undefined,
                careType: emergencyCareSelected ? 'Emergency 24/7' : activeGroup.label,
                note,
                followUp: requestedFollowup,
                followUpFor: requestedFollowup ? (requestedFollowupFor || elig?.lastPaidConsultId || null) : null,
                followUpFreeUntil: elig?.expiresAt || null,
                patientName: user?.name || 'New patient',
                patientInitials: user?.initials || 'PT',
              }));
              if (!created) return;
              // Free follow-up: if patient paid this same dentist within 7 days, skip pay step.
              if (noPaymentNeeded) {
                window.navigate && window.navigate('/confirmed?consult=' + encodeURIComponent(created.id));
              } else {
                // Send to mock pay page for the freshly-created consult
                const id = created?.id || '';
                window.navigate && window.navigate('/pay?consult=' + encodeURIComponent(id));
              }
            }} disabled={selectedSlotUnavailable} className="ml-btn ml-btn--primary" style={{ padding: '12px 22px', opacity: selectedSlotUnavailable ? 0.6 : 1 }}>
              <I.check size={13}/> {emergencyCareSelected ? 'Confirm emergency & pay' : (requestedFollowup ? (displayedFee === 0 ? 'Confirm follow-up' : 'Confirm & pay') : 'Confirm & pay')}
            </button>
          )}
        </div>
      </div>

      {/* Right: summary rail */}
      <aside style={{ background: 'var(--ink)', color: '#fff', padding: 32, display: 'flex', flexDirection: 'column', gap: 24 }}>
          <div className="ml-label" style={{ color: 'oklch(75% 0.02 240)' }}>YOUR DENTAL VISIT</div>

        <div>
          <div style={{ fontSize: 11, color: 'oklch(75% 0.02 240)' }}>With</div>
          <div style={{ fontFamily: 'var(--display)', fontSize: 22, fontWeight: 500 }}>{doc.n}</div>
          <div style={{ fontSize: 12, color: 'oklch(75% 0.02 240)' }}>{doc.creds} · {doc.y} yrs experience</div>
        </div>

        <div>
          <div style={{ fontSize: 11, color: 'oklch(75% 0.02 240)', marginBottom: 4 }}>{emergencyCareSelected ? 'Emergency' : 'When'}</div>
          <div style={{ fontFamily: 'var(--display)', fontSize: 28, fontWeight: 500, letterSpacing: -0.02 + 'em' }}>
            {emergencyCareSelected ? 'Immediate after payment' : `${bookingDayLabel} · ${bookingTimeLabel}`}
          </div>
          <div style={{ fontSize: 12, color: 'oklch(75% 0.02 240)' }}>
            {emergencyCareSelected ? 'Emergency consult after payment' : '15 minute dental consult'}
          </div>
        </div>

        <div style={{ background: 'oklch(30% 0.02 240)', padding: 16, borderRadius: 10, border: '1px solid oklch(35% 0.02 240)' }}>
          <div style={{ fontSize: 11, color: 'oklch(75% 0.02 240)', marginBottom: 6 }}>VISIT FEE</div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
            <span style={{ fontSize: 13 }}>{bookingModeLabel(mode)}</span><span>{displayedFee === 0 ? 'Free' : `₹${displayedFee}`}</span>
          </div>
          {!requestedFollowup && (
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
              <span style={{ fontSize: 13, color: 'oklch(75% 0.02 240)' }}>1 Follow-up included</span><span>Free</span>
            </div>
          )}
          {requestedFollowup && isFreeFollowup && followupUpgradeCharge > 0 && (
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
              <span style={{ fontSize: 13, color: 'oklch(75% 0.02 240)' }}>Mode upgrade difference</span><span>₹{followupUpgradeCharge}</span>
            </div>
          )}
          <hr style={{ border: 'none', height: 1, background: 'oklch(35% 0.02 240)', margin: '10px 0' }}/>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--display)', fontSize: 20 }}>
            <span>{displayedFee === 0 ? 'Due today' : 'Pay now'}</span><span>{displayedFee === 0 ? '₹0' : `₹${displayedFee}`}</span>
          </div>
        </div>

        <div style={{ marginTop: 'auto', fontSize: 12, color: 'oklch(75% 0.02 240)', lineHeight: 1.55 }}>
          <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}><I.shield size={14}/> Consultation happens on WhatsApp; Molara keeps booking, records and prescription history.</div>
          <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}><I.clock size={14}/> Free cancellation up to 1 hour before your visit.</div>
          <div style={{ display: 'flex', gap: 8 }}><I.doc size={14}/> Dental plan, Rx guidance, and clinic referrals delivered instantly.</div>
        </div>
      </aside>
    </div>
  );
}

const bookingInline = { display: 'inline-flex', alignItems: 'center', gap: 6 };

Object.assign(window, { BookingFlow, bookingModeKey, bookingModeLabel, bookingModeFee, bookingModeUpgradeCharge, bookingFreeFollowupRule });
