// client-booking.jsx — Customer-facing booking page.
// Loads real data from Supabase. Three-step flow: pick service, artist+date, confirm.
// Sticky summary rail on the right.

function ClientBookingPage() {
  const C = {
    bg: '#fafafa', bg2: '#f4f4f5', surface: '#ffffff',
    dark: '#09090b', ink: '#09090b', ink2: '#27272a',
    mute: '#52525b', mute2: '#71717a', mute3: '#a1a1aa',
    line: '#e4e4e7', line2: '#d4d4d8',
    accent: '#6366f1', accent2: '#a5b4fc', accentSoft: '#eef2ff',
    success: '#16a34a', successSoft: '#dcfce7',
    font: "'Geist', 'Inter', -apple-system, system-ui, sans-serif",
    display: "'Geist', 'Inter', -apple-system, system-ui, sans-serif",
  };
  const eyebrow = {
    fontSize: 11.5, fontWeight: 500,
    letterSpacing: '0.18em', textTransform: 'uppercase',
    color: C.mute,
  };

  // ── ALL HOOKS AT TOP LEVEL ────────────────────────────────────
  const [view, setView] = React.useState('loading');
  const [errorMsg, setErrorMsg] = React.useState('');
  const [workspace, setWorkspace] = React.useState(null);
  const [artistProfile, setArtistProfile] = React.useState(null);
  const [services, setServices] = React.useState([]);
  const [staffList, setStaffList] = React.useState([]);
  const [staffServices, setStaffServices] = React.useState({});

  const [service, setService] = React.useState(null);
  const [artist, setArtist] = React.useState(null);
  const [day, setDay] = React.useState(null);
  const [time, setTime] = React.useState(null);
  const [confirmed, setConfirmed] = React.useState(false);
  const [createdBooking, setCreatedBooking] = React.useState(null);

  const [timeSlots, setTimeSlots] = React.useState([]);
  const [slotsLoading, setSlotsLoading] = React.useState(false);

  const [clientName, setClientName] = React.useState('');
  const [clientPhone, setClientPhone] = React.useState('');
  const [clientEmail, setClientEmail] = React.useState('');

  const [activeCat, setActiveCat] = React.useState('All');

  // ── INIT: load workspace + services + staff from Supabase ────
  React.useEffect(() => {
    async function init() {
      try {
        const params = new URLSearchParams(window.location.search);
        const shopSlug = params.get('shop') || params.get('slug');
        const artistParam = params.get('artist');

        let ws = null;

        if (artistParam) {
          // Freelancer booking
          const { data: prof } = await db.from('profiles')
            .select('id, full_name, avatar_url, workspace_id')
            .eq('slug', artistParam).single();
          if (!prof) throw new Error('Artist not found');
          setArtistProfile(prof);
          const { data: w } = await db.from('workspaces')
            .select('*').eq('id', prof.workspace_id).single();
          ws = w;
        } else if (shopSlug) {
          const { data: w } = await db.from('workspaces')
            .select('*').eq('slug', shopSlug).single();
          if (!w) throw new Error('Studio not found');
          ws = w;
        } else {
          throw new Error('Missing shop or artist parameter');
        }

        setWorkspace(ws);
        document.title = `Book — ${ws.name}`;

        // Load services
        const { data: svcData } = await db.from('services')
          .select('*').eq('workspace_id', ws.id).eq('is_active', true)
          .order('display_order', { ascending: true });
        setServices(svcData || []);

        // Load staff
        const { data: staffData } = await db.from('profiles')
          .select('id, full_name, avatar_url, role, slug')
          .eq('workspace_id', ws.id)
          .in('role', ['artist', 'owner']);
        setStaffList(staffData || []);

        // Load staff-service restrictions
        const { data: ssData } = await db.from('staff_services')
          .select('staff_id, service_id')
          .eq('workspace_id', ws.id);
        if (ssData && ssData.length > 0) {
          const map = {};
          ssData.forEach(r => {
            if (!map[r.staff_id]) map[r.staff_id] = new Set();
            map[r.staff_id].add(r.service_id);
          });
          setStaffServices(map);
        }

        // Auto-select artist if freelancer booking
        if (artistParam) {
          const match = (staffData || []).find(s => s.slug === artistParam);
          if (match) setArtist(match);
        }

        // Load saved client info
        try {
          const saved = JSON.parse(localStorage.getItem('loxley_client_info') || '{}');
          if (saved.name) setClientName(saved.name);
          if (saved.phone) setClientPhone(saved.phone);
          if (saved.email) setClientEmail(saved.email);
        } catch(e) {}

        setView('flow');
      } catch (err) {
        console.error('Init error:', err);
        setErrorMsg(err.message || 'Failed to load booking page');
        setView('error');
      }
    }
    init();
  }, []);

  // ── FETCH TIME SLOTS when date or staff changes ──────────────
  React.useEffect(() => {
    if (!day || !service || !workspace) return;
    async function fetchSlots() {
      setSlotsLoading(true);
      setTime(null);
      try {
        const dateStr = [
          day.dateObj.getFullYear(),
          String(day.dateObj.getMonth() + 1).padStart(2, '0'),
          String(day.dateObj.getDate()).padStart(2, '0'),
        ].join('-');

        const staffId = (artist && artist.id !== 'any') ? artist.id : null;

        const { data, error } = await db.rpc('get_available_slots', {
          p_workspace_id: workspace.id,
          p_staff_id: staffId,
          p_date: dateStr,
          p_duration: service.duration || 60,
        });

        if (error) throw error;
        setTimeSlots((data || []).map(s => s.slot_time || s));
      } catch (err) {
        console.error('Slots error:', err);
        setTimeSlots([]);
      } finally {
        setSlotsLoading(false);
      }
    }
    fetchSlots();
  }, [day, artist, service, workspace]);

  // ── SUBMIT BOOKING ───────────────────────────────────────────
  async function handleConfirm() {
    if (!service || !day || !time) return;
    try {
      // Save client info
      localStorage.setItem('loxley_client_info', JSON.stringify({
        name: clientName, phone: clientPhone, email: clientEmail,
      }));

      const dateStr = [
        day.dateObj.getFullYear(),
        String(day.dateObj.getMonth() + 1).padStart(2, '0'),
        String(day.dateObj.getDate()).padStart(2, '0'),
      ].join('-');

      const { data, error } = await db.rpc('create_booking', {
        p_workspace_id: workspace.id,
        p_service_id: service.id,
        p_staff_id: (artist && artist.id !== 'any') ? artist.id : null,
        p_client_name: clientName || 'Guest',
        p_client_phone: clientPhone || '',
        p_client_email: clientEmail || '',
        p_date: dateStr,
        p_time: time,
        p_duration: service.duration || 60,
      });

      if (error) throw error;
      setCreatedBooking(data);
      setConfirmed(true);
    } catch (err) {
      console.error('Booking error:', err);
      alert(err.message || 'Booking failed. Please try again.');
    }
  }

  // ── RENDER ───────────────────────────────────────────────────
  if (view === 'loading') {
    return (
      <div style={{ minHeight: '100vh', background: C.bg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ textAlign: 'center', color: C.mute }}>
          <div style={{ width: 32, height: 32, border: `2px solid ${C.line}`, borderTopColor: C.accent, borderRadius: '50%', animation: 'spin 0.7s linear infinite', margin: '0 auto 16px' }} />
          <div style={{ fontSize: 14 }}>Loading booking page…</div>
        </div>
      </div>
    );
  }

  if (view === 'error') {
    return (
      <div style={{ minHeight: '100vh', background: C.bg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ textAlign: 'center', color: C.mute, maxWidth: 400 }}>
          <div style={{ fontSize: 48, marginBottom: 16 }}>😕</div>
          <h2 style={{ fontFamily: C.display, fontSize: 24, fontWeight: 600, color: C.ink, marginBottom: 8 }}>Something went wrong</h2>
          <p style={{ fontSize: 14, marginBottom: 24 }}>{errorMsg}</p>
          <a href="/" style={{ fontSize: 14, color: C.accent, fontWeight: 500 }}>← Back to homepage</a>
        </div>
      </div>
    );
  }

  // Studio data for display
  const studio = {
    initial: workspace.logo_letter || workspace.name.charAt(0),
    name: workspace.name,
    loc: workspace.location || workspace.city || '',
    address: workspace.address || '',
    rating: workspace.rating || 4.9,
    reviewCount: workspace.review_count || 0,
  };

  // Category filter
  const categories = ['All', ...new Set(services.map(s => s.category || 'General'))];
  const filteredServices = activeCat === 'All'
    ? services
    : services.filter(s => (s.category || 'General') === activeCat);

  // Staff filtering based on selected service
  const getFilteredStaff = () => {
    if (!service) return staffList;
    const hasRestrictions = Object.keys(staffServices).length > 0;
    if (hasRestrictions) {
      return staffList.filter(s => {
        if (staffServices[s.id]) return staffServices[s.id].has(service.id);
        return true;
      });
    }
    return staffList;
  };

  // Generate 14 days
  const days = React.useMemo(() => {
    const arr = [];
    const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    const now = new Date();
    for (let i = 1; i <= 14; i++) {
      const d = new Date(now.getTime() + i * 864e5);
      arr.push({
        id: i,
        dateObj: d,
        weekday: dayNames[d.getDay()],
        date: d.getDate(),
        month: monthNames[d.getMonth()],
      });
    }
    return arr;
  }, []);

  return (
    <div style={{
      width: '100%', minHeight: '100vh',
      background: C.bg, color: C.ink,
      fontFamily: C.font, fontSize: 14.5, lineHeight: 1.5,
      letterSpacing: '-0.005em',
    }}>
      <ClientNav C={C} studio={studio} />

      {!confirmed ? (
        <>
          <ClientHero C={C} studio={studio} eyebrow={eyebrow} />
          <div style={{
            maxWidth: 1240, margin: '0 auto',
            padding: '24px 40px 96px',
            display: 'grid', gridTemplateColumns: '1fr 380px',
            gap: 32, alignItems: 'flex-start',
          }}>
            <main style={{ minWidth: 0, display: 'flex', flexDirection: 'column', gap: 40 }}>
              <ServicesBlock C={C} eyebrow={eyebrow}
                services={filteredServices} categories={categories}
                activeCat={activeCat} setActiveCat={setActiveCat}
                selected={service} onSelect={setService}
                totalCount={services.length} />
              <ArtistsBlock C={C} eyebrow={eyebrow}
                staff={getFilteredStaff()} selected={artist} onSelect={setArtist}
                artistProfile={artistProfile} />
              <ScheduleBlock C={C} eyebrow={eyebrow}
                days={days} day={day} setDay={setDay}
                time={time} setTime={setTime}
                timeSlots={timeSlots} slotsLoading={slotsLoading}
                service={service} />
            </main>
            <aside style={{ position: 'sticky', top: 88 }}>
              <SummaryRail C={C} studio={studio}
                service={service} artist={artist} day={day} time={time}
                clientName={clientName} setClientName={setClientName}
                clientPhone={clientPhone} setClientPhone={setClientPhone}
                clientEmail={clientEmail} setClientEmail={setClientEmail}
                onConfirm={handleConfirm} />
            </aside>
          </div>
        </>
      ) : (
        <ClientSuccess C={C} studio={studio}
          service={service} artist={artist} day={day} time={time}
          createdBooking={createdBooking}
          onReset={() => {
            setConfirmed(false); setService(null); setArtist(null);
            setDay(null); setTime(null); setCreatedBooking(null);
          }} />
      )}

      <ClientFooter C={C} studio={studio} />
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
function ClientNav({ C, studio }) {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const fn = () => setScrolled(window.scrollY > 8);
    window.addEventListener('scroll', fn, { passive: true });
    return () => window.removeEventListener('scroll', fn);
  }, []);
  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 50,
      background: 'rgba(250,250,250,0.86)',
      backdropFilter: 'blur(18px) saturate(150%)',
      WebkitBackdropFilter: 'blur(18px) saturate(150%)',
      borderBottom: `1px solid ${scrolled ? C.line : 'transparent'}`,
      padding: '0 40px', height: 64,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      transition: 'border-color .3s',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <span style={{
          width: 32, height: 32, borderRadius: 10,
          background: C.ink, color: '#fff',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: C.display, fontSize: 14, fontWeight: 700,
        }}>{studio.initial}</span>
        <div>
          <div style={{ fontFamily: C.display, fontWeight: 600, fontSize: 15, letterSpacing: '-0.015em' }}>{studio.name}</div>
          <div style={{ fontSize: 12, color: C.mute2 }}>{studio.loc}</div>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
        <span style={{ width: 1, height: 18, background: C.line, margin: '0 8px' }} />
        <a href="/" style={{
          fontSize: 12, color: C.mute2, fontWeight: 500,
          display: 'inline-flex', alignItems: 'center', gap: 6,
        }}>
          Powered by <strong style={{ color: C.ink, fontWeight: 600 }}>Loxley</strong>
        </a>
      </div>
    </header>
  );
}

function ClientHero({ C, studio, eyebrow }) {
  return (
    <section style={{ maxWidth: 1240, margin: '0 auto', padding: '40px 40px 16px' }}>
      <Reveal>
        <div style={{ ...eyebrow, color: C.accent, marginBottom: 14 }}>Book an appointment</div>
        <h1 style={{
          fontFamily: C.display, fontWeight: 600, fontSize: 48,
          letterSpacing: '-0.04em', lineHeight: 1.05, margin: '0 0 14px',
          maxWidth: 720,
        }}>Your next appointment, sorted.</h1>
        <p style={{ fontSize: 16, color: C.mute, margin: 0, maxWidth: 620 }}>
          Pick a service, choose your artist, and book the time that fits your day. We'll text you within the hour.
        </p>
        <div style={{ display: 'flex', gap: 16, marginTop: 22, fontSize: 13.5, color: C.ink2, flexWrap: 'wrap' }}>
          {studio.rating > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="currentColor"><polygon points="8,1.5 10,6 14.5,6.5 11,9.5 12,14 8,11.5 4,14 5,9.5 1.5,6.5 6,6" /></svg>
              <strong style={{ fontWeight: 600 }}>{studio.rating}</strong>
              {studio.reviewCount > 0 && <span style={{ color: C.mute2 }}>({studio.reviewCount} reviews)</span>}
            </span>
          )}
          {studio.address && (
            <>
              <span style={{ color: C.mute3 }}>•</span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M8 14s-5-4.5-5-8a5 5 0 0 1 10 0c0 3.5-5 8-5 8z" /><circle cx="8" cy="6" r="2" /></svg>
                {studio.address}
              </span>
            </>
          )}
        </div>
      </Reveal>
    </section>
  );
}

// ────────────────────────────────────────────────────────────────
function ServicesBlock({ C, eyebrow, services, categories, activeCat, setActiveCat, selected, onSelect, totalCount }) {
  return (
    <section>
      <Reveal>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 18 }}>
          <div>
            <div style={{ ...eyebrow, marginBottom: 10 }}>Step one</div>
            <h2 style={{ fontFamily: C.display, fontWeight: 600, fontSize: 28, letterSpacing: '-0.03em', margin: 0, lineHeight: 1.1 }}>Pick a service.</h2>
          </div>
          <span style={{ fontSize: 13, color: C.mute }}>{totalCount} available</span>
        </div>
      </Reveal>

      <Reveal delay={60}>
        <div style={{ display: 'flex', gap: 6, marginBottom: 16, overflowX: 'auto', paddingBottom: 4 }}>
          {categories.map(c => (
            <button key={c} onClick={() => setActiveCat(c)} style={{
              flexShrink: 0,
              fontSize: 12.5, padding: '7px 14px', borderRadius: 999,
              background: activeCat === c ? C.ink : C.surface,
              color: activeCat === c ? '#fff' : C.ink2,
              border: activeCat === c ? `1px solid ${C.ink}` : `1px solid ${C.line}`,
              fontWeight: 500, cursor: 'pointer', transition: 'all .15s',
            }}>{c}</button>
          ))}
        </div>
      </Reveal>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {services.map((s, i) => (
          <Reveal key={s.id} delay={i * 50} y={10}>
            <ServiceCard C={C} s={s}
              selected={selected && selected.id === s.id}
              onClick={() => onSelect(s)} />
          </Reveal>
        ))}
      </div>
    </section>
  );
}

function ServiceCard({ C, s, selected, onClick }) {
  const [hover, setHover] = React.useState(false);
  const [open, setOpen] = React.useState(false);
  const price = typeof s.price === 'number' ? `£${s.price}` : (s.price || '—');
  const dur = s.duration ? `${s.duration} min` : '';
  const photoUrl = s.photo_url || s.photo || 'polishClose';

  return (
    <article style={{
      background: selected ? C.accentSoft : C.surface,
      border: `1.5px solid ${selected ? C.accent : C.line}`,
      borderRadius: 16, padding: 16,
      transition: 'background .2s, border-color .2s, transform .2s',
      transform: hover && !selected ? 'translateY(-1px)' : 'none',
    }}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}>
      <div onClick={onClick} style={{
        display: 'grid', gridTemplateColumns: '88px 1fr auto',
        gap: 16, alignItems: 'center', cursor: 'pointer',
      }}>
        <div style={{ overflow: 'hidden', borderRadius: 10 }}>
          <Photo src={photoUrl} style={{ height: 72 }} mute />
        </div>
        <div style={{ minWidth: 0 }}>
          <div style={{
            fontFamily: C.display, fontSize: 17, fontWeight: 600,
            letterSpacing: '-0.018em', marginBottom: 4,
            display: 'flex', alignItems: 'center', gap: 10,
          }}>
            {s.name}
            {s.is_popular && (
              <span style={{
                fontSize: 10, fontWeight: 600, letterSpacing: '0.04em',
                padding: '2px 7px', borderRadius: 999,
                background: C.accent, color: '#fff',
              }}>Popular</span>
            )}
          </div>
          <div style={{ fontSize: 13, color: C.mute, marginBottom: 8 }}>{s.description || ''}</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, fontSize: 12.5, color: C.ink2 }}>
            {dur && (
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
                <svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="8" cy="8" r="6.5" /><path d="M8 4v4l2.5 1.5" /></svg>
                {dur}
              </span>
            )}
          </div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div style={{ fontFamily: C.display, fontSize: 20, fontWeight: 600, letterSpacing: '-0.025em' }}>{price}</div>
          <div style={{
            marginTop: 8,
            fontSize: 12, fontWeight: 500,
            padding: '6px 12px', borderRadius: 999,
            background: selected ? C.ink : C.surface,
            color: selected ? '#fff' : C.ink2,
            border: selected ? `1px solid ${C.ink}` : `1px solid ${C.line}`,
            display: 'inline-flex', alignItems: 'center', gap: 5,
          }}>
            {selected ? <><Check size={11} /> Selected</> : 'Select'}
          </div>
        </div>
      </div>
    </article>
  );
}

// ────────────────────────────────────────────────────────────────
function ArtistsBlock({ C, eyebrow, staff, selected, onSelect, artistProfile }) {
  const artists = [
    { id: 'any', full_name: 'Any artist', avatar_url: null, role: 'any' },
    ...staff,
  ];
  return (
    <section>
      <Reveal>
        <div style={{ marginBottom: 18 }}>
          <div style={{ ...eyebrow, marginBottom: 10 }}>Step two</div>
          <h2 style={{ fontFamily: C.display, fontWeight: 600, fontSize: 28, letterSpacing: '-0.03em', margin: 0, lineHeight: 1.1 }}>Choose your artist.</h2>
        </div>
      </Reveal>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
        {artists.map((a, i) => (
          <Reveal key={a.id} delay={i * 50} y={8}>
            <ArtistCard C={C} a={a}
              selected={selected && selected.id === a.id}
              onClick={() => onSelect(a)} />
          </Reveal>
        ))}
      </div>
    </section>
  );
}

function ArtistCard({ C, a, selected, onClick }) {
  const [hover, setHover] = React.useState(false);
  const name = a.full_name || a.name || 'Artist';
  const sub = a.role === 'any' ? 'First available' : (a.role || 'Artist');

  return (
    <button onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        background: selected ? C.accentSoft : C.surface,
        border: `1.5px solid ${selected ? C.accent : C.line}`,
        borderRadius: 14, padding: 14, width: '100%',
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10,
        cursor: 'pointer', textAlign: 'center',
        transition: 'all .2s',
        transform: hover && !selected ? 'translateY(-2px)' : 'none',
      }}>
      {a.avatar_url ? (
        <img src={a.avatar_url} alt={name} style={{ width: 60, height: 60, borderRadius: 999, objectFit: 'cover' }} />
      ) : (
        <span style={{
          width: 60, height: 60, borderRadius: 999,
          background: C.bg2, color: C.mute,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="22" height="22" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="8" cy="6" r="2.5" /><path d="M3 14c0-2.8 2.2-5 5-5s5 2.2 5 5" />
          </svg>
        </span>
      )}
      <div>
        <div style={{ fontSize: 14, fontWeight: 600, letterSpacing: '-0.01em' }}>{name}</div>
        <div style={{ fontSize: 11.5, color: C.mute2, marginTop: 2 }}>{sub}</div>
      </div>
    </button>
  );
}

// ────────────────────────────────────────────────────────────────
function ScheduleBlock({ C, eyebrow, days, day, setDay, time, setTime, timeSlots, slotsLoading, service }) {
  // Group time slots by period
  const morning = timeSlots.filter(t => parseInt(t) < 12);
  const afternoon = timeSlots.filter(t => { const h = parseInt(t); return h >= 12 && h < 17; });
  const evening = timeSlots.filter(t => parseInt(t) >= 17);

  return (
    <section>
      <Reveal>
        <div style={{ marginBottom: 18 }}>
          <div style={{ ...eyebrow, marginBottom: 10 }}>Step three</div>
          <h2 style={{ fontFamily: C.display, fontWeight: 600, fontSize: 28, letterSpacing: '-0.03em', margin: 0, lineHeight: 1.1 }}>Pick a day and time.</h2>
        </div>
      </Reveal>

      <div style={{
        background: C.surface, border: `1px solid ${C.line}`, borderRadius: 16,
        padding: 20,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
          <div style={{ fontSize: 13, fontWeight: 600, letterSpacing: '-0.01em' }}>Next 14 days</div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 6, marginBottom: 18 }}>
          {days.map(d => (
            <button key={d.id}
              onClick={() => { setDay(d); setTime(null); }}
              style={{
                padding: '10px 6px', borderRadius: 10,
                background: day && day.id === d.id ? C.ink : C.surface,
                color: day && day.id === d.id ? '#fff' : C.ink2,
                border: `1px solid ${day && day.id === d.id ? C.ink : C.line}`,
                cursor: 'pointer',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2,
                transition: 'all .15s',
              }}>
              <span style={{ fontSize: 11, fontWeight: 500, color: day && day.id === d.id ? 'rgba(255,255,255,0.7)' : C.mute2 }}>{d.weekday}</span>
              <span style={{ fontFamily: C.display, fontSize: 17, fontWeight: 600, letterSpacing: '-0.015em' }}>{d.date}</span>
              <span style={{ fontSize: 10.5, color: day && day.id === d.id ? 'rgba(255,255,255,0.6)' : C.mute3 }}>{d.month}</span>
            </button>
          ))}
        </div>

        {day && !slotsLoading && timeSlots.length > 0 && (
          <>
            <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 12, padding: '0 2px' }}>
              <div style={{ fontSize: 13, fontWeight: 600 }}>
                Times for {day.weekday}, {day.date} {day.month}
              </div>
              <span style={{
                fontSize: 11, color: C.mute2, padding: '2px 8px', background: C.bg2, borderRadius: 999,
              }}>{timeSlots.length} slots open</span>
            </div>

            {[
              { label: 'Morning', slots: morning },
              { label: 'Afternoon', slots: afternoon },
              { label: 'Evening', slots: evening },
            ].filter(g => g.slots.length > 0).map(g => (
              <div key={g.label} style={{ marginBottom: 14 }}>
                <div style={{
                  fontSize: 10.5, fontWeight: 500, letterSpacing: '0.14em',
                  textTransform: 'uppercase', color: C.mute2, marginBottom: 8,
                }}>{g.label}</div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 6 }}>
                  {g.slots.map(t => {
                    const isSelected = time === t;
                    return (
                      <button key={t}
                        onClick={() => setTime(t)}
                        style={{
                          padding: '10px 4px', borderRadius: 8,
                          fontSize: 13, fontWeight: 500, fontFamily: C.display,
                          background: isSelected ? C.ink : C.surface,
                          color: isSelected ? '#fff' : C.ink,
                          border: `1px solid ${isSelected ? C.ink : C.line}`,
                          cursor: 'pointer',
                          transition: 'all .15s',
                        }}>{t}</button>
                    );
                  })}
                </div>
              </div>
            ))}
          </>
        )}

        {day && slotsLoading && (
          <div style={{ padding: '32px 24px', textAlign: 'center', color: C.mute2, fontSize: 13.5 }}>
            <div style={{ width: 24, height: 24, border: `2px solid ${C.line}`, borderTopColor: C.accent, borderRadius: '50%', animation: 'spin 0.7s linear infinite', margin: '0 auto 12px' }} />
            Loading available times…
          </div>
        )}

        {day && !slotsLoading && timeSlots.length === 0 && (
          <div style={{
            padding: '32px 24px', textAlign: 'center',
            border: `1.5px dashed ${C.line2}`, borderRadius: 12,
            color: C.mute2, fontSize: 13.5,
          }}>
            No available slots for this day. Try another date.
          </div>
        )}

        {!day && (
          <div style={{
            padding: '32px 24px', textAlign: 'center',
            border: `1.5px dashed ${C.line2}`, borderRadius: 12,
            color: C.mute2, fontSize: 13.5,
          }}>
            {service ? 'Pick a day above to see available times.' : 'Select a service first, then pick a day.'}
          </div>
        )}
      </div>
    </section>
  );
}

// ────────────────────────────────────────────────────────────────
function SummaryRail({ C, studio, service, artist, day, time, clientName, setClientName, clientPhone, setClientPhone, clientEmail, setClientEmail, onConfirm }) {
  const ready = service && artist && day && time;
  const price = service ? (typeof service.price === 'number' ? `£${service.price}` : service.price) : '£—';

  return (
    <div style={{
      background: C.surface, border: `1px solid ${C.line}`, borderRadius: 18,
      padding: 22,
      boxShadow: '0 1px 0 rgba(0,0,0,0.02), 0 30px 60px -30px rgba(0,0,0,0.12)',
    }}>
      <div style={{
        fontSize: 11.5, fontWeight: 500, letterSpacing: '0.18em',
        textTransform: 'uppercase', color: C.mute, marginBottom: 16,
      }}>Booking summary</div>

      <SummaryRow C={C} label="Studio" value={studio.name} sub={studio.loc} />
      <SummaryRow C={C} label="Service" value={service ? service.name : 'Choose a service'} sub={service ? `${service.duration || ''} min` : ''} muted={!service} />
      <SummaryRow C={C} label="Artist" value={artist ? (artist.full_name || artist.name) : 'Choose an artist'} muted={!artist} />
      <SummaryRow C={C} label="When" value={day ? `${day.weekday}, ${day.date} ${day.month}` : 'Pick a day'} sub={time || ''} muted={!day} last />

      <div style={{
        borderTop: `1px solid ${C.line}`, borderBottom: `1px solid ${C.line}`,
        padding: '14px 0', margin: '14px 0',
        display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
      }}>
        <span style={{ fontSize: 13.5, fontWeight: 500 }}>Total</span>
        <span style={{
          fontFamily: C.display, fontSize: 26, fontWeight: 600, letterSpacing: '-0.025em',
          color: ready ? C.ink : C.mute3,
        }}>{price}</span>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 14 }}>
        <input
          value={clientName}
          onChange={(e) => setClientName(e.target.value)}
          placeholder="Your name"
          style={{
            background: C.bg, border: `1px solid ${C.line}`, borderRadius: 10,
            padding: '11px 14px', fontSize: 13.5, fontFamily: 'inherit',
            color: C.ink, outline: 'none',
          }}
        />
        <input
          value={clientPhone}
          onChange={(e) => setClientPhone(e.target.value)}
          placeholder="Mobile number"
          style={{
            background: C.bg, border: `1px solid ${C.line}`, borderRadius: 10,
            padding: '11px 14px', fontSize: 13.5, fontFamily: 'inherit',
            color: C.ink, outline: 'none',
          }}
        />
        <input
          value={clientEmail}
          onChange={(e) => setClientEmail(e.target.value)}
          placeholder="Email (optional)"
          style={{
            background: C.bg, border: `1px solid ${C.line}`, borderRadius: 10,
            padding: '11px 14px', fontSize: 13.5, fontFamily: 'inherit',
            color: C.ink, outline: 'none',
          }}
        />
      </div>

      <button
        disabled={!ready}
        onClick={onConfirm}
        style={{
          width: '100%',
          background: ready ? C.ink : C.bg2,
          color: ready ? '#fff' : C.mute2,
          border: 0, borderRadius: 999,
          padding: '14px', fontSize: 14.5, fontWeight: 500,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 9,
          cursor: ready ? 'pointer' : 'not-allowed',
          transition: 'all .2s',
        }}>
        {ready ? <>Confirm appointment <ArrowR size={12} /></> : 'Complete the steps above'}
      </button>

      <div style={{ marginTop: 14, fontSize: 12, color: C.mute, textAlign: 'center', lineHeight: 1.55 }}>
        Free to book. The studio will text you to confirm within an hour.
      </div>
    </div>
  );
}

function SummaryRow({ C, label, value, sub, muted, last }) {
  return (
    <div style={{
      padding: '10px 0',
      borderBottom: last ? 'none' : `1px solid ${C.line}`,
    }}>
      <div style={{ fontSize: 11, color: C.mute2, fontWeight: 500, letterSpacing: '0.1em', textTransform: 'uppercase', marginBottom: 3 }}>{label}</div>
      <div style={{ fontSize: 13.5, fontWeight: 500, color: muted ? C.mute2 : C.ink }}>{value}</div>
      {sub && <div style={{ fontSize: 12, color: C.mute2, marginTop: 2 }}>{sub}</div>}
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
function ClientSuccess({ C, studio, service, artist, day, time, createdBooking, onReset }) {
  const price = service ? (typeof service.price === 'number' ? `£${service.price}` : service.price) : '';
  return (
    <section style={{ maxWidth: 700, margin: '0 auto', padding: '72px 40px 80px', textAlign: 'center' }}>
      <Reveal>
        <div style={{
          width: 72, height: 72, borderRadius: 999,
          background: C.successSoft, color: C.success,
          margin: '0 auto 24px',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="32" height="32" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="3 8 7 12 13 4" />
          </svg>
        </div>
        <h1 style={{
          fontFamily: C.display, fontWeight: 600, fontSize: 42,
          letterSpacing: '-0.04em', lineHeight: 1.05, margin: '0 0 12px',
        }}>You're booked in.</h1>
        <p style={{ fontSize: 16, color: C.mute, margin: '0 auto 32px', lineHeight: 1.6, maxWidth: 480 }}>
          {studio.name} will text you a confirmation within the hour.
        </p>
      </Reveal>

      <Reveal delay={120}>
        <div style={{
          background: C.surface, border: `1px solid ${C.line}`, borderRadius: 18,
          padding: 24, textAlign: 'left', marginBottom: 24,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 20 }}>
            <span style={{
              width: 48, height: 48, borderRadius: 12,
              background: C.ink, color: '#fff',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: C.display, fontSize: 18, fontWeight: 700,
            }}>{studio.initial}</span>
            <div>
              <div style={{ fontFamily: C.display, fontSize: 17, fontWeight: 600 }}>{studio.name}</div>
              <div style={{ fontSize: 12.5, color: C.mute }}>{studio.address}</div>
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, paddingTop: 18, borderTop: `1px solid ${C.line}` }}>
            <SuccessStat C={C} label="Service" value={service ? service.name : ''} sub={service ? `${service.duration} min` : ''} />
            <SuccessStat C={C} label="Artist" value={artist ? (artist.full_name || artist.name) : ''} />
            <SuccessStat C={C} label="When" value={day ? `${day.weekday}, ${day.date} ${day.month}` : ''} sub={time} />
            <SuccessStat C={C} label="Price" value={price} sub="Pay at the studio" />
          </div>
        </div>
      </Reveal>

      <Reveal delay={220}>
        <div style={{ display: 'inline-flex', gap: 10 }}>
          <button onClick={onReset} style={{
            background: 'transparent', color: C.ink2,
            border: `1px solid ${C.line}`, borderRadius: 999,
            padding: '13px 22px', fontSize: 14, fontWeight: 500,
            cursor: 'pointer',
          }}>Book another</button>
        </div>
      </Reveal>

      <Reveal delay={320}>
        <p style={{ marginTop: 32, fontSize: 12, color: C.mute, lineHeight: 1.6 }}>
          Need to change or cancel? Reply to the confirmation text or call the studio directly.
        </p>
      </Reveal>
    </section>
  );
}

function SuccessStat({ C, label, value, sub }) {
  return (
    <div>
      <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.mute, marginBottom: 5 }}>{label}</div>
      <div style={{ fontFamily: C.display, fontSize: 17, fontWeight: 600, letterSpacing: '-0.018em' }}>{value}</div>
      {sub && <div style={{ fontSize: 12, color: C.mute2, marginTop: 2 }}>{sub}</div>}
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
function ClientFooter({ C, studio }) {
  return (
    <section style={{ borderTop: `1px solid ${C.line}`, background: C.surface, padding: '32px 40px' }}>
      <div style={{
        maxWidth: 1240, margin: '0 auto',
        display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 24, flexWrap: 'wrap',
        fontSize: 12.5, color: C.mute,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{
            width: 24, height: 24, borderRadius: 7,
            background: C.ink, color: '#fff',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: C.display, fontSize: 11, fontWeight: 700,
          }}>{studio.initial}</span>
          <span style={{ fontWeight: 500, color: C.ink2 }}>{studio.name}</span>
          {studio.address && (
            <>
              <span style={{ color: C.mute3 }}>·</span>
              <span>{studio.address}</span>
            </>
          )}
        </div>
        <a href="/" style={{ fontSize: 12, color: C.mute2, textDecoration: 'none' }}>
          Powered by <strong style={{ color: C.ink, fontWeight: 600 }}>Loxley</strong>
        </a>
      </div>
    </section>
  );
}

Object.assign(window, { ClientBookingPage });
