/* global React, Icon */
// Saloon — Booking MVP (single pro, deployable).
// ── HOW TO DEPLOY ─────────────────────────────────────────────
// 1. Edit the CONFIG object below (name, services, contact).
// 2. Wire sendBooking() to your backend (see the marked TODO):
//    - Email   : Resend / SendGrid  (POST to your serverless function)
//    - SMS     : Twilio
//    - WhatsApp: Twilio WhatsApp API / Meta Cloud API
// 3. Host the HTML anywhere static (Vercel, Netlify, your server).
//    The serverless function lives on your side; this page just POSTs to it.
// ──────────────────────────────────────────────────────────────

const { useState: useStateMV, useMemo: useMemoMV, useEffect: useEffectMV } = React;

// Resolve a resource: use the bundler-inlined blob if present, else the live URL.
const R = (id, url) => (typeof window !== 'undefined' && window.__resources && window.__resources[id]) || url;

const CONFIG = {
  proName: 'Davido Fashionne',
  businessName: 'Davido Fashionne',
  tagline: 'Salon de coiffure · Paris 18e',
  bio: 'Coupe, couleur et soins au cœur du 18e arrondissement. Réservation en ligne, confirmation rapide par WhatsApp.',
  rating: 4.9,
  reviewCount: 0,
  cover: R('cover', '/img/cover.jpg'),
  portrait: R('portrait', '/img/portrait.jpg'),
  address: '26 Rue Eugène Sue, 75018 Paris',
  phone: '+33 7 53 88 33 91',
  instagram: '@davidofashionne',
  hoursToday: 'Sur rendez-vous',
  accent: '#B8924B',

  // Backend de réservation (notre serveur Express). Vide = mode autonome :
  // le lien WhatsApp est alors construit côté navigateur, sans persistance.
  bookingEndpoint: '/api/bookings',
  // Numéro WhatsApp du salon (format international, sans le +).
  whatsapp: '33753883391',
  notifyChannels: ['whatsapp'],

  // ⚠️ PLACEHOLDER — prix/durées à confirmer avec le salon. Images = /img/*.svg
  // (placeholders de marque, à remplacer par des photos générées/réelles).
  services: [
    { id: 's1', name: 'Démarrage de locks',        desc: 'Création de vos locks (méthode au choix)', price: 80,  duration: 120, image: R('s1', '/img/s1.jpg'), popular: true, variants: [] },
    { id: 's2', name: 'Entretien de locks',         desc: 'Reprise des racines / retwist',            price: 45,  duration: 60,  image: R('s2', '/img/s2.jpg'), popular: true, variants: [] },
    { id: 's3', name: 'Rajout / extensions de locks', desc: 'Ajout de longueur ou de densité',        price: 150, duration: 180, image: R('s3', '/img/s3.jpg'), variants: [] },
    { id: 's4', name: 'Coupe homme',                desc: 'Coupe, contours et finitions',             price: 25,  duration: 30,  image: R('s4', '/img/s4.jpg'), variants: [] },
    { id: 's5', name: 'Coupe + barbe',              desc: 'Coupe homme + taille de barbe',            price: 35,  duration: 45,  image: R('s5', '/img/s5.jpg'), variants: [] },
    { id: 's6', name: 'Taille de barbe',            desc: 'Mise en forme et contours',                price: 15,  duration: 20,  image: R('s6', '/img/s6.jpg'), variants: [] },
    { id: 's7', name: 'Coloration',                 desc: 'Couleur sur cheveux ou locks',             price: 60,  duration: 90,  image: R('s7', '/img/s7.jpg'), variants: [] },
  ],

  // Jours proposés = 6 prochains jours, calculés automatiquement.
  days: (() => {
    const wd = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
    const pad = (n) => String(n).padStart(2, '0');
    const out = []; const now = new Date();
    for (let i = 0; i < 6; i++) {
      const d = new Date(now); d.setDate(now.getDate() + i);
      const date = d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
      out.push({ label: wd[d.getDay()] + ' ' + d.getDate(), date });
    }
    return out;
  })(),
  slots: ['09:30', '10:15', '11:00', '11:45', '14:00', '14:45', '15:30', '16:15', '17:00', '17:45'],
};

// ── BACKEND HOOK ──────────────────────────────────────────────
// Construit le lien WhatsApp pré-rempli (notification gratuite + instantanée).
function buildWaUrl(p) {
  const lines = [
    `Bonjour ${CONFIG.businessName}, je souhaite réserver :`,
    `• ${p.service}${p.variant ? ' — ' + p.variant : ''} (${p.duration} min — ${p.price} €)`,
    `• ${p.day} à ${p.slot}`,
    `• Nom : ${p.name}`,
    `• Tél : ${p.phone}`,
  ];
  if (p.email) lines.push(`• Email : ${p.email}`);
  if (p.note) lines.push(`• Note : ${p.note}`);
  lines.push('', '(Demande envoyée via la page de réservation en ligne)');
  return 'https://wa.me/' + CONFIG.whatsapp + '?text=' + encodeURIComponent(lines.join('\n'));
}

async function sendBooking(payload) {
  // payload = { service, variant, price, duration, day, slot, name, phone, email, note }
  let whatsappUrl = null;
  if (CONFIG.bookingEndpoint) {
    // Enregistre la réservation côté serveur, qui renvoie le lien WhatsApp.
    try {
      const res = await fetch(CONFIG.bookingEndpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) return { ok: false, error: data.error || 'Réservation impossible.' };
      whatsappUrl = data.whatsappUrl || null;
    } catch (e) {
      // Backend indisponible → repli sur le lien construit côté navigateur.
    }
  }
  if (!whatsappUrl) whatsappUrl = buildWaUrl(payload);
  return { ok: true, whatsappUrl };
}

// ──────────────────────────────────────────────────────────────
function BookingMVP() {
  const c = CONFIG;
  const [open, setOpen] = useStateMV(false);
  const [presetService, setPresetService] = useStateMV(null);

  return (
    <div style={{ '--accent': c.accent }}>
      <Nav c={c} onBook={() => { setPresetService(null); setOpen(true); }} />
      <Hero c={c} onBook={() => { setPresetService(null); setOpen(true); }} />
      <ServicesSection c={c} onBook={(s) => { setPresetService(s); setOpen(true); }} />
      <AboutStrip c={c} />
      <Footer c={c} onBook={() => { setPresetService(null); setOpen(true); }} />
      {open && <BookingFlow c={c} preset={presetService} onClose={() => setOpen(false)} />}
    </div>
  );
}

function Nav({ c, onBook }) {
  const [scrolled, setScrolled] = useStateMV(false);
  useEffectMV(() => {
    const f = () => setScrolled(window.scrollY > 60);
    window.addEventListener('scroll', f); return () => window.removeEventListener('scroll', f);
  }, []);
  return (
    <nav style={{ position: 'sticky', top: 0, zIndex: 100, height: 62, display: 'flex', alignItems: 'center', padding: '0 clamp(20px,5vw,56px)',
      background: scrolled ? 'rgba(255,255,255,0.9)' : 'transparent', backdropFilter: scrolled ? 'blur(14px)' : 'none',
      borderBottom: scrolled ? '1px solid var(--line)' : '1px solid transparent', transition: 'background .25s, border-color .25s' }}>
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 10 }}>
        <svg width="32" height="32" viewBox="0 0 100 100" style={{ flexShrink: 0 }} aria-hidden="true">
          <rect width="100" height="100" rx="24" fill="var(--ink)" />
          <rect x="6" y="6" width="88" height="88" rx="19" fill="none" stroke="var(--accent)" strokeWidth="1.4" opacity="0.5" />
          <text x="50" y="67" textAnchor="middle" fontFamily="var(--display)" fontStyle="italic" fontWeight="500" fontSize="44" fill="var(--accent)">DF</text>
        </svg>
        <span style={{ fontFamily: 'var(--display)', fontStyle: 'italic', fontSize: 19, fontWeight: 500, letterSpacing: '-0.01em', color: scrolled ? 'var(--ink)' : 'inherit' }}>{c.businessName}</span>
      </div>
      <button onClick={onBook} style={{ height: 38, padding: '0 18px', borderRadius: 999, background: 'var(--ink)', color: '#fff', border: 0, cursor: 'pointer', fontSize: 13.5, fontWeight: 600 }}>Réserver</button>
    </nav>
  );
}

function Hero({ c, onBook }) {
  return (
    <header style={{ position: 'relative', marginTop: -62 }}>
      <div style={{ position: 'relative', height: 'min(80vh, 680px)', overflow: 'hidden' }}>
        <img src={c.cover} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.62) 100%)' }} />
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: 'clamp(28px,6vw,64px)', color: '#fff' }}>
          <div style={{ display: 'flex', gap: 8, marginBottom: 18 }}>
            <span style={badgeLight()}><Icon name="star" size={10} color="var(--ink)" /> <span className="num">{c.rating}</span> · {c.reviewCount} avis</span>
            <span style={badgeLight()}><span style={{ width: 7, height: 7, borderRadius: 999, background: '#5DD9A0' }} /> {c.hoursToday}</span>
          </div>
          <h1 style={{ fontFamily: 'var(--display)', fontStyle: 'italic', fontWeight: 500, fontSize: 'clamp(44px,8vw,92px)', lineHeight: 0.96, letterSpacing: '-0.02em', marginBottom: 16 }}>{c.businessName}</h1>
          <div style={{ fontSize: 'clamp(15px,2vw,19px)', opacity: 0.92, maxWidth: '46ch', lineHeight: 1.5, marginBottom: 26 }}>{c.tagline}</div>
          <div>
            <button onClick={onBook} style={{ height: 50, padding: '0 28px', borderRadius: 999, background: '#fff', color: 'var(--ink)', border: 0, cursor: 'pointer', fontSize: 15, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
              Réserver un rendez-vous <Icon name="arrow_right" size={15} color="var(--ink)" stroke={2.2} />
            </button>
          </div>
        </div>
      </div>
    </header>
  );
}

function ServicesSection({ c, onBook }) {
  return (
    <section id="services" style={{ maxWidth: 1080, margin: '0 auto', padding: 'clamp(48px,7vw,90px) clamp(20px,5vw,56px)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 14 }}>
        <span style={{ width: 24, height: 1, background: 'var(--accent)' }} />
        <span style={{ fontSize: 11.5, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent)', fontWeight: 600 }}>Prestations</span>
      </div>
      <h2 style={{ fontSize: 'clamp(28px,4vw,46px)', fontWeight: 600, letterSpacing: '-0.02em', marginBottom: 36 }}>
        Choisissez votre <span style={{ fontFamily: 'var(--display)', fontStyle: 'italic', fontWeight: 500, color: 'var(--accent)' }}>service</span>
      </h2>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(330px, 1fr))', gap: 14 }}>
        {c.services.map(s => (
          <button key={s.id} onClick={() => onBook(s)} style={{ display: 'flex', gap: 16, padding: 14, textAlign: 'left', background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 14, cursor: 'pointer', transition: 'border-color .15s, transform .12s, box-shadow .15s' }}
            onMouseEnter={e => { e.currentTarget.style.borderColor = 'var(--accent)'; e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = 'var(--shadow-2)'; }}
            onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--line)'; e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = 'none'; }}>
            <div style={{ position: 'relative', width: 88, height: 88, borderRadius: 10, overflow: 'hidden', flexShrink: 0, background: 'var(--bg-2)' }}>
              <img src={s.image} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />
              {s.popular && <span style={{ position: 'absolute', top: 5, left: 5, padding: '2px 6px', borderRadius: 999, background: 'rgba(255,255,255,0.95)', fontSize: 9, fontWeight: 700, color: 'var(--accent)' }}>★</span>}
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, marginBottom: 3 }}>
                <span style={{ fontSize: 15, fontWeight: 600 }}>{s.name}</span>
                <span className="num" style={{ fontSize: 15, fontWeight: 700, whiteSpace: 'nowrap' }}>{s.variants.length ? 'dès ' : ''}{s.variants.length ? Math.min(...s.variants.map(v => v.price)) : s.price}&nbsp;€</span>
              </div>
              <div style={{ fontSize: 12.5, color: 'var(--muted)', lineHeight: 1.4, marginBottom: 8 }}>{s.desc}</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 11.5, color: 'var(--muted)' }}>
                <span className="num">{s.duration} min</span>
                {s.variants.length > 0 && <><span>·</span><span>{s.variants.length} options</span></>}
                <span style={{ marginLeft: 'auto', color: 'var(--accent)', fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 3 }}>Réserver <Icon name="arrow_right" size={11} color="var(--accent)" stroke={2.2} /></span>
              </div>
            </div>
          </button>
        ))}
      </div>
    </section>
  );
}

function AboutStrip({ c }) {
  return (
    <section style={{ background: 'var(--surface)', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
      <div style={{ maxWidth: 1080, margin: '0 auto', padding: 'clamp(40px,6vw,72px) clamp(20px,5vw,56px)', display: 'grid', gridTemplateColumns: '240px 1fr', gap: 'clamp(28px,5vw,56px)', alignItems: 'center' }}>
        <img src={c.portrait} alt="" style={{ width: '100%', aspectRatio: '4/5', objectFit: 'cover', borderRadius: 16 }} />
        <div>
          <div style={{ fontSize: 12, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--accent)', fontWeight: 600, marginBottom: 12 }}>Le salon</div>
          <h2 style={{ fontSize: 'clamp(26px,3.4vw,40px)', fontWeight: 600, letterSpacing: '-0.02em', marginBottom: 16 }}>{c.proName}</h2>
          <p style={{ fontSize: 16, color: 'var(--muted)', lineHeight: 1.7, marginBottom: 22 }}>{c.bio}</p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13.5 }}>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, color: 'var(--muted)' }}><Icon name="pin" size={13} color="var(--accent)" /> {c.address}</span>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, color: 'var(--muted)' }}><Icon name="phone" size={13} color="var(--accent)" /> {c.phone}</span>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, color: 'var(--muted)' }}><Icon name="globe" size={13} color="var(--accent)" /> {c.instagram}</span>
          </div>
        </div>
      </div>
    </section>
  );
}

function Footer({ c, onBook }) {
  return (
    <section style={{ background: 'var(--ink)', color: '#fff', textAlign: 'center', padding: 'clamp(56px,8vw,110px) clamp(20px,5vw,56px)' }}>
      <h2 style={{ fontSize: 'clamp(30px,5vw,60px)', fontWeight: 600, lineHeight: 1.0, letterSpacing: '-0.02em', marginBottom: 20 }}>
        Réservez en <span style={{ fontFamily: 'var(--display)', fontStyle: 'italic', fontWeight: 500, color: 'var(--accent)' }}>une minute</span>
      </h2>
      <p style={{ fontSize: 15.5, opacity: 0.76, maxWidth: '42ch', margin: '0 auto 30px', lineHeight: 1.6 }}>Pas de compte à créer. Indiquez vos coordonnées, on vous confirme le rendez-vous rapidement.</p>
      <button onClick={onBook} style={{ height: 52, padding: '0 30px', borderRadius: 999, background: '#fff', color: 'var(--ink)', border: 0, cursor: 'pointer', fontSize: 15, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
        Réserver un rendez-vous <Icon name="arrow_right" size={15} color="var(--ink)" stroke={2.2} />
      </button>
      <div style={{ marginTop: 40, fontSize: 12.5, opacity: 0.55, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
        Propulsé par <strong style={{ fontFamily: 'var(--display)', fontStyle: 'italic', opacity: 1 }}>saloon</strong>
      </div>
    </section>
  );
}

// ─── Booking flow ─────────────────────────────────────────────
function BookingFlow({ c, preset, onClose }) {
  const [step, setStep] = useStateMV(preset ? 'detail' : 'service');
  const [service, setService] = useStateMV(preset || null);
  const [variantId, setVariantId] = useStateMV(preset?.variants?.[0]?.id || null);
  const [day, setDay] = useStateMV(0);
  const [slot, setSlot] = useStateMV(null);
  const [slots, setSlots] = useStateMV(c.slots);
  const [loadingSlots, setLoadingSlots] = useStateMV(false);
  const [form, setForm] = useStateMV({ name: '', phone: '', note: '' });
  const [sending, setSending] = useStateMV(false);
  const [err, setErr] = useStateMV('');
  const [result, setResult] = useStateMV(null);

  const variant = service?.variants?.find(v => v.id === variantId);
  const price = variant?.price ?? service?.price ?? 0;
  const duration = service?.duration ?? 0;
  const canSubmit = form.name.trim() && form.phone.trim() && slot;

  // Créneaux réels : on retire ceux déjà réservés (confirmation automatique).
  useEffectMV(() => {
    if (!service) return;
    const dd = c.days[day];
    let alive = true;
    setLoadingSlots(true);
    setSlot(null);
    fetch(`/api/availability?date=${dd.date}&duration=${duration}`)
      .then(r => r.json())
      .then(d => { if (alive) setSlots(Array.isArray(d.slots) ? d.slots : c.slots); })
      .catch(() => { if (alive) setSlots(c.slots); })
      .finally(() => { if (alive) setLoadingSlots(false); });
    return () => { alive = false; };
  }, [service, day]);

  const submit = async () => {
    setSending(true);
    setErr('');
    const r = await sendBooking({
      service: service.name, variant: variant?.name || null, price, duration,
      day: c.days[day].label, date: c.days[day].date, slot,
      name: form.name, phone: form.phone, note: form.note,
    });
    setSending(false);
    if (!r.ok) {
      setErr(r.error || 'Une erreur est survenue, réessayez.');
      setStep('detail'); // le créneau a peut-être été pris entre-temps
      return;
    }
    setResult(r);
    setStep('done');
  };

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 300, background: 'rgba(15,15,14,0.6)', backdropFilter: 'blur(10px)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <div style={{ width: 'min(440px,100%)', height: 'min(820px, calc(100vh - 48px))', background: 'var(--surface)', borderRadius: 24, overflow: 'hidden', display: 'flex', flexDirection: 'column', boxShadow: '0 24px 60px rgba(0,0,0,0.3)', animation: 'bmIn .25s ease-out' }}>

        {/* Header */}
        {step !== 'done' && (
          <div style={{ padding: '16px 18px', borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center', gap: 10, flexShrink: 0 }}>
            {step !== 'service' && !(preset && step === 'detail') && (
              <button onClick={() => setStep(step === 'info' ? 'detail' : 'service')} style={iconBtn()}><Icon name="chevron_left" size={14} /></button>
            )}
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--muted)', fontWeight: 600 }}>
                {step === 'service' ? 'Étape 1' : step === 'detail' ? 'Étape 2' : 'Étape 3'} · {preset ? 2 : 3} max
              </div>
              <div style={{ fontSize: 16, fontWeight: 600 }}>
                {step === 'service' ? 'Choisir un service' : step === 'detail' ? 'Créneau' : 'Vos coordonnées'}
              </div>
            </div>
            <button onClick={onClose} style={iconBtn()}><Icon name="close" size={13} /></button>
          </div>
        )}

        {/* Step: service */}
        {step === 'service' && (
          <div className="bm-scroll" style={{ flex: 1, overflowY: 'auto', padding: 14 }}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {c.services.map(s => (
                <button key={s.id} onClick={() => { setService(s); setVariantId(s.variants[0]?.id || null); setStep('detail'); }}
                  style={{ display: 'flex', gap: 12, padding: 10, textAlign: 'left', background: 'var(--bg)', border: '1px solid var(--line)', borderRadius: 12, cursor: 'pointer' }}>
                  <img src={s.image} alt="" style={{ width: 54, height: 54, borderRadius: 8, objectFit: 'cover', flexShrink: 0 }} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}>
                      <span style={{ fontSize: 13.5, fontWeight: 600 }}>{s.name}</span>
                      <span className="num" style={{ fontSize: 13.5, fontWeight: 700 }}>{s.variants.length ? 'dès ' : ''}{s.variants.length ? Math.min(...s.variants.map(v => v.price)) : s.price}&nbsp;€</span>
                    </div>
                    <div style={{ fontSize: 11.5, color: 'var(--muted)', marginTop: 2 }}>{s.desc}</div>
                    <div className="num" style={{ fontSize: 11, color: 'var(--muted)', marginTop: 4 }}>{s.duration} min</div>
                  </div>
                  <Icon name="chevron_right" size={14} color="var(--muted)" />
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Step: detail (variant + slot) */}
        {step === 'detail' && service && (
          <>
            <div className="bm-scroll" style={{ flex: 1, overflowY: 'auto' }}>
              <div style={{ position: 'relative', height: 140, flexShrink: 0, background: 'var(--bg-2)' }}>
                <img src={service.image} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />
                <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 40%, rgba(0,0,0,0.6) 100%)' }} />
                <div style={{ position: 'absolute', bottom: 12, left: 16, right: 16, color: '#fff' }}>
                  <div style={{ fontSize: 20, fontWeight: 600 }}>{service.name}</div>
                  <div className="num" style={{ fontSize: 12.5, opacity: 0.9 }}>{service.duration} min</div>
                </div>
              </div>

              {service.variants.length > 0 && (
                <Sect title="Option" required>
                  {service.variants.map(v => (
                    <button key={v.id} onClick={() => setVariantId(v.id)} style={{ width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 6px', borderBottom: '1px solid var(--line)', background: variantId === v.id ? 'var(--bg-2)' : 'transparent', border: 0, cursor: 'pointer', textAlign: 'left' }}>
                      <span style={{ fontSize: 13.5, fontWeight: 500 }}>{v.name}</span>
                      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
                        <span className="num" style={{ fontSize: 13.5, fontWeight: 700 }}>{v.price} €</span>
                        <span style={{ width: 20, height: 20, borderRadius: 999, border: '2px solid', borderColor: variantId === v.id ? 'var(--ink)' : 'var(--line-strong)', background: variantId === v.id ? 'var(--ink)' : 'transparent', position: 'relative' }}>
                          {variantId === v.id && <span style={{ position: 'absolute', inset: 4, borderRadius: 999, background: '#fff' }} />}
                        </span>
                      </span>
                    </button>
                  ))}
                </Sect>
              )}

              <Sect title="Jour" required>
                <div style={{ display: 'flex', gap: 8, overflowX: 'auto' }} className="bm-scroll">
                  {c.days.map((d, i) => (
                    <button key={d.date} onClick={() => setDay(i)} style={{ flex: '0 0 auto', textAlign: 'center', padding: '8px 12px', borderRadius: 10, border: '1px solid', borderColor: day === i ? 'var(--ink)' : 'var(--line)', background: day === i ? 'var(--ink)' : 'var(--surface)', color: day === i ? '#fff' : 'var(--ink)', cursor: 'pointer' }}>
                      <div style={{ fontSize: 11, opacity: 0.7 }}>{d.label.split(' ')[0]}</div>
                      <div className="num" style={{ fontSize: 14, fontWeight: 700 }}>{d.label.split(' ')[1]}</div>
                    </button>
                  ))}
                </div>
              </Sect>

              <Sect title="Heure" required>
                {loadingSlots ? (
                  <div style={{ fontSize: 12.5, color: 'var(--muted)' }}>Chargement des disponibilités…</div>
                ) : slots.length === 0 ? (
                  <div style={{ fontSize: 12.5, color: 'var(--muted)' }}>Complet ce jour-là — choisissez un autre jour.</div>
                ) : (
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
                    {slots.map(t => (
                      <button key={t} onClick={() => setSlot(t)} className="num" style={{ padding: '9px 0', borderRadius: 8, border: '1px solid', borderColor: slot === t ? 'var(--ink)' : 'var(--line)', background: slot === t ? 'var(--ink)' : 'var(--surface)', color: slot === t ? '#fff' : 'var(--ink)', fontSize: 12.5, fontWeight: 600, cursor: 'pointer' }}>{t}</button>
                    ))}
                  </div>
                )}
                {err && <div style={{ fontSize: 12, color: 'var(--warning)', marginTop: 10 }}>{err}</div>}
              </Sect>
            </div>
            <div style={{ padding: '14px 18px 18px', borderTop: '1px solid var(--line)' }}>
              <button disabled={!slot} onClick={() => setStep('info')} style={{ width: '100%', height: 50, borderRadius: 999, border: 0, background: slot ? 'var(--ink)' : 'var(--bg-2)', color: slot ? '#fff' : 'var(--muted)', cursor: slot ? 'pointer' : 'not-allowed', display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 22px', fontSize: 14, fontWeight: 600 }}>
                <span>{slot ? 'Continuer' : 'Choisissez une heure'}</span>
                <span className="num">{slot ? `${price} € · ${duration} min` : '↑'}</span>
              </button>
            </div>
          </>
        )}

        {/* Step: info */}
        {step === 'info' && (
          <>
            <div className="bm-scroll" style={{ flex: 1, overflowY: 'auto', padding: '18px' }}>
              <div style={{ padding: 14, background: 'var(--bg-2)', borderRadius: 12, marginBottom: 18, display: 'flex', gap: 12, alignItems: 'center' }}>
                <img src={service.image} alt="" style={{ width: 44, height: 44, borderRadius: 8, objectFit: 'cover' }} />
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13.5, fontWeight: 600 }}>{service.name}{variant ? ` — ${variant.name}` : ''}</div>
                  <div className="num" style={{ fontSize: 11.5, color: 'var(--muted)' }}>{c.days[day].label} · {slot} · {duration} min</div>
                </div>
                <span className="num" style={{ fontSize: 15, fontWeight: 700 }}>{price} €</span>
              </div>

              <Field label="Nom complet" required><input value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="Votre nom" style={inp()} /></Field>
              <Field label="Téléphone" required><input value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} placeholder="06 12 34 56 78" style={inp()} className="num" /></Field>
              <Field label="Note (optionnel)"><textarea value={form.note} onChange={e => setForm({ ...form, note: e.target.value })} placeholder="Une précision pour votre RDV ?" style={{ ...inp(), minHeight: 70, resize: 'vertical', paddingTop: 10 }} /></Field>

              <div style={{ fontSize: 11.5, color: 'var(--muted)', lineHeight: 1.5, display: 'flex', gap: 8, alignItems: 'flex-start', marginTop: 4 }}>
                <Icon name="info" size={11} color="var(--muted)" />
                <span>Réservation confirmée immédiatement. Le salon est prévenu par WhatsApp. Aucun paiement en ligne.</span>
              </div>
            </div>
            <div style={{ padding: '14px 18px 18px', borderTop: '1px solid var(--line)' }}>
              <button disabled={!canSubmit || sending} onClick={submit} style={{ width: '100%', height: 52, borderRadius: 999, border: 0, background: (canSubmit && !sending) ? 'var(--ink)' : 'var(--bg-2)', color: (canSubmit && !sending) ? '#fff' : 'var(--muted)', cursor: (canSubmit && !sending) ? 'pointer' : 'not-allowed', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, fontSize: 14, fontWeight: 600 }}>
                {sending ? 'Réservation…' : <>Réserver maintenant <Icon name="arrow_right" size={14} color="#fff" stroke={2.2} /></>}
              </button>
            </div>
          </>
        )}

        {/* Step: done */}
        {step === 'done' && (
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 30, textAlign: 'center' }}>
            <div style={{ width: 88, height: 88, borderRadius: 999, background: 'var(--success)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 0 0 8px var(--success-tint)', marginBottom: 20 }}>
              <Icon name="check" size={42} color="#fff" stroke={2.6} />
            </div>
            <div style={{ fontSize: 23, fontWeight: 600, marginBottom: 8 }}>Réservation confirmée</div>
            <div style={{ fontSize: 13.5, color: 'var(--muted)', lineHeight: 1.55, marginBottom: 8, maxWidth: '34ch' }}>
              {service.name}{variant ? ` — ${variant.name}` : ''} · {c.days[day].label} à {slot}.<br />
              C&apos;est réservé. Prévenez le salon sur WhatsApp si vous le souhaitez.
            </div>
            {result?.whatsappUrl && (
              <a href={result.whatsappUrl} target="_blank" rel="noopener" style={{ height: 50, padding: '0 26px', borderRadius: 999, background: '#25D366', color: '#fff', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, fontSize: 14.5, fontWeight: 700, marginBottom: 12 }}>
                Prévenir le salon sur WhatsApp <Icon name="arrow_right" size={14} color="#fff" stroke={2.2} />
              </a>
            )}
            <button onClick={onClose} style={{ height: 44, padding: '0 24px', borderRadius: 999, background: 'transparent', color: 'var(--muted)', border: 0, cursor: 'pointer', fontSize: 13.5, fontWeight: 600 }}>Fermer</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ─── tiny helpers ─────────────────────────────────────────────
function Sect({ title, required, children }) {
  return (
    <div style={{ padding: '14px 18px', borderTop: '1px solid var(--line)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
        <div style={{ flex: 1, fontSize: 15, fontWeight: 600 }}>{title}</div>
        {required && <span style={{ padding: '3px 9px', borderRadius: 999, fontSize: 10, fontWeight: 600, background: 'var(--ink)', color: '#fff' }}>Obligatoire</span>}
      </div>
      {children}
    </div>
  );
}
function Field({ label, required, children }) {
  return (
    <div style={{ marginBottom: 14 }}>
      <div style={{ fontSize: 11, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--muted)', fontWeight: 600, marginBottom: 6 }}>{label}{required && <span style={{ color: 'var(--accent)', marginLeft: 4 }}>*</span>}</div>
      {children}
    </div>
  );
}
function inp() { return { width: '100%', height: 44, padding: '0 14px', border: '1px solid var(--line-strong)', borderRadius: 10, fontSize: 14, fontFamily: 'inherit', outline: 'none', background: 'var(--surface)', color: 'var(--ink)' }; }
function iconBtn() { return { width: 34, height: 34, borderRadius: 999, background: 'var(--bg-2)', border: 0, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }; }
function badgeLight() { return { height: 28, padding: '0 11px', borderRadius: 999, display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11.5, fontWeight: 600, background: 'rgba(255,255,255,0.95)', color: '#131312' }; }

window.BookingMVP = BookingMVP;
