// app.jsx - EvryStay demo booking portal (flow + state)
const { useState, useEffect, useMemo, useRef } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "layout": "sidebar",
  "surface": "gradient",
  "buttons": "gradient",
  "accent": "#6858F9"
}/*EDITMODE-END*/;

const STORE_KEY = 'evry_booking_v1';
const TODAY = new Date(2026, 5, 6); // June 6 2026 (project clock)
const SCHEDULER_URLS = {
  ivan: 'https://scheduler.zoom.us/ivan-vargas-cfwey1/chat-with-ivan',
  support: 'https://scheduler.zoom.us/ivan-vargas-cfwey1/evrystay-support',
  frazer: 'https://scheduler.zoom.us/d/imyeosqc/evrystay-meeting',
};

// Frazer's scheduler is only used when his presence is guaranteed (large
// portfolios, or invited by him directly). A CEO *request* via the toggle
// stays on Ivan's calendar - Frazer may not accept - and the request is
// passed into the booking instead.
// Booking-form prefill: Zoom Scheduler matches query params to form fields
// by question text, lowercased with spaces removed (unmatched params are
// ignored). The booking pages need custom questions named: Company,
// Current PMS, Properties Managed, Booking Reason, CEO Requested.
function schedulerUrl(intent, form, route) {
  const frazerGuaranteed = route.hosts.some((h) => h.id === 'frazer') && !route.ceoRequested;
  const base = intent === 'support'
    ? SCHEDULER_URLS.support
    : frazerGuaranteed ? SCHEDULER_URLS.frazer : SCHEDULER_URLS.ivan;
  const p = new URLSearchParams({ embed: 'true' });
  if (form.name) {
    const parts = form.name.trim().split(/\s+/);
    p.set('firstname', parts[0]);
    if (parts.length > 1) p.set('lastname', parts.slice(1).join(' '));
  }
  if (form.email) p.set('email', form.email);
  if (form.phone) p.set('phone', form.phone);
  if (form.company) p.set('company', form.company);
  if (form.pms) p.set('currentpms', form.pms);
  if (form.tier) {
    const tier = PROPERTY_TIERS.find((t) => t.id === form.tier);
    p.set('propertiesmanaged', tier ? (tier.k + ' ' + tier.s) : form.tier);
  }
  p.set('bookingreason', intent === 'invited'
    ? 'Invited by ' + (route.hosts[0] ? route.hosts[0].name : 'the team')
    : intent === 'support' ? 'Support call' : 'Product demo');
  if (route.ceoRequested) p.set('ceorequested', 'Yes - pending Frazer’s confirmation');
  return base + '?' + p.toString();
}

function loadState() {
  try {
    const raw = localStorage.getItem(STORE_KEY);
    if (!raw) return null;
    const s = JSON.parse(raw);
    if (s.dateISO) s.date = new Date(s.dateISO);
    if (s.monthISO) s.month = new Date(s.monthISO);
    return s;
  } catch (e) { return null; }
}

/* =========================================================== INTENT / ROUTING */
const INTENT_FLOW = {
  demo:    { steps: ['portfolio', 'time'], labels: ['Portfolio', 'Pick a time'] },
  invited: { steps: ['inviter', 'time'],   labels: ['Who invited you', 'Pick a time'] },
  support: { steps: ['support', 'time'],   labels: ['How can we help', 'Pick a time'] },
};

const INTENT_PATHS = { demo: '/demo', invited: '/invited', support: '/support' };

function routeFromPath(pathname) {
  const path = (pathname || '/').replace(/\/+$/, '') || '/';
  if (path === '/') return { view: 'landing' };
  if (path === '/book') return { view: 'intent' };
  if (path === '/done') return { view: 'done' };
  for (const id of Object.keys(INTENT_PATHS)) {
    const base = INTENT_PATHS[id];
    if (path === base) return { view: 'wizard', intent: id, step: 0 };
    if (path === base + '/booking') return { view: 'wizard', intent: id, step: 1 };
  }
  return { view: 'landing' };
}

function pathForWizard(intent, step) {
  const base = INTENT_PATHS[intent] || INTENT_PATHS.demo;
  return step > 0 ? base + '/booking' : base;
}

// Hosts + open windows depend on why they came.
function buildRoute(intent, form) {
  if (intent === 'invited') {
    if (form.inviter === 'frazer')
      return { hosts: [TEAM.frazer], windows: ['afternoon'], big: false, canRequestCeo: false,
               note: 'Frazer hosts in the afternoon, 2:00–5:30pm AEST.' };
    return { hosts: [TEAM.ivan], windows: ['morning', 'afternoon'], big: false, canRequestCeo: false,
             note: 'Ivan hosts your session - mornings or afternoons.' };
  }
  if (intent === 'support') {
    return { hosts: [TEAM.ivan], windows: ['morning'], big: false, canRequestCeo: false,
             note: 'A quick morning call with Ivan, 10:00–1:00pm AEST.' };
  }
  return routeFor(form.tier, form.ceoRequested);
}

/* =========================================================== LANDING */
function Landing({ onStart }) {
  return (
    <div className="bp-content fadein">
      <div className="bp-wrap" style={{ paddingBottom: 24 }}>
        {/* hero */}
        <div style={{ maxWidth: 860, margin: '0 auto', textAlign: 'center' }}>
          <h1 className="gradient-text" style={{
            fontFamily: 'var(--font-display)', fontWeight: 700,
            fontSize: 'clamp(54px, 8vw, 92px)', lineHeight: 0.98, letterSpacing: '-0.01em',
            margin: '16px 0 0',
          }}>
            Book a chat with an<br />EvryStay team member.
          </h1>
          <p style={{ fontSize: 'clamp(18px, 2.4vw, 22px)', lineHeight: 1.45, color: 'var(--ink-900)', margin: '24px auto 0', maxWidth: 620 }}>
            Book for EvryThing. support. onboarding. advice. questions.
          </p>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center', justifyContent: 'center', flexWrap: 'wrap', margin: '34px 0 0' }}>
            <button className="btn btn-lg" onClick={onStart}>
              Book a chat with us <Icon name="arrowR" size={18} stroke={2.4} />
            </button>
            <div style={{ display: 'flex', alignItems: 'center', gap: 9, color: 'var(--ink-500)', fontSize: 14, fontWeight: 600 }}>
              <Icon name="video" size={17} /> Zoom
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* =========================================================== STEP 0 - PORTFOLIO */
function StepPortfolio({ form, set, route }) {
  return (
    <div className="fadein">
      <h2 style={{ fontSize: 23, fontWeight: 700, margin: '0 0 4px' }}>Tell us about your portfolio</h2>
      <p className="muted" style={{ margin: '0 0 18px', fontSize: 14.5 }}>So the chat is built around how you actually operate.</p>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div className="grid2">
          <Field label="Company / brand" required value={form.company} placeholder="e.g. Coastline Stays"
                 onChange={(v) => set({ company: v })} autoComplete="organization" />
          <SelectField label="Current PMS" value={form.pms} options={PMS_OPTIONS}
                       placeholder="Which platform do you use?" onChange={(v) => set({ pms: v })} />
        </div>

        <div className="field">
          <label>How many properties do you manage?<span className="req"> *</span></label>
          <Tiles options={PROPERTY_TIERS} value={form.tier} onChange={(v) => set({ tier: v, ceoRequested: false })} />
        </div>

        {form.tier && (
          <div className="fadein">
            <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink-900)', marginBottom: 11 }}>Who you’ll meet</div>
            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
              {route.hosts.map((h) => (
                <div key={h.id} className="bp-card" style={{ padding: 13, display: 'flex', alignItems: 'center', gap: 12, flex: '1 1 220px', boxShadow: 'var(--shadow-card)' }}>
                  <img src={h.photo} alt={h.name} style={{ width: 48, height: 48, borderRadius: 14, objectFit: 'cover', objectPosition: 'center top' }} />
                  <div>
                    <div style={{ fontWeight: 700, fontSize: 14.5 }}>{h.name}</div>
                    <div style={{ color: 'var(--purple-600)', fontWeight: 600, fontSize: 12.5 }}>{h.role}</div>
                  </div>
                </div>
              ))}
            </div>
            <div style={{ fontSize: 13, color: 'var(--ink-500)', lineHeight: 1.45, marginTop: 11 }}>{route.note}</div>
          </div>
        )}

        {form.tier && route.canRequestCeo && (
          <div className="bp-card fadein" style={{ padding: 18, display: 'flex', gap: 14, alignItems: 'center', background: 'var(--bg-soft)', borderColor: 'var(--purple-200)' }}>
            <img src={TEAM.frazer.photo} alt="Frazer King" style={{ width: 46, height: 46, borderRadius: 13, objectFit: 'cover', objectPosition: 'center top' }} />
            <div style={{ flex: 1 }}>
              <div style={{ fontWeight: 700, fontSize: 14.5 }}>Want our CEO in the room?</div>
              <div className="muted" style={{ fontSize: 13, lineHeight: 1.45 }}>If Frazer’s available at your chosen time, he’ll join you and Ivan.</div>
            </div>
            <Toggle id="ceo" checked={!!form.ceoRequested} onChange={(v) => set({ ceoRequested: v })} />
          </div>
        )}
      </div>
    </div>
  );
}

/* =========================================================== STEP 1 - TIME */
function StepTime({ intent, form, route }) {
  const frameSrc = useMemo(() => schedulerUrl(intent, form, route), [intent, form, route]);
  return (
    <div className="scheduler-shell fadein">
      <div className="scheduler-head">
        <div className="scheduler-pill"><Icon name="calendar" size={16} /> Pick a time</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
          <AvatarStack people={route.hosts} size={26} />
          <span style={{ fontSize: 13, color: 'var(--ink-500)' }}>
            with {route.hosts.map((h) => h.name).join(' & ')}
            {route.ceoRequested && <em style={{ fontStyle: 'normal', color: 'var(--ink-400)' }}> · Frazer requested, pending his confirmation</em>}
          </span>
        </div>
      </div>

      <div className="scheduler-frame-wrap">
        <iframe
          src={frameSrc}
          title="Chat with EvryStay scheduler"
          frameBorder="0"
          className="scheduler-frame"
        />
      </div>
    </div>
  );
}

/* =========================================================== STEP 2 - DETAILS */
function StepDetails({ form, set }) {
  return (
    <div className="fadein">
      <h2 style={{ fontSize: 23, fontWeight: 700, margin: '0 0 4px' }}>Your details</h2>
      <p className="muted" style={{ margin: '0 0 24px', fontSize: 14.5 }}>We’ll send the calendar invite and Zoom link here.</p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        <Field label="Full name" required value={form.name} placeholder="Your name"
               onChange={(v) => set({ name: v })} autoComplete="name" />
        <div className="grid2">
          <Field label="Work email" required type="email" value={form.email} placeholder="you@company.com"
                 inputMode="email" onChange={(v) => set({ email: v })} autoComplete="email" />
          <Field label="Phone" required type="tel" value={form.phone} placeholder="+61 …"
                 inputMode="tel" onChange={(v) => set({ phone: v })} autoComplete="tel" />
        </div>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', color: 'var(--ink-500)', fontSize: 13, marginTop: 2 }}>
          <Icon name="shield" size={17} style={{ color: 'var(--purple-500)' }} />
          We’ll only use these to set up your chat. No spam, ever.
        </div>
      </div>
    </div>
  );
}

/* =========================================================== CONFIRMATION */
function pad2(n) { return String(n).padStart(2, '0'); }
function slotDates(date, slot) {
  const start = new Date(date.getFullYear(), date.getMonth(), date.getDate(), Math.floor(slot / 60), slot % 60);
  const end = new Date(start.getTime() + 45 * 60000);
  return { start, end };
}
function icsStamp(d) { return '' + d.getFullYear() + pad2(d.getMonth() + 1) + pad2(d.getDate()) + 'T' + pad2(d.getHours()) + pad2(d.getMinutes()) + '00'; }
function buildICS(form, route, date, slot) {
  const { start, end } = slotDates(date, slot);
  const who = route.hosts.map((h) => h.name + ' (' + h.role + ')').join(', ');
  const lines = [
    'BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//EvryStay//Booking//EN', 'BEGIN:VEVENT',
    'UID:' + Date.now() + '@evrystay.com.au',
    'DTSTAMP:' + icsStamp(new Date()),
    'DTSTART:' + icsStamp(start), 'DTEND:' + icsStamp(end),
    'SUMMARY:EvryStay portfolio chat - ' + (form.company || 'your portfolio'),
    'DESCRIPTION:45-minute chat with an EvryStay portfolio expert - ' + who + '. A Zoom link will be emailed to you.',
    'LOCATION:Zoom (link emailed)', 'END:VEVENT', 'END:VCALENDAR',
  ];
  return lines.join('\r\n');
}
function googleCalUrl(form, route, date, slot) {
  const { start, end } = slotDates(date, slot);
  const who = route.hosts.map((h) => h.name).join(' & ');
  const p = new URLSearchParams({
    action: 'TEMPLATE',
    text: 'EvryStay portfolio chat - ' + (form.company || 'your portfolio'),
    dates: icsStamp(start) + '/' + icsStamp(end),
    details: '45-minute chat with an EvryStay portfolio expert - ' + who + '. Zoom link will be emailed.',
    location: 'Zoom',
  });
  return 'https://calendar.google.com/calendar/render?' + p.toString();
}

function Confirmation({ intent, form, route, date, slot, onRestart }) {
  const hasLocalSlot = !!date && slot != null;
  const icsHref = useMemo(() => hasLocalSlot ? 'data:text/calendar;charset=utf-8,' + encodeURIComponent(buildICS(form, route, date, slot)) : '#', [hasLocalSlot, form, route, date, slot]);
  const gcal = useMemo(() => hasLocalSlot ? googleCalUrl(form, route, date, slot) : '#', [hasLocalSlot, form, route, date, slot]);
  return (
    <div className="bp-content fadein">
      <div className="bp-wrap" style={{ maxWidth: 640 }}>
        <div style={{ textAlign: 'center' }}>
          <div style={{ width: 76, height: 76, borderRadius: 24, margin: '0 auto', background: 'var(--evry-gradient)', display: 'grid', placeItems: 'center', color: '#fff', boxShadow: 'var(--shadow-ink)' }}>
            <Icon name="check" size={38} stroke={2.6} />
          </div>
          <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'clamp(30px,5vw,42px)', margin: '22px 0 6px' }}>You’re booked in.</h1>
          <p className="muted" style={{ fontSize: 16, margin: 0 }}>A calendar invite and Zoom link are on their way to <strong style={{ color: 'var(--ink-900)' }}>{form.email || 'your inbox'}</strong>.</p>
        </div>

        <div className="bp-card" style={{ padding: 26, marginTop: 30 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 16, paddingBottom: 18, borderBottom: '1px solid var(--hairline)' }}>
            <AvatarStack people={route.hosts} size={48} />
            <div>
              <div style={{ fontWeight: 700, fontSize: 16 }}>{route.hosts.map((h) => h.name).join(' & ')}</div>
              <div className="muted" style={{ fontSize: 13.5 }}>{route.hosts.map((h) => h.role).join(' · ')}</div>
            </div>
          </div>
          <div style={{ paddingTop: 6 }}>
            {hasLocalSlot ? (
              <>
                <div className="sum-row"><span className="sr-ic"><Icon name="calendar" size={18} /></span><div><div className="sr-k">Date</div><div className="sr-v">{fmtDay(date)}, {date.getFullYear()}</div></div></div>
                <div className="sum-row"><span className="sr-ic"><Icon name="clock" size={18} /></span><div><div className="sr-k">Time</div><div className="sr-v">{fmtTime(slot)}–{fmtTime(slot + 45)} AEST</div></div></div>
              </>
            ) : (
              <div className="sum-row"><span className="sr-ic"><Icon name="calendar" size={18} /></span><div><div className="sr-k">Calendar</div><div className="sr-v">Managed by Zoom Scheduler</div></div></div>
            )}
            <div className="sum-row"><span className="sr-ic"><Icon name="video" size={18} /></span><div><div className="sr-k">Where</div><div className="sr-v">Zoom - link emailed</div></div></div>
            {intent === 'demo' ? (
              <div className="sum-row"><span className="sr-ic"><Icon name="building" size={18} /></span><div><div className="sr-k">Portfolio</div><div className="sr-v">{form.company} · {(PROPERTY_TIERS.find((t) => t.id === form.tier) || {}).k}{form.tier !== 'hotel' ? ' properties' : ''}</div></div></div>
            ) : (
              <div className="sum-row"><span className="sr-ic"><Icon name="spark" size={18} /></span><div><div className="sr-k">Reason</div><div className="sr-v">{intent === 'invited' ? 'Invited by ' + route.hosts[0].name : 'Support call'}</div></div></div>
            )}
            {route.ceoRequested && (
              <div className="sum-row"><span className="sr-ic"><Icon name="crown" size={18} /></span><div><div className="sr-k">CEO requested</div><div className="sr-v">We’ve asked Frazer to join - pending his confirmation</div></div></div>
            )}
          </div>
          {hasLocalSlot && (
            <div style={{ display: 'flex', gap: 12, marginTop: 20, flexWrap: 'wrap' }}>
              <a className="btn" href={gcal} target="_blank" rel="noreferrer"><Icon name="calendar" size={17} /> Add to Google Calendar</a>
              <a className="btn btn-ghost" href={icsHref} download="evrystay-chat.ics"><Icon name="arrowR" size={17} /> Download .ics</a>
            </div>
          )}
        </div>

        <div style={{ textAlign: 'center', marginTop: 28 }}>
          <div className="muted" style={{ fontSize: 13.5, marginBottom: 12 }}>Follow along until then</div>
          <div style={{ display: 'flex', justifyContent: 'center' }}><Socials /></div>
          <button className="linkback" style={{ margin: '26px auto 0', justifyContent: 'center' }} onClick={onRestart}>
            <Icon name="chevL" size={16} /> Book another chat
          </button>
        </div>
      </div>
    </div>
  );
}

/* =========================================================== INTENT SCREEN */
function IntentScreen({ onPick, onBack }) {
  const opts = [
    { id: 'demo',    ic: 'video', t: 'I’m here for a product demo', s: 'See EvryStay run your portfolio - a 45-minute walkthrough with a portfolio expert.' },
    { id: 'invited', ic: 'user',  t: 'I’ve been invited to book by an EvryStay team member', s: 'Already spoke with someone on the team? Book straight into their calendar.' },
    { id: 'support', ic: 'spark', t: 'I’m here for support', s: 'Got a question about your account? Message Ivan or grab a quick morning call.' },
  ];
  return (
    <div className="bp-content fadein">
      <div className="bp-wrap" style={{ maxWidth: 760 }}>
        <button className="linkback" onClick={onBack} style={{ marginBottom: 16 }}>
          <Icon name="chevL" size={16} /> Back
        </button>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'clamp(30px,5vw,46px)', lineHeight: 1.05, letterSpacing: '-0.01em', margin: '0 0 8px' }}>What brings you in?</h1>
        <p className="muted" style={{ fontSize: 16, margin: 0 }}>Pick one so we point you to the right person.</p>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginTop: 26 }}>
          {opts.map((o) => (
            <button key={o.id} type="button" className="bp-card intent-card" onClick={() => onPick(o.id)}>
              <span className="ic"><Icon name={o.ic} size={22} /></span>
              <span style={{ flex: 1 }}>
                <span style={{ display: 'block', fontWeight: 700, fontSize: 16.5, color: 'var(--ink-900)' }}>{o.t}</span>
                <span className="muted" style={{ display: 'block', fontSize: 13.5, lineHeight: 1.45, marginTop: 3 }}>{o.s}</span>
              </span>
              <span className="chev"><Icon name="chevR" size={20} /></span>
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

/* =========================================================== STEP - WHO INVITED YOU */
function StepInviter({ form, set }) {
  return (
    <div className="fadein">
      <h2 style={{ fontSize: 23, fontWeight: 700, margin: '0 0 4px' }}>Who invited you?</h2>
      <p className="muted" style={{ margin: '0 0 18px', fontSize: 14.5 }}>Pick whoever you’ve been talking to - we’ll show you their availability.</p>
      <div className="grid2">
        {[TEAM.ivan, TEAM.frazer].map((p) => {
          const sel = form.inviter === p.id;
          return (
            <button key={p.id} type="button" onClick={() => set({ inviter: p.id })}
              className="bp-card" style={{
                padding: 14, display: 'flex', flexDirection: 'column', gap: 10, cursor: 'pointer', textAlign: 'left', position: 'relative',
                borderColor: sel ? 'var(--purple-600)' : 'var(--border)',
                boxShadow: sel ? 'inset 0 0 0 1px var(--purple-600)' : 'var(--shadow-card)',
                background: sel ? 'var(--purple-50)' : 'var(--bg)',
              }}>
              <img src={p.photo} alt={p.name} style={{ width: 64, height: 64, borderRadius: 16, objectFit: 'cover', objectPosition: 'center top' }} />
              <div>
                <div style={{ fontWeight: 700, fontSize: 16 }}>{p.name}</div>
                <div style={{ color: 'var(--purple-600)', fontWeight: 600, fontSize: 13 }}>{p.role}</div>
              </div>
              {sel && <span style={{ position: 'absolute', top: 14, right: 14, color: 'var(--purple-600)' }}><Icon name="checkCircle" size={22} /></span>}
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* =========================================================== STEP - SUPPORT */
function StepSupport({ onBook }) {
  return (
    <div className="fadein">
      <h2 style={{ fontSize: 23, fontWeight: 700, margin: '0 0 4px' }}>How can we help?</h2>
      <p className="muted" style={{ margin: '0 0 22px', fontSize: 14.5 }}>Quick question? Message Ivan on WhatsApp. Prefer to talk it through? Grab a short morning call.</p>
      <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap' }}>
        <a className="btn btn-wa btn-lg" href="https://wa.me/61439758079" target="_blank" rel="noreferrer" style={{ flex: '1 1 220px' }}>
          <Icon name="whatsapp" size={20} /> Text Ivan
        </a>
        <button className="btn btn-lg" onClick={onBook} style={{ flex: '1 1 220px' }}>
          <Icon name="phone" size={18} /> Book a call with Ivan
        </button>
      </div>
      <div className="bp-card" style={{ marginTop: 18, padding: 14, display: 'flex', alignItems: 'center', gap: 12, boxShadow: 'var(--shadow-card)' }}>
        <img src={TEAM.ivan.photo} alt="Ivan Vargas" style={{ width: 46, height: 46, borderRadius: 13, objectFit: 'cover', objectPosition: 'center top' }} />
        <div>
          <div style={{ fontWeight: 700, fontSize: 14.5 }}>Ivan Vargas · Head of Customer</div>
          <div className="muted" style={{ fontSize: 13 }}>Call slots: mornings 10:00–1:00pm AEST · 15 min</div>
        </div>
      </div>
    </div>
  );
}

/* =========================================================== WIZARD */
function Wizard({ intent, form, set, state, patch, onStep, onConfirm, onExit }) {
  const flow = INTENT_FLOW[intent] || INTENT_FLOW.demo;
  const route = useMemo(() => buildRoute(intent, form), [intent, form.tier, form.ceoRequested, form.inviter]);
  const step = Math.min(state.step, flow.steps.length - 1);
  const stepName = flow.steps[step];
  const isSchedulerStep = stepName === 'time';

  const valid = {
    portfolio: !!(form.company && form.tier),
    inviter: !!form.inviter,
    support: false,
    time: true,
    details: !!(form.name && form.email && form.phone),
  };
  const canNext = valid[stepName];
  const isLast = step === flow.steps.length - 1;
  const showNext = stepName !== 'support' && stepName !== 'time';

  const next = () => { if (!isLast) onStep(step + 1); else onConfirm(); };
  const back = () => { if (step === 0) onExit(); else onStep(step - 1); };

  return (
    <div className="bp-content">
      <div className="bp-wrap">
        <button className="linkback" onClick={back} style={{ marginBottom: isSchedulerStep ? 6 : 10 }}>
          <Icon name="chevL" size={16} /> Back
        </button>
        <div style={{ maxWidth: isSchedulerStep ? 1040 : 720, margin: '0 auto' }}>
          <div className={isSchedulerStep ? '' : 'bp-card'} style={isSchedulerStep ? undefined : { padding: 'clamp(18px, 2.4vw, 28px)' }}>
            {!isSchedulerStep && <div style={{ marginBottom: 18 }}><Stepper step={step} labels={flow.labels} /></div>}

            {stepName === 'portfolio' && <StepPortfolio form={form} set={set} route={route} />}
            {stepName === 'inviter' && <StepInviter form={form} set={set} />}
            {stepName === 'support' && <StepSupport onBook={() => onStep(step + 1)} />}
            {stepName === 'time' && <StepTime intent={intent} form={form} route={route} />}
            {stepName === 'details' && <StepDetails form={form} set={set} />}

            {!isSchedulerStep && (
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 14, marginTop: 22, paddingTop: 16, borderTop: '1px solid var(--hairline)' }}>
                <button className="linkback" onClick={back}>{step === 0 ? 'Cancel' : 'Back'}</button>
                {showNext && (
                  <button className="btn" onClick={next} disabled={!canNext}>
                    {isLast ? <>Confirm booking <Icon name="check" size={17} stroke={2.4} /></> : <>Continue <Icon name="arrowR" size={17} stroke={2.4} /></>}
                  </button>
                )}
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

/* =========================================================== APP */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const saved = useRef(loadState());
  const s0 = saved.current || {};

  const initialRoute = routeFromPath(window.location.pathname);
  const [view, setView] = useState(initialRoute.view || s0.view || 'landing'); // landing | intent | wizard | done
  const [intent, setIntent] = useState(initialRoute.intent || s0.intent || 'demo'); // demo | invited | support
  const [form, setForm] = useState(s0.form || { company: '', pms: '', tier: '', ceoRequested: false, inviter: '', name: '', email: '', phone: '' });
  const [state, setState] = useState({
    step: initialRoute.step != null ? initialRoute.step : (s0.step || 0),
    month: s0.month || new Date(TODAY.getFullYear(), TODAY.getMonth(), 1),
    date: s0.date || null,
    slot: (s0.slot === 0 || s0.slot) ? s0.slot : null,
  });

  const applyRoute = (route) => {
    setView(route.view);
    if (route.intent) setIntent(route.intent);
    if (route.step != null) setState((st) => ({ ...st, step: route.step, date: null, slot: null }));
  };

  const navigate = (path) => {
    if (window.location.pathname !== path) window.history.pushState({}, '', path);
    applyRoute(routeFromPath(path));
    window.scrollTo({ top: 0 });
  };

  useEffect(() => {
    const onPop = () => applyRoute(routeFromPath(window.location.pathname));
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  // persist
  useEffect(() => {
    const payload = {
      view, intent, form, step: state.step, slot: state.slot,
      dateISO: state.date ? state.date.toISOString() : null,
      monthISO: state.month ? state.month.toISOString() : null,
    };
    try { localStorage.setItem(STORE_KEY, JSON.stringify(payload)); } catch (e) {}
  }, [view, intent, form, state]);

  const set = (patchObj) => setForm((f) => ({ ...f, ...patchObj }));
  const patch = (patchObj) => setState((st) => ({ ...st, ...patchObj }));

  const goIntent = () => navigate('/book');
  const pickIntent = (id) => navigate(pathForWizard(id, 0));
  const goWizardStep = (step) => navigate(pathForWizard(intent, step));
  const confirm = () => navigate('/done');
  const restart = () => {
    setIntent('demo');
    setForm({ company: '', pms: '', tier: '', ceoRequested: false, inviter: '', name: '', email: '', phone: '' });
    setState({ step: 0, month: new Date(TODAY.getFullYear(), TODAY.getMonth(), 1), date: null, slot: null });
    navigate('/');
  };

  const route = buildRoute(intent, form);

  return (
    <div className="bp-app" data-layout={t.layout} data-surface={t.surface} data-buttons={t.buttons} data-view={view}
         style={{ '--purple-600': t.accent }}>
      {/* top bar */}
      <header className="bp-bar">
        <button onClick={restart} style={{ border: 0, background: 'none', cursor: 'pointer', padding: 0, display: 'flex' }}>
          <Logo height={26} />
        </button>
        <div className="bar-right">
          {view === 'landing' && <button className="btn" style={{ padding: '11px 18px', fontSize: 14 }} onClick={goIntent}>Book a chat</button>}
        </div>
      </header>

      {view === 'landing' && <Landing onStart={goIntent} />}
      {view === 'intent' && <IntentScreen onPick={pickIntent} onBack={() => navigate('/')} />}
      {view === 'wizard' && <Wizard intent={intent} form={form} set={set} state={state} patch={patch} onStep={goWizardStep} onConfirm={confirm} onExit={() => navigate('/book')} />}
      {view === 'done' && <Confirmation intent={intent} form={form} route={route} date={state.date} slot={state.slot} onRestart={restart} />}

      {/* footer */}
      <footer className="footer">
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
          <Logo height={20} />
          <span className="f-legal">© 2026 Evrystay Pty Ltd · Mornington, Australia</span>
        </div>
        <Socials size={38} />
      </footer>

      {/* Tweaks */}
      <TweaksPanel>
        <TweakSection label="Layout" />
        <TweakRadio label="Background" value={t.surface} options={['gradient', 'tint']}
                    onChange={(v) => setTweak('surface', v)} />
        <TweakSection label="Brand" />
        <TweakRadio label="Buttons" value={t.buttons} options={['gradient', 'solid']}
                    onChange={(v) => setTweak('buttons', v)} />
        <TweakColor label="Accent" value={t.accent}
                    options={['#6858F9', '#9589FF', '#7A5AE0', '#2C6E8E']}
                    onChange={(v) => setTweak('accent', v)} />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
