// VeloraTech — Booking modal (Technician visit + Consultation call)
const { useState, useEffect, useMemo } = React;

const FORMSPREE_URL = 'https://formspree.io/f/xykveqan';

function submitBooking(payload) {
  return fetch(FORMSPREE_URL, {
    method: 'POST',
    headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  }).then(function (res) { return res.ok; }).catch(function () { return false; });
}

// ----- Service catalog -----
const TECH_SERVICES = [
  { id: 'wifi',    name: 'Home Internet & Wi-Fi Setup',       icon: 'Wifi',     price: 'from $140' },
  { id: 'cctv',    name: 'CCTV & Smart Home Installation',    icon: 'Camera',   price: 'from $220' },
  { id: 'biz',     name: 'Business IT Support',               icon: 'Building', price: 'from $100' },
  { id: 'compute', name: 'Computer & Printer Help',           icon: 'Tv',       price: 'from $110' },
  { id: 'other',   name: 'Something Else',                    icon: 'Hand',     price: 'quoted on call' },
];

const CONSULT_TOPICS = [
  { id: 'web',     name: 'Web Design & Ongoing Care',         icon: 'Globe',    price: 'free 30 min' },
  { id: 'wifi',    name: 'Home Internet & Wi-Fi Setup',       icon: 'Wifi',     price: 'free 30 min' },
  { id: 'cctv',    name: 'CCTV & Smart Home Installation',    icon: 'Camera',   price: 'free 30 min' },
  { id: 'biz',     name: 'Business IT Support',               icon: 'Building', price: 'free 30 min' },
  { id: 'compute', name: 'Computer & Printer Help',           icon: 'Tv',       price: 'free 30 min' },
  { id: 'other',   name: 'Something Else',                    icon: 'Hand',     price: 'free 30 min' },
];

const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const DOW = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];

const TIME_SLOTS_WEEKDAY = ['08:00', '09:30', '11:00', '12:30', '14:00', '15:30', '17:00', '18:30'];
const TIME_SLOTS_WEEKEND = ['09:00', '10:30', '12:00', '13:30', '15:00', '16:30'];

// Simulated booked slots so calendar shows realism
const BOOKED = {
  // ISO date -> array of disabled times
};
function isBooked(iso, time) {
  return BOOKED[iso] && BOOKED[iso].includes(time);
}

function pad(n) { return n < 10 ? '0' + n : '' + n; }
function isoFor(d) {
  return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}`;
}
function sameDay(a, b) {
  return a.getFullYear()===b.getFullYear() && a.getMonth()===b.getMonth() && a.getDate()===b.getDate();
}
function addDays(d, n) {
  const x = new Date(d); x.setDate(x.getDate()+n); return x;
}

// ----- Calendar -----
function Calendar({ value, onChange, minDate }) {
  const today = useMemo(() => { const t = new Date(); t.setHours(0,0,0,0); return t; }, []);
  const initial = value || today;
  const [view, setView] = useState({ year: initial.getFullYear(), month: initial.getMonth() });

  const firstOfMonth = new Date(view.year, view.month, 1);
  const startWeekday = firstOfMonth.getDay();
  const daysInMonth = new Date(view.year, view.month + 1, 0).getDate();
  const prevMonthDays = new Date(view.year, view.month, 0).getDate();

  const cells = [];
  for (let i = startWeekday - 1; i >= 0; i--) {
    cells.push({ day: prevMonthDays - i, muted: true, date: new Date(view.year, view.month - 1, prevMonthDays - i) });
  }
  for (let d = 1; d <= daysInMonth; d++) {
    cells.push({ day: d, muted: false, date: new Date(view.year, view.month, d) });
  }
  while (cells.length % 7 !== 0 || cells.length < 42) {
    const idx = cells.length - (startWeekday + daysInMonth) + 1;
    cells.push({ day: idx, muted: true, date: new Date(view.year, view.month + 1, idx) });
    if (cells.length >= 42) break;
  }

  const min = minDate || today;
  const monthLabel = `${MONTHS[view.month]} ${view.year}`;
  const canGoBack = view.year > today.getFullYear() || (view.year === today.getFullYear() && view.month > today.getMonth());

  return (
    <div className="cal">
      <div className="cal__head">
        <div className="cal__title">{monthLabel}</div>
        <div className="cal__nav">
          <button type="button" onClick={() => setView(v => v.month === 0 ? { year: v.year - 1, month: 11 } : { ...v, month: v.month - 1 })} disabled={!canGoBack}><Icon.ChevronL/></button>
          <button type="button" onClick={() => setView(v => v.month === 11 ? { year: v.year + 1, month: 0 } : { ...v, month: v.month + 1 })}><Icon.ChevronR/></button>
        </div>
      </div>
      <div className="cal__grid">
        {DOW.map(d => <div key={d} className="cal__dow">{d}</div>)}
        {cells.map((c, i) => {
          const isPast = c.date < min;
          const dow = c.date.getDay();
          const isWeekend = dow === 0 || dow === 6;
          const isSelected = value && sameDay(value, c.date);
          const isToday = sameDay(c.date, today);
          const classes = ['cal__cell'];
          if (c.muted) classes.push('muted');
          if (isWeekend) classes.push('weekend');
          if (isToday) classes.push('today');
          if (isSelected) classes.push('selected');
          return (
            <button
              key={i}
              type="button"
              className={classes.join(' ')}
              disabled={isPast}
              onClick={() => onChange(c.date)}
            >{c.day}</button>
          );
        })}
      </div>
      <div className="cal-foot">
        <span><span className="dotw"></span>Weekends open</span>
        <span>Mon-Fri 8am – 8pm</span>
        <span>Sat-Sun 9am – 6pm</span>
      </div>
    </div>
  );
}

// ----- Modal shell -----
function Modal({ title, subtitle, onClose, children, footer }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [onClose]);
  return (
    <div className="modal-backdrop" onClick={(e) => { if (e.target.classList.contains('modal-backdrop')) onClose(); }}>
      <div className="modal" role="dialog" aria-modal="true">
        <div className="modal__head">
          <div>
            <h3 className="modal__title">{title}</h3>
            {subtitle && <p className="modal__sub">{subtitle}</p>}
          </div>
          <button className="modal__close" type="button" onClick={onClose} aria-label="Close"><Icon.Close/></button>
        </div>
        <div className="modal__body">{children}</div>
        {footer && <div className="modal__footer">{footer}</div>}
      </div>
    </div>
  );
}

// ----- Technician booking flow -----
function TechnicianBooking({ onClose }) {
  const [step, setStep] = useState(0);
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState(false);
  const [data, setData] = useState({
    location: 'home',
    services: [],
    date: null,
    time: null,
    name: '',
    phone: '',
    email: '',
    address: '',
    suburb: '',
    notes: '',
  });
  const [errors, setErrors] = useState({});

  const update = (k, v) => setData(d => ({ ...d, [k]: v }));
  const toggleService = (id) => {
    setData(d => ({
      ...d,
      services: d.services.includes(id) ? d.services.filter(s => s !== id) : [...d.services, id],
    }));
  };

  const isWeekend = data.date && (data.date.getDay() === 0 || data.date.getDay() === 6);
  const slots = isWeekend ? TIME_SLOTS_WEEKEND : TIME_SLOTS_WEEKDAY;

  const validate = () => {
    const e = {};
    if (step === 0) {
      if (data.services.length === 0) e.services = 'Pick at least one';
    } else if (step === 1) {
      if (!data.date) e.date = 'Choose a date';
      if (!data.time) e.time = 'Pick a time';
    } else if (step === 2) {
      if (!data.name.trim()) e.name = 'Required';
      if (!data.phone.trim()) e.phone = 'Required';
      if (!data.email.trim() || !data.email.includes('@')) e.email = 'Enter a valid email';
      if (!data.address.trim()) e.address = 'Required';
      if (!data.suburb.trim()) e.suburb = 'Required';
    }
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const next = () => { if (validate()) setStep(s => s + 1); };
  const back = () => setStep(s => Math.max(0, s - 1));

  const ref = useMemo(() => 'VT-' + Math.random().toString(36).slice(2, 7).toUpperCase(), []);

  const confirm = () => {
    setSubmitting(true);
    setSubmitError(false);

    const today = new Date().toISOString().split('T')[0];
    const serviceNames = data.services.map(id => TECH_SERVICES.find(s => s.id === id)?.name).filter(Boolean).join(', ');
    const SVC_AMT = { wifi: 140, cctv: 220, biz: 100, compute: 110, other: 0 };
    const totalAmt = data.services.reduce((s, id) => s + (SVC_AMT[id] || 0), 0);

    const payload = {
      _subject: `New technician visit — ${data.name} (${ref})`,
      booking_type: 'Technician visit',
      reference: ref,
      location_type: data.location,
      services: serviceNames,
      date: data.date && data.date.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }),
      time: data.time,
      name: data.name,
      phone: data.phone,
      email: data.email,
      address: data.address,
      suburb: data.suburb,
      notes: data.notes,
    };

    // 1. Write to Supabase — admin sees this in the Jobs panel immediately
    window.vtNextJobId && window.vtNextJobId().then(jobId => window.vtInsertJob({
      id: jobId,
      customer: data.name.trim(),
      phone: data.phone.trim(),
      email: data.email.trim(),
      service: serviceNames || 'Technician Visit',
      address: [data.address.trim(), data.suburb.trim()].filter(Boolean).join(', '),
      lat: 0, lng: 0,
      date: data.date ? isoFor(data.date) : today,
      time: data.time || '09:00',
      status: 'Pending',
      assigned_to: '',
      deposit_paid: false,
      notes: [data.location === 'business' ? 'Location: Business/site' : '', data.notes.trim()].filter(Boolean).join('\n'),
      amount: totalAmt,
      created: today,
    })).catch(e => console.warn('[VT] Supabase job write:', e));

    // 2. Email notification (fire-and-forget)
    try { submitBooking(payload).catch(() => {}); } catch (e) {}

    // 3. Show success after brief visual delay
    setTimeout(() => {
      setSubmitting(false);
      setStep(4);
    }, 700);
  };

  // ----- step content -----
  let body, footer;
  if (step === 0) {
    body = (
      <>
        <Stepper count={4} active={0}/>
        <div className="field">
          <label className="field__label">Where do you need us?</label>
          <div className="toggle-group">
            <button type="button" className={data.location === 'home' ? 'active' : ''} onClick={() => update('location','home')}>
              <Icon.Home/> &nbsp;Home visit
            </button>
            <button type="button" className={data.location === 'business' ? 'active' : ''} onClick={() => update('location','business')}>
              <Icon.Building/> &nbsp;Business / site
            </button>
          </div>
        </div>
        <div className="field">
          <label className="field__label">What can we help with? (pick any)</label>
          <div className="svc-picker">
            {TECH_SERVICES.map(s => {
              const Ico = Icon[s.icon];
              const active = data.services.includes(s.id);
              return (
                <button key={s.id} type="button" className={'svc-chip' + (active ? ' active' : '')} onClick={() => toggleService(s.id)}>
                  <div className="svc-chip__icon"><Ico/></div>
                  <div style={{flex: 1, minWidth: 0}}>
                    <div className="svc-chip__name">{s.name}</div>
                    <div className="svc-chip__price">{s.price}</div>
                  </div>
                  {active && <Icon.Check/>}
                </button>
              );
            })}
          </div>
          {errors.services && <div className="field__err">{errors.services}</div>}
        </div>
      </>
    );
    footer = (
      <>
        <span className="modal__hint">Step 1 of 4 — services</span>
        <button className="btn btn--ink" type="button" onClick={next}>Continue <Icon.Arrow/></button>
      </>
    );
  } else if (step === 1) {
    body = (
      <>
        <Stepper count={4} active={1}/>
        <Calendar value={data.date} onChange={(d) => { update('date', d); update('time', null); }} />
        {data.date && (
          <>
            <div className="field" style={{marginTop: 22}}>
              <label className="field__label">Available times — {data.date.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })}</label>
              <div className="slots">
                {slots.map(t => {
                  const disabled = isBooked(isoFor(data.date), t);
                  return (
                    <button key={t} type="button" className={'slot' + (data.time === t ? ' active' : '')} disabled={disabled} onClick={() => update('time', t)}>{t}</button>
                  );
                })}
              </div>
            </div>
          </>
        )}
        {errors.date && <div className="field__err mt-8">{errors.date}</div>}
        {errors.time && <div className="field__err mt-8">{errors.time}</div>}
      </>
    );
    footer = (
      <>
        <button className="btn btn--ghost btn--sm" type="button" onClick={back}>Back</button>
        <button className="btn btn--ink" type="button" onClick={next}>Continue <Icon.Arrow/></button>
      </>
    );
  } else if (step === 2) {
    body = (
      <>
        <Stepper count={4} active={2}/>
        <div className="field__row">
          <div className="field">
            <label className="field__label">Full name</label>
            <input className="field__input" value={data.name} onChange={e => update('name', e.target.value)} placeholder="Jordan Hayes"/>
            {errors.name && <div className="field__err">{errors.name}</div>}
          </div>
          <div className="field">
            <label className="field__label">Phone</label>
            <input className="field__input" value={data.phone} onChange={e => update('phone', e.target.value)} placeholder="0400 000 000"/>
            {errors.phone && <div className="field__err">{errors.phone}</div>}
          </div>
        </div>
        <div className="field">
          <label className="field__label">Email</label>
          <input type="email" className="field__input" value={data.email} onChange={e => update('email', e.target.value)} placeholder="you@email.com"/>
          {errors.email && <div className="field__err">{errors.email}</div>}
        </div>
        <div className="field">
          <label className="field__label">Street address</label>
          <input className="field__input" value={data.address} onChange={e => update('address', e.target.value)} placeholder="12 Sample Street"/>
          {errors.address && <div className="field__err">{errors.address}</div>}
        </div>
        <div className="field__row">
          <div className="field">
            <label className="field__label">Suburb / postcode</label>
            <input className="field__input" value={data.suburb} onChange={e => update('suburb', e.target.value)} placeholder="Burleigh Heads 4220"/>
            {errors.suburb && <div className="field__err">{errors.suburb}</div>}
          </div>
          <div className="field">
            <label className="field__label">Access notes (optional)</label>
            <input className="field__input" value={data.notes} onChange={e => update('notes', e.target.value)} placeholder="Parking, gate code…"/>
          </div>
        </div>
      </>
    );
    footer = (
      <>
        <button className="btn btn--ghost btn--sm" type="button" onClick={back}>Back</button>
        <button className="btn btn--ink" type="button" onClick={next}>Review <Icon.Arrow/></button>
      </>
    );
  } else if (step === 3) {
    const serviceNames = data.services.map(id => TECH_SERVICES.find(s => s.id === id)?.name).join(', ');
    body = (
      <>
        <Stepper count={4} active={3}/>
        <div className="summary">
          <div className="summary__row"><span className="k">Service</span><span className="v">{data.location === 'home' ? 'Home visit' : 'Business / site'}</span></div>
          <div className="summary__row"><span className="k">Helping with</span><span className="v" style={{textAlign: 'right', maxWidth: '60%'}}>{serviceNames}</span></div>
          <div className="summary__row"><span className="k">Date</span><span className="v accent">{data.date?.toLocaleDateString('en-AU', { weekday: 'short', day: 'numeric', month: 'short' })}</span></div>
          <div className="summary__row"><span className="k">Time</span><span className="v accent">{data.time}</span></div>
          <div className="summary__row"><span className="k">Contact</span><span className="v">{data.name}</span></div>
          <div className="summary__row"><span className="k">At</span><span className="v" style={{textAlign:'right', fontSize:14}}>{data.address}, {data.suburb}</span></div>
        </div>
        <p style={{fontSize: 13, color: 'var(--ink-3)', margin: 0}}>
          We'll send a confirmation to <strong>{data.email}</strong> and an SMS reminder the morning of your visit. Cancel free up to 4 hours before.
        </p>
        {submitError && (
          <div className="field__err" style={{marginTop: 14}}>Couldn't send your booking — please call 0449 991 572 or try again.</div>
        )}
      </>
    );
    footer = (
      <>
        <button className="btn btn--ghost btn--sm" type="button" onClick={back} disabled={submitting}>Back</button>
        <button className="btn btn--primary" type="button" onClick={confirm} disabled={submitting}>
          {submitting ? 'Sending…' : (<>Confirm booking <Icon.Check/></>)}
        </button>
      </>
    );
  } else {
    body = (
      <div className="success">
        <div className="success__icon"><Icon.Check/></div>
        <h3 className="success__title">You're <em>booked in.</em></h3>
        <p className="success__sub">A technician will arrive on {data.date?.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })} between {data.time} and {addHour(data.time)}. We've sent the details to {data.email}.</p>
        <div className="success__ref">Ref · {ref}</div>
      </div>
    );
    footer = (
      <>
        <span className="modal__hint">Need to reach us? 0449 991 572</span>
        <button className="btn btn--ink" type="button" onClick={onClose}>Done</button>
      </>
    );
  }

  return (
    <Modal
      title={<>Book a <em>technician visit</em></>}
      subtitle="On-site help — homes, businesses, anywhere across Brisbane, Gold Coast & Tweed Heads."
      onClose={onClose}
      footer={footer}
    >{body}</Modal>
  );
}

function addHour(t) {
  if (!t) return '';
  const [h, m] = t.split(':').map(Number);
  const nh = (h + 1) % 24;
  return pad(nh) + ':' + pad(m);
}

// ----- Consultation flow -----
function ConsultationBooking({ onClose }) {
  const [step, setStep] = useState(0);
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState(false);
  const [data, setData] = useState({
    topic: null,
    date: null,
    time: null,
    name: '',
    phone: '',
    email: '',
    business: '',
    notes: '',
    method: 'phone',
  });
  const [errors, setErrors] = useState({});
  const update = (k, v) => setData(d => ({ ...d, [k]: v }));

  const isWeekend = data.date && (data.date.getDay() === 0 || data.date.getDay() === 6);
  const slots = isWeekend ? TIME_SLOTS_WEEKEND : TIME_SLOTS_WEEKDAY;

  const validate = () => {
    const e = {};
    if (step === 0) {
      if (!data.topic) e.topic = 'Pick a topic';
    } else if (step === 1) {
      if (!data.date) e.date = 'Choose a date';
      if (!data.time) e.time = 'Pick a time';
    } else if (step === 2) {
      if (!data.name.trim()) e.name = 'Required';
      if (!data.phone.trim()) e.phone = 'Required';
      if (!data.email.trim() || !data.email.includes('@')) e.email = 'Enter a valid email';
    }
    setErrors(e);
    return Object.keys(e).length === 0;
  };
  const next = () => { if (validate()) setStep(s => s + 1); };
  const back = () => setStep(s => Math.max(0, s - 1));

  const ref = useMemo(() => 'VT-' + Math.random().toString(36).slice(2, 7).toUpperCase(), []);

  const confirm = () => {
    setSubmitting(true);
    setSubmitError(false);

    const today = new Date().toISOString().split('T')[0];
    const topic = CONSULT_TOPICS.find(t => t.id === data.topic);

    const payload = {
      _subject: `New free-consult booking — ${data.name} (${ref})`,
      booking_type: 'Free 30-min consultation',
      reference: ref,
      topic: topic && topic.name,
      call_method: data.method === 'phone' ? 'Phone call' : 'Video call',
      date: data.date && data.date.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }),
      time: data.time,
      name: data.name,
      phone: data.phone,
      email: data.email,
      business: data.business,
      notes: data.notes,
    };

    // 1. Write to Supabase — admin sees this in the Jobs panel immediately
    window.vtNextJobId && window.vtNextJobId().then(jobId => window.vtInsertJob({
      id: jobId,
      customer: data.name.trim(),
      phone: data.phone.trim(),
      email: data.email.trim(),
      service: 'Free Consultation',
      address: '',
      lat: 0, lng: 0,
      date: data.date ? isoFor(data.date) : today,
      time: data.time || '09:00',
      status: 'Pending',
      assigned_to: '',
      deposit_paid: false,
      notes: [
        topic ? 'Topic: ' + topic.name : '',
        'Call format: ' + (data.method === 'video' ? 'Video call' : 'Phone call'),
        data.business ? 'Business: ' + data.business : '',
        data.notes.trim(),
      ].filter(Boolean).join('\n'),
      amount: 0,
      created: today,
    })).catch(e => console.warn('[VT] Supabase consult write:', e));

    // 2. Email notification (fire-and-forget)
    try { submitBooking(payload).catch(() => {}); } catch (e) {}

    // 3. Show success
    setTimeout(() => {
      setSubmitting(false);
      setStep(4);
    }, 700);
  };

  let body, footer;
  if (step === 0) {
    body = (
      <>
        <Stepper count={4} active={0}/>
        <div className="field">
          <label className="field__label">What would you like to talk about?</label>
          <div className="svc-picker">
            {CONSULT_TOPICS.map(t => {
              const Ico = Icon[t.icon];
              const active = data.topic === t.id;
              return (
                <button key={t.id} type="button" className={'svc-chip' + (active ? ' active' : '')} onClick={() => update('topic', t.id)}>
                  <div className="svc-chip__icon"><Ico/></div>
                  <div style={{flex: 1, minWidth: 0}}>
                    <div className="svc-chip__name">{t.name}</div>
                    <div className="svc-chip__price">{t.price}</div>
                  </div>
                  {active && <Icon.Check/>}
                </button>
              );
            })}
          </div>
          {errors.topic && <div className="field__err">{errors.topic}</div>}
        </div>
        <div className="field">
          <label className="field__label">How should we call?</label>
          <div className="toggle-group">
            <button type="button" className={data.method === 'phone' ? 'active' : ''} onClick={() => update('method','phone')}>
              <Icon.Phone/> &nbsp;Phone call
            </button>
            <button type="button" className={data.method === 'video' ? 'active' : ''} onClick={() => update('method','video')}>
              <Icon.Globe/> &nbsp;Video call
            </button>
          </div>
        </div>
      </>
    );
    footer = (
      <>
        <span className="modal__hint">Step 1 of 4 — topic</span>
        <button className="btn btn--ink" type="button" onClick={next}>Pick a time <Icon.Arrow/></button>
      </>
    );
  } else if (step === 1) {
    body = (
      <>
        <Stepper count={4} active={1}/>
        <Calendar value={data.date} onChange={(d) => { update('date', d); update('time', null); }} />
        {data.date && (
          <div className="field" style={{marginTop: 22}}>
            <label className="field__label">Available times — {data.date.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })}</label>
            <div className="slots">
              {slots.map(t => (
                <button key={t} type="button" className={'slot' + (data.time === t ? ' active' : '')} onClick={() => update('time', t)}>{t}</button>
              ))}
            </div>
          </div>
        )}
        {errors.date && <div className="field__err mt-8">{errors.date}</div>}
        {errors.time && <div className="field__err mt-8">{errors.time}</div>}
      </>
    );
    footer = (
      <>
        <button className="btn btn--ghost btn--sm" type="button" onClick={back}>Back</button>
        <button className="btn btn--ink" type="button" onClick={next}>Continue <Icon.Arrow/></button>
      </>
    );
  } else if (step === 2) {
    body = (
      <>
        <Stepper count={4} active={2}/>
        <div className="field__row">
          <div className="field">
            <label className="field__label">Full name</label>
            <input className="field__input" value={data.name} onChange={e => update('name', e.target.value)} placeholder="Jordan Hayes"/>
            {errors.name && <div className="field__err">{errors.name}</div>}
          </div>
          <div className="field">
            <label className="field__label">Phone</label>
            <input className="field__input" value={data.phone} onChange={e => update('phone', e.target.value)} placeholder="0400 000 000"/>
            {errors.phone && <div className="field__err">{errors.phone}</div>}
          </div>
        </div>
        <div className="field">
          <label className="field__label">Email</label>
          <input type="email" className="field__input" value={data.email} onChange={e => update('email', e.target.value)} placeholder="you@email.com"/>
          {errors.email && <div className="field__err">{errors.email}</div>}
        </div>
        <div className="field">
          <label className="field__label">Business name (optional)</label>
          <input className="field__input" value={data.business} onChange={e => update('business', e.target.value)} placeholder="e.g. Harbour Plumbing"/>
        </div>
        <div className="field">
          <label className="field__label">What should we know before the call?</label>
          <textarea className="field__textarea" value={data.notes} onChange={e => update('notes', e.target.value)} placeholder="A quick sketch of your business, current website (if any), goals…"/>
        </div>
      </>
    );
    footer = (
      <>
        <button className="btn btn--ghost btn--sm" type="button" onClick={back}>Back</button>
        <button className="btn btn--ink" type="button" onClick={next}>Review <Icon.Arrow/></button>
      </>
    );
  } else if (step === 3) {
    const topic = CONSULT_TOPICS.find(t => t.id === data.topic);
    body = (
      <>
        <Stepper count={4} active={3}/>
        <div className="summary">
          <div className="summary__row"><span className="k">Topic</span><span className="v">{topic?.name}</span></div>
          <div className="summary__row"><span className="k">Format</span><span className="v">{data.method === 'phone' ? 'Phone call' : 'Video call'} · 30 min</span></div>
          <div className="summary__row"><span className="k">Date</span><span className="v accent">{data.date?.toLocaleDateString('en-AU', { weekday: 'short', day: 'numeric', month: 'short' })}</span></div>
          <div className="summary__row"><span className="k">Time</span><span className="v accent">{data.time}</span></div>
          <div className="summary__row"><span className="k">Contact</span><span className="v">{data.name}</span></div>
          <div className="summary__row"><span className="k">Cost</span><span className="v">Free — no obligation</span></div>
        </div>
        <p style={{fontSize: 13, color: 'var(--ink-3)', margin: 0}}>
          We'll send a calendar invite to <strong>{data.email}</strong>. You can reschedule from the invite any time.
        </p>
        {submitError && (
          <div className="field__err" style={{marginTop: 14}}>Couldn't send your booking — please call 0449 991 572 or try again.</div>
        )}
      </>
    );
    footer = (
      <>
        <button className="btn btn--ghost btn--sm" type="button" onClick={back} disabled={submitting}>Back</button>
        <button className="btn btn--primary" type="button" onClick={confirm} disabled={submitting}>
          {submitting ? 'Sending…' : (<>Confirm call <Icon.Check/></>)}
        </button>
      </>
    );
  } else {
    body = (
      <div className="success">
        <div className="success__icon"><Icon.Check/></div>
        <h3 className="success__title">All <em>locked in.</em></h3>
        <p className="success__sub">We'll call you on {data.date?.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })} at {data.time}. The invite is on its way to {data.email}.</p>
        <div className="success__ref">Ref · {ref}</div>
      </div>
    );
    footer = (
      <>
        <span className="modal__hint">Talk soon · info@veloratech.com.au</span>
        <button className="btn btn--ink" type="button" onClick={onClose}>Done</button>
      </>
    );
  }

  return (
    <Modal
      title={<>Free <em>30-minute consult</em></>}
      subtitle="No-obligation chat about your website, IT or business tech."
      onClose={onClose}
      footer={footer}
    >{body}</Modal>
  );
}

function Stepper({ count, active }) {
  return (
    <div className="stepper">
      {Array.from({length: count}).map((_, i) => (
        <div key={i} className={'stepper__dot ' + (i < active ? 'done' : i === active ? 'active' : '')}></div>
      ))}
    </div>
  );
}

window.TechnicianBooking = TechnicianBooking;
window.ConsultationBooking = ConsultationBooking;
