/* Fluffy Friends — full booking page (shareable at /book → /site/#book).
   Pick a groomer → pet & service → date & a real time-slot → pin location →
   details. Submitting creates a PENDING booking on the dashboard calendar and
   opens a pre-filled WhatsApp message. */
const { Button, Input, Select, Checkbox, Badge } = window.FluffyFriendsDesignSystem_a09c32;

// Pull lat/lng out of a full Google Maps URL (no network needed).
function _latLngFromMapsUrl(u) {
  const m = (u || '').match(/@(-?\d{1,3}\.\d+),(-?\d{1,3}\.\d+)/)
        || (u || '').match(/!3d(-?\d{1,3}\.\d+)!4d(-?\d{1,3}\.\d+)/)
        || (u || '').match(/[?&](?:q|query|ll|center|destination)=(-?\d{1,3}\.\d+),\s*(-?\d{1,3}\.\d+)/);
  return m ? { lat: +m[1], lng: +m[2] } : null;
}
function _looksLikeMapsUrl(t) {
  return /^https?:\/\//i.test((t || '').trim()) && /(google\.[a-z.]+\/maps|maps\.google\.|maps\.app\.goo\.gl|goo\.gl\/maps)/i.test(t);
}

let _mapsPromise = null;
function loadGoogleMaps(key) {
  if (window.google && window.google.maps && window.google.maps.places) return Promise.resolve(true);
  if (!key) return Promise.reject(new Error('no-key'));
  if (_mapsPromise) return _mapsPromise;
  _mapsPromise = new Promise((resolve, reject) => {
    window.__flfMapsReady = () => resolve(true);
    const s = document.createElement('script');
    s.src = `https://maps.googleapis.com/maps/api/js?key=${key}&libraries=places&callback=__flfMapsReady`;
    s.async = true; s.defer = true;
    s.onerror = () => reject(new Error('maps-load-failed'));
    document.head.appendChild(s);
  });
  return _mapsPromise;
}

function BookingPage({ initialPet, onNav }) {
  const D = window.BOOKING_DATA;
  const petIdRef = React.useRef(0);
  const newPet = (petKey) => {
    const k = petKey || 'dog';
    return { id: ++petIdRef.current, pet: k, catAge: 'adult', size: 'small', service: '', extras: {}, instruction: '' };
  };
  const [groomers, setGroomers]   = React.useState([]);
  const [groomer, setGroomer]     = React.useState('any');     // key or 'any'
  const [pets, setPets]           = React.useState(() => [newPet(initialPet || 'dog')]);
  const [date, setDate]           = React.useState('');
  const [slots, setSlots]         = React.useState([]);
  const [slotsLoading, setSL]     = React.useState(false);
  const [slot, setSlot]           = React.useState(null);      // {start,end,label}
  const [form, setForm]           = React.useState({ name: '', phone: '', notes: '', hear: '' });

  // Attribution: captured once from the tracked-link query string (src + UTM) and
  // the referrer. No customer personal data is ever read into these.
  const attribution = React.useMemo(() => {
    const q = new URLSearchParams(window.location.search);
    return {
      src: q.get('src') || '',
      utm_source: q.get('utm_source') || '',
      utm_medium: q.get('utm_medium') || '',
      utm_campaign: q.get('utm_campaign') || '',
      raw_referrer: document.referrer || '',
    };
  }, []);
  const [loc, setLoc]             = React.useState({ address: '', lat: null, lng: null, building: '', street: '', apartment: '' });
  const [mapsOk, setMapsOk]       = React.useState(null);      // null=loading, true/false
  const [submitting, setSubmit]   = React.useState(false);
  const [done, setDone]           = React.useState(false);

  const addrRef = React.useRef(null);
  const mapRef  = React.useRef(null);
  const mapObj  = React.useRef(null);
  const marker  = React.useRef(null);

  // Load groomers + Google Maps once.
  React.useEffect(() => {
    fetch('/api/public/groomers').then(r => r.json()).then(j => setGroomers(j.groomers || [])).catch(() => {});
    fetch('/api/public/config').then(r => r.json()).then(cfg => {
      loadGoogleMaps(cfg.maps_key).then(() => setMapsOk(true)).catch(() => setMapsOk(false));
    }).catch(() => setMapsOk(false));
  }, []);

  // ── Pet list helpers ──
  const addPet      = () => setPets(p => [...p, newPet('dog')]);
  const removePet   = (id) => setPets(p => (p.length > 1 ? p.filter(x => x.id !== id) : p));
  const updatePet   = (id, patch) => setPets(p => p.map(x => (x.id === id ? { ...x, ...patch } : x)));
  // changing the pet type resets the service/extras/age to valid defaults
  const changePet   = (id, key) => updatePet(id, { pet: key, service: '', extras: {}, catAge: 'adult', size: 'small' });
  const togglePetExtra = (id, exKey) =>
    setPets(p => p.map(x => (x.id === id ? { ...x, extras: { ...x.extras, [exKey]: !x.extras[exKey] } } : x)));

  const petLabelOf = (pt) =>
    pt.pet === 'cat' ? `Cat (${pt.catAge})`
      : pt.pet === 'dog' ? `Dog (${pt.size})`
      : D.PET_OPTS.find(p => p.key === pt.pet).label;
  // Dogs are priced by size (D.BASE.dog[size][service]); cats by age; others flat.
  const priceFor = (pt, svc) => (pt.pet === 'cat' ? (D.BASE.cat[pt.catAge] || {})[svc]
    : pt.pet === 'dog' ? ((D.BASE.dog[pt.size] || {})[svc])
    : (D.BASE[pt.pet] || {})[svc]) || 0;
  const petPrice = (pt) => {
    const base = priceFor(pt, pt.service);
    const ex = D.EXTRAS.filter(x => pt.extras[x.key]);
    return { base, ex, total: base + ex.reduce((s, x) => s + x.price, 0) };
  };

  // Total groom time to reserve — sum of each pet's typical duration (dogs are
  // size-based). This blocks the groomer's schedule, so multi-pet bookings hold
  // a real slot.
  const petDuration = (pt) => {
    if (D.SERVICE_DURATIONS && D.SERVICE_DURATIONS[pt.service]) return D.SERVICE_DURATIONS[pt.service];
    return pt.pet === 'dog'
      ? (D.DOG_SIZES.find(s => s.key === pt.size) || D.DOG_SIZES[0]).duration
      : (D.DURATIONS[pt.pet] || 60);
  };
  const duration = pets.reduce((s, pt) => s + petDuration(pt), 0);
  const durationLabel = duration >= 60
    ? `${Math.floor(duration / 60)}h${duration % 60 ? ` ${duration % 60}m` : ''}`
    : `${duration}m`;

  const selectedProf = (() => {
    if (groomer === 'any') return '';
    const g = groomers.find(x => x.key === groomer);
    return (g && g.professional) || '';
  })();

  // Fetch availability whenever groomer or date changes.
  React.useEffect(() => {
    if (!date) { setSlots([]); setSlot(null); return; }
    setSL(true); setSlot(null);
    const qs = new URLSearchParams({ day: date, professional: selectedProf, duration: String(duration) });
    fetch(`/api/public/slots?${qs}`).then(r => r.json())
      .then(j => setSlots(j.slots || []))
      .catch(() => setSlots([]))
      .finally(() => setSL(false));
  }, [date, groomer, groomers, duration]); // eslint-disable-line

  // Init the map + Places autocomplete once Maps is ready and the inputs exist.
  React.useEffect(() => {
    if (mapsOk !== true || !addrRef.current || mapObj.current) return;
    const g = window.google;
    const center = { lat: 25.2048, lng: 55.2708 }; // Dubai
    const map = new g.maps.Map(mapRef.current, { center, zoom: 11, mapTypeControl: false, streetViewControl: false });
    const mk = new g.maps.Marker({ map, position: center, draggable: true, visible: false });
    mapObj.current = map; marker.current = mk;
    const place = (ll) => { mk.setPosition(ll); mk.setVisible(true); setLoc(l => ({ ...l, lat: ll.lat(), lng: ll.lng() })); };
    mk.addListener('dragend', () => place(mk.getPosition()));
    map.addListener('click', (e) => place(e.latLng));   // tap the map to drop a pin
    const ac = new g.maps.places.Autocomplete(addrRef.current, {
      componentRestrictions: { country: 'ae' }, fields: ['geometry', 'formatted_address'],
    });
    ac.addListener('place_changed', () => {
      const place = ac.getPlace();
      if (!place.geometry) return;
      const ll = place.geometry.location;
      map.setCenter(ll); map.setZoom(15);
      mk.setPosition(ll); mk.setVisible(true);
      setLoc({ address: place.formatted_address || addrRef.current.value, lat: ll.lat(), lng: ll.lng() });
    });
  }, [mapsOk]);

  // Paste a Google Maps link → drop the pin. Full URLs parse locally; short
  // links (maps.app.goo.gl) are resolved by the public backend resolver.
  const resolveMapsLink = React.useCallback(async (url) => {
    let c = _latLngFromMapsUrl(url);
    if (!c) {
      try {
        const res = await fetch('/api/public/geo/resolve?url=' + encodeURIComponent(url));
        const j = await res.json();
        if (res.ok && j.lat != null) c = { lat: j.lat, lng: j.lng };
      } catch (e) { /* ignore */ }
    }
    if (!c) {
      if (addrRef.current) addrRef.current.value = '';
      setLoc(l => ({ ...l, address: '' }));
      alert("We couldn't read that Google Maps link. Please type your address or drop the pin on the map.");
      return;
    }
    setLoc(l => ({ ...l, lat: c.lat, lng: c.lng }));
    const g = window.google;
    if (g && mapObj.current && marker.current) {
      const ll = new g.maps.LatLng(c.lat, c.lng);
      mapObj.current.setCenter(ll); mapObj.current.setZoom(15);
      marker.current.setPosition(ll); marker.current.setVisible(true);
      new g.maps.Geocoder().geocode({ location: ll }, (r, s) => {
        if (s === 'OK' && r[0]) { if (addrRef.current) addrRef.current.value = r[0].formatted_address; setLoc(l => ({ ...l, address: r[0].formatted_address })); }
      });
    } else {
      const label = '📍 Pinned from Google Maps link';
      if (addrRef.current) addrRef.current.value = label;
      setLoc(l => ({ ...l, address: label }));
    }
  }, []);

  React.useEffect(() => {
    const el = addrRef.current;
    if (!el) return;
    const onPaste = (e) => {
      const t = (e.clipboardData || window.clipboardData).getData('text') || '';
      if (_looksLikeMapsUrl(t)) { e.preventDefault(); resolveMapsLink(t.trim()); }
    };
    const onBlur = () => { if (_looksLikeMapsUrl(el.value)) resolveMapsLink(el.value.trim()); };
    el.addEventListener('paste', onPaste);
    el.addEventListener('blur', onBlur);
    return () => { el.removeEventListener('paste', onPaste); el.removeEventListener('blur', onBlur); };
  }, [resolveMapsLink, mapsOk]);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const setAddr = (k, v) => setLoc(l => ({ ...l, [k]: v }));
  const addrDetail = [
    loc.building && `Villa/Bldg ${loc.building}`,
    loc.street && loc.street,
    loc.apartment && `Apt/Floor ${loc.apartment}`,
  ].filter(Boolean).join(', ');
  const total = pets.reduce((s, pt) => s + petPrice(pt).total, 0);
  const groomerName = groomer === 'any' ? 'Any available groomer'
    : (groomers.find(g => g.key === groomer) || {}).name || '';

  const allServicesPicked = pets.every(pt => pt.service);
  const canSubmit = date && slot && form.name.trim() && form.phone.trim() && allServicesPicked && !submitting;

  // One-line summary per pet, e.g. 'Cat (adult): Full groom + Teeth brushing — Mochi, sensitive skin'
  const petSummary = (pt) => {
    const ex = petPrice(pt).ex.map(x => x.label);
    return `${petLabelOf(pt)}: ${pt.service}${ex.length ? ` + ${ex.join(', ')}` : ''}${pt.instruction ? ` — ${pt.instruction}` : ''}`;
  };

  const buildMessage = () => {
    const lines = [
      `Hi Fluffy Friends! 🐾 I'd like to book a groom for ${pets.length} pet${pets.length > 1 ? 's' : ''}:`,
    ];
    pets.forEach((pt, i) => {
      const pr = petPrice(pt);
      lines.push(`• ${pets.length > 1 ? `Pet ${i + 1} — ` : ''}${petLabelOf(pt)}: ${pt.service} — AED ${pr.base}`);
      if (pr.ex.length) lines.push(`   add-ons: ${pr.ex.map(x => `${x.label} (AED ${x.price})`).join(', ')}`);
      if (pt.instruction) lines.push(`   instructions: ${pt.instruction}`);
    });
    lines.push(`• Estimated total: AED ${total}`);
    lines.push(`• Groomer: ${groomerName}`);
    if (date && slot) lines.push(`• When: ${date} at ${slot.label}`);
    if (form.name) lines.push(`• Name: ${form.name}`);
    if (form.phone) lines.push(`• Mobile: ${form.phone}`);
    if (loc.address) lines.push(`• Location: ${loc.address}`);
    if (addrDetail) lines.push(`• Address details: ${addrDetail}`);
    if (form.notes) lines.push(`• Notes: ${form.notes}`);
    return lines.join('\n');
  };

  const submit = async () => {
    if (!canSubmit) return;
    // Open WhatsApp immediately, while we're still inside the click gesture.
    // Opening it after `await fetch(...)` gets suppressed by the popup blocker
    // (the call is no longer considered user-initiated), so WhatsApp never opened.
    openWhatsApp(buildMessage());
    setSubmit(true);
    const fullAddress = [loc.address, addrDetail].filter(Boolean).join(' · ');
    const petTypes = [...new Set(pets.map(pt => D.PET_OPTS.find(p => p.key === pt.pet).label))].join(', ');
    const serviceType = pets.length === 1
      ? (pets[0].pet === 'cat' ? `${pets[0].service} (${pets[0].catAge})` : pets[0].service)
      : `${pets.length} pets`;
    const payload = {
      day: date, professional: selectedProf, customer_name: form.name,
      customer_phone: form.phone, booking_start: `${date} ${slot.start}`, booking_end: `${date} ${slot.end}`,
      service_type: serviceType,
      pet_type: petTypes, lat: loc.lat, lng: loc.lng, amount: total,
      address: fullAddress,
      notes: [pets.map(petSummary).join(' · '), form.notes].filter(Boolean).join(' · '),
      source: 'website',
      // Attribution (page handle + UTM from the tracked link; manual selection).
      ...attribution,
      hear_about: form.hear,
    };
    try {
      // Save the booking to the dashboard in the background. WhatsApp is already
      // open with the full details, so the request reaches us either way.
      const res = await fetch('/api/public/bookings', {
        method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload),
      });
      if (!res.ok) throw new Error('save-failed');
    } catch (e) {
      /* best-effort: details already sent via WhatsApp */
    } finally {
      setSubmit(false);
      setDone(true);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    }
  };

  if (done) {
    return (
      <main className="bk-wrap"><div className="container bk-done">
        <div className="success__ring"><Bunny src="flf-bunny-pink.png" style={{ width: 64 }} /></div>
        <h1>Booking request sent! 🐾</h1>
        <p>Thank you, {form.name.split(' ')[0]}. We've received your request for <b>{date} at {slot.label}</b> with <b>{groomerName}</b>, and opened WhatsApp so you can send it through. Our team will confirm shortly and bring the pink van to your door.</p>
        <div style={{ marginTop: 24, display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
          <Button variant="primary" size="lg" onClick={() => onNav('home')}>Back to home</Button>
          <Button variant="ghost" onClick={() => openWhatsApp(buildMessage())}>Re-open WhatsApp</Button>
        </div>
      </div></main>
    );
  }

  return (
    <main className="bk-wrap">
      <BookStyles />
      <div className="container">
        <header className="bk-head">
          <span className="eyebrow">Book your groom</span>
          <h1>Let's get your friend looking fabulous</h1>
          <p>Choose your groomer, a time that suits you, and where to bring the van. We'll confirm by WhatsApp.</p>
        </header>

        <div className="bk-grid">
          <div className="bk-main">
            {/* 1 — groomer */}
            <section className="bk-card">
              <h3><span className="bk-num">1</span> Choose your groomer</h3>
              <div className="bk-groomers">
                <button className={'bk-groomer' + (groomer === 'any' ? ' on' : '')} onClick={() => setGroomer('any')}>
                  <div className="bk-groomer__any"><Icon name="sparkles" size={22} /></div>
                  <b>Any groomer</b><span>First available</span>
                </button>
                {groomers.map(g => (
                  <button key={g.key} className={'bk-groomer' + (groomer === g.key ? ' on' : '')} onClick={() => setGroomer(g.key)}>
                    <img src={FLF.A + g.photo} alt={g.name} />
                    <b>{g.name}</b><span>{g.blurb}</span>
                  </button>
                ))}
              </div>
            </section>

            {/* 2 — pets & services (one block per pet) */}
            <section className="bk-card">
              <h3><span className="bk-num">2</span> Your pets & services</h3>
              {pets.map((pt, i) => {
                const showExtras = pt.pet === 'dog' || pt.pet === 'cat';
                return (
                  <div className="bk-petcard" key={pt.id}>
                    <div className="bk-petcard__head">
                      <span className="bk-petcard__title">Pet {i + 1}</span>
                      {pets.length > 1 && (
                        <button type="button" className="bk-petrm" onClick={() => removePet(pt.id)}>Remove</button>
                      )}
                    </div>
                    <label className="fl-lab">Which friend are we grooming?</label>
                    <div className="pet-pick">
                      {D.PET_OPTS.map(p => (
                        <button key={p.key} type="button" className={'pet-opt' + (pt.pet === p.key ? ' on' : '')} onClick={() => changePet(pt.id, p.key)}>
                          <Icon name={p.icon} size={24} stroke={pt.pet === p.key ? 'var(--ink-900)' : 'var(--ink-500)'} /> {p.label}
                        </button>
                      ))}
                    </div>
                    {pt.pet === 'cat' && (
                      <div style={{ marginTop: 12 }}>
                        <label className="fl-lab">How old is your cat?</label>
                        <Select value={pt.catAge} onChange={e => updatePet(pt.id, { catAge: e.target.value })}>
                          {D.CAT_AGES.map(a => <option key={a.key} value={a.key}>{a.label}</option>)}
                        </Select>
                      </div>
                    )}
                    {pt.pet === 'dog' && (
                      <div style={{ marginTop: 12 }}>
                        <label className="fl-lab">How big is your dog?</label>
                        <Select value={pt.size} onChange={e => updatePet(pt.id, { size: e.target.value })}>
                          {D.DOG_SIZES.map(s => <option key={s.key} value={s.key}>{s.label}</option>)}
                        </Select>
                      </div>
                    )}
                    <div style={{ marginTop: 12 }}>
                      <label className="fl-lab">Service</label>
                      <Select value={pt.service} onChange={e => updatePet(pt.id, { service: e.target.value })}>
                        <option value="">Select service type</option>
                        {D.SERVICE_OPTS[pt.pet].map(s => <option key={s} value={s}>{s} — AED {priceFor(pt, s)}</option>)}
                      </Select>
                    </div>
                    {showExtras && (
                      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 14 }}>
                        <label className="fl-lab" style={{ marginBottom: 0 }}>Add a little extra</label>
                        {D.EXTRAS.map(x => (
                          <Checkbox key={x.key} label={`${x.label} (+AED ${x.price})`} checked={!!pt.extras[x.key]} onChange={() => togglePetExtra(pt.id, x.key)} />
                        ))}
                      </div>
                    )}
                    <div style={{ marginTop: 14 }}>
                      <Input label="Pet instruction (optional)" placeholder="Name, grooming style, medical conditions, etc." value={pt.instruction} onChange={e => updatePet(pt.id, { instruction: e.target.value })} />
                    </div>
                  </div>
                );
              })}
              <button type="button" className="bk-addpet" onClick={addPet}>+ Add another pet</button>
            </section>

            {/* 3 — date & time */}
            <section className="bk-card">
              <h3><span className="bk-num">3</span> Pick a date & time</h3>
              <p className="bk-muted" style={{ marginTop: -6, marginBottom: 12 }}>
                We'll reserve about <b style={{ color: 'var(--ink-900)' }}>{durationLabel}</b> for {pets.length > 1 ? `your ${pets.length} pets` : 'your pet'}.
              </p>
              <Input label="Preferred date" type="date" value={date} onChange={e => setDate(e.target.value)} />
              {date && (
                <div style={{ marginTop: 14 }}>
                  <label className="fl-lab">Available times {groomer !== 'any' ? `for ${groomerName}` : ''}</label>
                  {slotsLoading ? <p className="bk-muted">Finding open slots…</p>
                    : slots.length === 0 ? <p className="bk-muted">No open slots that day — try another date or groomer.</p>
                    : <div className="bk-slots">
                        {slots.map(s => (
                          <button key={s.start} className={'bk-slot' + (slot && slot.start === s.start ? ' on' : '')} onClick={() => setSlot(s)}>{s.label}</button>
                        ))}
                      </div>}
                </div>
              )}
            </section>

            {/* 4 — location */}
            <section className="bk-card">
              <h3><span className="bk-num">4</span> Where should we come?</h3>
              <label className="fl-lab">Search your address, then drag the pin to fine-tune</label>
              <input ref={addrRef} className="bk-input" placeholder="Type your address, or paste a Google Maps link…"
                     defaultValue={loc.address} onChange={e => setLoc(l => ({ ...l, address: e.target.value }))} />
              <div ref={mapRef} className="bk-map" style={{ display: mapsOk === true ? 'block' : 'none' }} />
              {mapsOk === false && <p className="bk-muted" style={{ marginTop: 8 }}>Map unavailable — just type your address above and we'll find you.</p>}
              {loc.lat && <p className="bk-muted" style={{ marginTop: 8 }}>📍 Pin set ({loc.lat.toFixed(4)}, {loc.lng.toFixed(4)})</p>}
              <label className="fl-lab" style={{ marginTop: 16 }}>Address details</label>
              <div className="bk-row">
                <Input label="Villa / building no." placeholder="e.g. Villa 12" value={loc.building} onChange={e => setAddr('building', e.target.value)} />
                <Input label="Street / area" placeholder="e.g. Al Wasl Rd, Jumeirah 1" value={loc.street} onChange={e => setAddr('street', e.target.value)} />
              </div>
              <div style={{ marginTop: 14 }}>
                <Input label="Apartment / floor (optional)" placeholder="e.g. Apt 304, 3rd floor" value={loc.apartment} onChange={e => setAddr('apartment', e.target.value)} />
              </div>
            </section>

            {/* 5 — details */}
            <section className="bk-card">
              <h3><span className="bk-num">5</span> Your details</h3>
              <div className="bk-row">
                <Input label="Your name" placeholder="e.g. Mariam" value={form.name} onChange={e => set('name', e.target.value)} />
                <Input label="Mobile number" placeholder="+971 50 …" value={form.phone} onChange={e => set('phone', e.target.value)} />
              </div>
              <Input label="Anything we should know? (optional)" placeholder="Nervous, matted coat…" value={form.notes} onChange={e => set('notes', e.target.value)} />
              <label className="bk-label" style={{ display: 'block', marginTop: 12 }}>
                How did you hear about us? (optional)
                <select className="bk-input" style={{ marginTop: 6 }} value={form.hear} onChange={e => set('hear', e.target.value)}>
                  <option value="">Select…</option>
                  <option value="instagram">Instagram</option>
                  <option value="referral">Friend / word of mouth</option>
                  <option value="google">Google search</option>
                  <option value="walk-in">Saw the van</option>
                  <option value="website">Website</option>
                  <option value="other">Other</option>
                </select>
              </label>
            </section>
          </div>

          {/* summary rail */}
          <aside className="bk-summary">
            <div className="bk-summary__card">
              <h4>Your booking</h4>
              <div className="bk-sum-row"><span>Groomer</span><b>{groomerName}</b></div>
              {pets.map((pt, i) => {
                const pr = petPrice(pt);
                return (
                  <React.Fragment key={pt.id}>
                    <div className="bk-sum-row"><span>{petLabelOf(pt)} — {pt.service}</span><b>AED {pr.base}</b></div>
                    {pr.ex.map(x => <div className="bk-sum-row bk-sum-sub" key={x.key}><span>+ {x.label}</span><b>AED {x.price}</b></div>)}
                    {pt.instruction ? <div className="bk-sum-row bk-sum-sub"><span>📝 {pt.instruction}</span></div> : null}
                  </React.Fragment>
                );
              })}
              <div className="bk-sum-row"><span>When</span><b>{date && slot ? `${date}, ${slot.label}` : '—'}</b></div>
              <div className="bk-sum-row bk-sum-total"><span>Estimated total</span><b>AED {total}</b></div>
              <Button variant="primary" size="lg" onClick={submit} disabled={!canSubmit} style={{ width: '100%', marginTop: 14 }}>
                <WhatsAppGlyph size={18} /> {submitting ? 'Sending…' : 'Confirm booking'}
              </Button>
              {!canSubmit && <p className="bk-muted" style={{ marginTop: 8, textAlign: 'center' }}>{allServicesPicked ? 'Pick a date, time, and add your name & mobile.' : 'Choose a service for each pet.'}</p>}
              <p className="bk-muted" style={{ marginTop: 10, textAlign: 'center', fontSize: 12 }}>We'll confirm your slot on WhatsApp.</p>
            </div>
          </aside>
        </div>
      </div>
    </main>
  );
}

function BookStyles() {
  return <style>{`
    .bk-wrap { background: var(--cream); min-height: 100vh; padding: 90px 0 80px; }
    .bk-head { text-align: center; max-width: 640px; margin: 0 auto 34px; }
    .bk-head h1 { font-family: var(--font-display); font-size: clamp(28px, 4vw, 42px); margin: 8px 0 10px; color: var(--ink-900); }
    .bk-head p { color: var(--text-muted); font-size: 16px; }
    .bk-grid { display: grid; grid-template-columns: 1fr 340px; gap: 24px; align-items: start; }
    .bk-main { display: flex; flex-direction: column; gap: 18px; }
    .bk-card { background: #fff; border: 1px solid var(--ink-200); border-radius: 22px; padding: 22px 24px; box-shadow: var(--shadow-card); }
    .bk-card h3 { font-family: var(--font-display); font-size: 19px; color: var(--ink-900); display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }
    .bk-num { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--pink-300); color: var(--ink-900); font-size: 14px; font-weight: 800; }
    .bk-groomers { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; }
    .bk-groomer { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; padding: 14px 10px; border: 2px solid var(--ink-200); border-radius: 18px; background: #fff; cursor: pointer; transition: all .15s; }
    .bk-groomer:hover { border-color: var(--pink-300); transform: translateY(-2px); }
    .bk-groomer.on { border-color: var(--ink-900); background: var(--pink-50); }
    .bk-groomer img, .bk-groomer__any { width: 60px; height: 60px; border-radius: 50%; object-fit: cover; margin-bottom: 4px; }
    .bk-groomer__any { display: flex; align-items: center; justify-content: center; background: var(--pink-100); color: var(--ink-700); }
    .bk-groomer b { font-size: 14px; color: var(--ink-900); }
    .bk-groomer span { font-size: 11px; color: var(--text-muted); line-height: 1.3; }
    .bk-slots { display: flex; flex-wrap: wrap; gap: 8px; }
    .bk-slot { padding: 9px 15px; border: 2px solid var(--ink-200); border-radius: 999px; background: #fff; font-weight: 700; font-size: 14px; color: var(--ink-800); cursor: pointer; transition: all .15s; }
    .bk-slot:hover { border-color: var(--pink-300); }
    .bk-slot.on { background: var(--ink-900); color: #fff; border-color: var(--ink-900); }
    .bk-input { width: 100%; padding: 12px 14px; border: 1.5px solid var(--ink-200); border-radius: 14px; font: inherit; font-size: 15px; }
    .bk-input:focus { outline: none; border-color: var(--pink-300); }
    .bk-map { width: 100%; height: 240px; border-radius: 16px; margin-top: 12px; border: 1px solid var(--ink-200); }
    .bk-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
    .bk-muted { color: var(--text-muted); font-size: 13px; }
    .bk-petcard { border: 1.5px solid var(--ink-200); border-radius: 16px; padding: 16px 16px 18px; margin-bottom: 14px; background: var(--pink-50); }
    .bk-petcard__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
    .bk-petcard__title { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: var(--ink-900); }
    .bk-petrm { background: none; border: none; color: var(--pink-600); font-weight: 700; font-size: 12px; cursor: pointer; padding: 2px 4px; }
    .bk-petrm:hover { text-decoration: underline; }
    .bk-addpet { width: 100%; padding: 12px; border: 2px dashed var(--ink-200); border-radius: 14px; background: #fff; color: var(--ink-700); font-family: var(--font-body); font-weight: 700; font-size: 14px; cursor: pointer; transition: all .15s; }
    .bk-addpet:hover { border-color: var(--pink-300); color: var(--ink-900); transform: translateY(-1px); }
    .bk-sum-sub span { color: var(--text-muted); font-size: 12.5px; padding-left: 6px; }
    .bk-summary { position: sticky; top: 90px; }
    .bk-summary__card { background: #fff; border: 1px solid var(--ink-200); border-radius: 22px; padding: 22px; box-shadow: var(--shadow-card); }
    .bk-summary__card h4 { font-family: var(--font-display); font-size: 18px; margin: 0 0 14px; color: var(--ink-900); }
    .bk-sum-row { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; font-size: 14px; color: var(--text-muted); border-bottom: 1px dashed var(--ink-200); }
    .bk-sum-row b { color: var(--ink-900); text-align: right; }
    .bk-sum-total { border-bottom: none; margin-top: 4px; font-size: 16px; }
    .bk-sum-total b { color: var(--brand); }
    .bk-done { text-align: center; max-width: 560px; margin: 40px auto; }
    .bk-done h1 { font-family: var(--font-display); font-size: 34px; color: var(--ink-900); margin: 14px 0; }
    .bk-done p { color: var(--text-muted); font-size: 16px; }
    @media (max-width: 880px) { .bk-grid { grid-template-columns: 1fr; } .bk-summary { position: static; } .bk-row { grid-template-columns: 1fr; } }
  `}</style>;
}

Object.assign(window, { BookingPage });
