// Step UIs for the onboarding wizard. Each step reads from the industry config (cfg)
// and the per-step answers (get/update).

const { useState: useStateOB, useEffect: useEffectOB } = React;

/* Shared atoms ============================================================ */
function Field({ label, hint, children }) {
  return (
    <label style={{ display:'flex', flexDirection:'column', gap:7 }}>
      <span style={{ fontSize:11, fontWeight:700, letterSpacing:'0.12em', textTransform:'uppercase', color:'var(--mute-1)' }}>{label}</span>
      {children}
      {hint && <span style={{ fontSize:12, color:'var(--mute-2)' }}>{hint}</span>}
    </label>
  );
}
function TextInput({ value, onChange, placeholder, prefix, suffix, type='text' }) {
  return (
    <div style={{ display:'flex', alignItems:'center', gap:8, background:'#fff', border:'1.5px solid var(--line)', borderRadius:12, padding:'12px 16px', transition:'border-color 0.15s' }}
      onFocus={e => e.currentTarget.style.borderColor = 'var(--ink)'}
      onBlur={e => e.currentTarget.style.borderColor = 'var(--line)'}
    >
      {prefix && <span style={{ color:'var(--mute-2)', fontFamily:'var(--font-mono)', fontSize:14 }}>{prefix}</span>}
      <input type={type} value={value ?? ''} onChange={e => onChange(type === 'number' ? Number(e.target.value || 0) : e.target.value)}
        placeholder={placeholder}
        style={{ flex:1, border:0, outline:0, background:'transparent', fontFamily:'var(--font-body)', fontSize:15, color:'var(--ink)', minWidth:0 }}/>
      {suffix && <span style={{ color:'var(--mute-2)', fontFamily:'var(--font-mono)', fontSize:12 }}>{suffix}</span>}
    </div>
  );
}
function SelectInput({ value, onChange, options }) {
  return (
    <select value={value ?? ''} onChange={e => onChange(e.target.value)}
      style={{ background:'#fff', border:'1.5px solid var(--line)', borderRadius:12, padding:'12px 16px', fontFamily:'var(--font-body)', fontSize:15, color:'var(--ink)', outline:0 }}>
      <option value="">— select —</option>
      {options.map(o => <option key={o} value={o}>{o}</option>)}
    </select>
  );
}
function Toggle({ value, onChange, label }) {
  return (
    <button onClick={() => onChange(!value)} style={{
      display:'flex', alignItems:'center', gap:10, background: value ? 'var(--chart-100)' : '#fff',
      border:'1.5px solid ' + (value ? 'var(--chart-400)' : 'var(--line)'),
      borderRadius:12, padding:'10px 14px', fontFamily:'var(--font-body)', fontSize:13.5, fontWeight:600, color:'var(--ink)',
      cursor:'pointer', transition:'all 0.15s', textAlign:'left',
    }}>
      <span style={{ width:18, height:18, borderRadius:5, background: value ? 'var(--ink)' : 'var(--paper-3)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
        {value && <IconCheck size={11} stroke="var(--chart-300)" sw={3}/>}
      </span>
      <span>{label}</span>
    </button>
  );
}
function CardSection({ title, hint, children, accent }) {
  return (
    <section className="ob-card" style={{ background:'#fff', borderRadius:20, padding:'30px 32px', border:'1px solid var(--line)', boxShadow:'0 1px 0 rgba(0,0,0,0.02)' }}>
      <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:hint ? 4 : 18 }}>
        <span style={{ width:8, height:8, borderRadius:99, background: accent || 'var(--chart-300)' }}/>
        <h3 className="display" style={{ fontSize:22, fontWeight:600, letterSpacing:'-0.025em', margin:0 }}>{title}</h3>
      </div>
      {hint && <p style={{ fontSize:13, color:'var(--mute-1)', marginTop:0, marginBottom:18 }}>{hint}</p>}
      {children}
    </section>
  );
}

/* 1. WELCOME ============================================================ */
function StepWelcome({ cfg, get, update, prefillAll }) {
  const [psState, setPsState] = useStateOB('idle'); // idle | searching | found | dismissed
  const [psLabel, setPsLabel] = useStateOB('');
  const firedRef = React.useRef('');

  useEffectOB(() => {
    const company = get('company') || '';
    const city    = get('city')    || '';
    if (!company || company.length < 3 || !city) return;
    const key = `${company}|${city}`;
    if (key === firedRef.current || psState === 'searching') return;

    const t = setTimeout(async () => {
      firedRef.current = key;
      setPsState('searching');
      try {
        const res = await fetch('/api/prefill', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            bizName: company,
            city,
            trade: cfg?.cat || cfg?.serviceName || '',
            phone: get('phone') || '',
            email: get('email') || '',
          }),
        });
        if (!res.ok) { setPsState('idle'); return; }
        const data = await res.json();
        if (!data.ok || !data.prefill) { setPsState('idle'); return; }

        const pf = data.prefill;

        // Apply welcome fields — only empty slots
        const wPatch = {};
        for (const [k, v] of Object.entries(pf.welcome || {})) {
          if (v != null && !get(k)) wPatch[k] = v;
        }
        if (Object.keys(wPatch).length) update(wPatch);

        // Stash certs / services / voice for downstream steps
        if (prefillAll) {
          const other = {};
          if (Object.keys(pf.certs    || {}).length) other.certs    = pf.certs;
          if (Object.keys(pf.services || {}).length) other.services = pf.services;
          if (Object.keys(pf.voice    || {}).length) other.voice    = pf.voice;
          if (Object.keys(other).length) prefillAll(other);
        }

        const src = pf.meta?.website_url || pf.meta?.gmb_url || company;
        const count = Object.keys(wPatch).length +
          Object.keys(pf.certs || {}).length +
          Object.keys(pf.services || {}).length;
        setPsLabel(`${count} field${count !== 1 ? 's' : ''} filled from ${src}`);
        setPsState(count > 0 ? 'found' : 'idle');
      } catch { setPsState('idle'); }
    }, 900);

    return () => clearTimeout(t);
  }, [get('company'), get('city')]);

  return (
    <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:20 }}>
      <CardSection title="Company basics" hint="What's printed on the truck.">
        {/* Prefill status banner */}
        {psState === 'searching' && (
          <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:16, padding:'10px 14px', background:'var(--paper-3)', borderRadius:10, border:'1px solid var(--line-2)', fontSize:13, color:'var(--mute-1)' }}>
            <span style={{ display:'inline-block', animation:'spin 1.2s linear infinite', fontSize:14 }}>⟳</span>
            Searching for your business online…
          </div>
        )}
        {psState === 'found' && (
          <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:16, padding:'10px 14px', background:'var(--chart-100)', borderRadius:10, border:'1px solid var(--chart-400)', fontSize:13 }}>
            <span style={{ fontSize:14 }}>✓</span>
            <span style={{ flex:1, color:'var(--chart-900)', fontWeight:500 }}>{psLabel}</span>
            <button onClick={() => setPsState('dismissed')} style={{ background:'transparent', border:0, cursor:'pointer', color:'var(--mute-2)', fontSize:16, lineHeight:1 }}>×</button>
          </div>
        )}
        <div style={{ display:'flex', flexDirection:'column', gap:18 }}>
          <Field label="Your name" hint="We'll sign outgoing messages with this."><TextInput value={get('ownerName')} onChange={v => update({ ownerName:v })} placeholder="Jordan Chapman"/></Field>
          <Field label="Legal company name"><TextInput value={get('company')} onChange={v => update({ company:v })} placeholder="Cardinal Roofing LLC"/></Field>
          <Field label="DBA / what customers see"><TextInput value={get('dba')} onChange={v => update({ dba:v })} placeholder="Cardinal Roofing"/></Field>
          <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
            <Field label="Primary city"><TextInput value={get('city')} onChange={v => update({ city:v })} placeholder="Tampa"/></Field>
            <Field label="State"><TextInput value={get('state')} onChange={v => update({ state:v })} placeholder="FL"/></Field>
          </div>
          <Field label="Service radius" hint="Miles from your shop."><TextInput type="number" value={get('radius', 30)} onChange={v => update({ radius:v })} suffix="miles"/></Field>
          <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
            <Field label="Work email" hint="We'll reach out here."><TextInput type="text" value={get('email')} onChange={v => update({ email:v })} placeholder="you@cardinalroof.com"/></Field>
            <Field label="Mobile phone"><TextInput type="text" value={get('phone')} onChange={v => update({ phone:v })} placeholder="(813) 555-0198"/></Field>
          </div>
        </div>
      </CardSection>

      <CardSection title="Crew + footprint" hint="Sizing the system to your team.">
        <div style={{ display:'flex', flexDirection:'column', gap:18 }}>
          <Field label="Year established"><TextInput type="number" value={get('founded')} onChange={v => update({ founded:v })} placeholder="2014"/></Field>
          <Field label="Field crew"><SelectInput value={get('crew')} onChange={v => update({ crew:v })} options={['1–3 techs','4–8 techs','9–15 techs','16+ techs']}/></Field>
          <Field label="Office staff"><SelectInput value={get('office')} onChange={v => update({ office:v })} options={['Just me','1–2 people','3–5 people','6+']}/></Field>
          <Field label="License #" hint="State contractor's license."><TextInput value={get('license')} onChange={v => update({ license:v })} placeholder="CCC1330218"/></Field>
        </div>
      </CardSection>

      <div style={{ gridColumn:'1 / -1' }}>
        <CardSection title="Your trade · confirmed" hint={`The whole system will be configured for ${cfg.serviceName.toLowerCase()} work. Anything off?`} accent="var(--lilac-500)">
          <div style={{ display:'flex', alignItems:'center', gap:14, padding:'14px 18px', background:'var(--ink)', borderRadius:14, color:'#fff' }}>
            <div style={{ width:42, height:42, borderRadius:12, background:'var(--chart-300)', color:'var(--ink)', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'var(--font-display)', fontWeight:800, fontSize:18 }}>
              {cfg.serviceName.slice(0,1)}
            </div>
            <div style={{ flex:1 }}>
              <div style={{ fontSize:10, fontWeight:700, letterSpacing:'0.12em', color:'var(--chart-300)' }}>{(cfg.industryLabel || cfg.serviceName).toUpperCase()}</div>
              <div className="display" style={{ fontSize:20, fontWeight:600, letterSpacing:'-0.025em', marginTop:2 }}>{cfg.serviceName}</div>
              <div style={{ fontSize:11, color:'rgba(255,255,255,0.55)', marginTop:2 }}>
                {cfg.estimateFields.length} default fields · {cfg.leadQs.length} intake questions · {cfg.partners.length} supported partners
              </div>
            </div>
          </div>
        </CardSection>
      </div>
    </div>
  );
}

/* 2. SERVICES (sub-trades) ============================================================ */
function StepServices({ cfg, get, update }) {
  const selected = get('subTrades', cfg.subTrades.slice(0, Math.min(4, cfg.subTrades.length)));
  const setSel = (sub) => {
    const next = selected.includes(sub) ? selected.filter(s => s !== sub) : [...selected, sub];
    update({ subTrades: next });
  };
  return (
    <div>
      <CardSection title={`${cfg.industryLabel || cfg.serviceName} sub-trades`} hint="Pick everything you'd quote on a normal week. We won't price what you don't sell." accent="var(--chart-400)">
        <div className="ob-grid-3col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:8 }}>
          {cfg.subTrades.map((s, i) => (
            <Toggle key={s} value={selected.includes(s)} onChange={() => setSel(s)} label={s}/>
          ))}
        </div>
      </CardSection>

      <div className="ob-grid-2col" style={{ marginTop:18, display:'grid', gridTemplateColumns:'1fr 1fr', gap:18 }}>
        <CardSection title="Service ratio" hint="Roughly how does your week split?">
          <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
            {[
              ['Residential',  'residentialPct', 70],
              ['Commercial',   'commercialPct',  20],
              ['Insurance / claim work',  'insurancePct',   10],
            ].map(([label, key, def]) => (
              <Slider key={key} label={label} value={get(key, def)} onChange={v => update({ [key]: v })}/>
            ))}
          </div>
        </CardSection>

        <CardSection title="Preferred materials" hint="The brands you actually install. The system filters quotes to these.">
          {cfg.materials.length === 0 ? (
            <div style={{ padding:'22px 18px', background:'var(--paper-3)', borderRadius:10, fontSize:13, color:'var(--mute-1)' }}>This trade doesn't use a materials catalog. Skip.</div>
          ) : (
            <div style={{ display:'flex', flexWrap:'wrap', gap:6 }}>
              {cfg.materials.map(m => {
                const list = get('materials', cfg.materials.slice(0,3));
                const sel = list.includes(m);
                return (
                  <button key={m} onClick={() => update({ materials: sel ? list.filter(x=>x!==m) : [...list, m] })}
                    style={{ background: sel ? 'var(--ink)' : '#fff', color: sel ? 'var(--chart-300)' : 'var(--ink)',
                      border:'1px solid '+(sel ? 'var(--ink)' : 'var(--line)'),
                      padding:'7px 13px', borderRadius:99, fontSize:12.5, fontWeight:600, cursor:'pointer', fontFamily:'var(--font-body)' }}>
                    {m}
                  </button>
                );
              })}
            </div>
          )}
        </CardSection>
      </div>
    </div>
  );
}

function Slider({ label, value, onChange }) {
  return (
    <div>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
        <span style={{ fontSize:13.5, fontWeight:600 }}>{label}</span>
        <span style={{ fontFamily:'var(--font-mono)', fontSize:13, color:'var(--ink)' }}>{value}%</span>
      </div>
      <input type="range" min="0" max="100" value={value} onChange={e => onChange(Number(e.target.value))}
        style={{ width:'100%', marginTop:6, accentColor:'var(--ink)' }}/>
    </div>
  );
}

/* 3. PRICING ============================================================ */
function StepPricing({ cfg, get, update }) {
  const ex = cfg.pricingExample;
  return (
    <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1.2fr 1fr', gap:20 }}>
      <CardSection title="Labor + materials" hint="Your floor. The engine adjusts ABOVE this based on live signals — never below.">
        <div style={{ display:'flex', flexDirection:'column', gap:18 }}>
          <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
            <Field label="Burdened labor rate" hint="What it costs you fully loaded — per crew, per hour.">
              <TextInput type="number" value={get('rate', ex.rate)} onChange={v => update({ rate:v })} prefix="$" suffix="/ hr"/>
            </Field>
            <Field label="Material markup" hint="Default markup on materials at quote.">
              <TextInput type="number" value={get('markup', ex.markup)} onChange={v => update({ markup:v })} suffix="%"/>
            </Field>
          </div>
          <Field label="Margin floor" hint="Quote will never go below this margin, no matter the signals.">
            <TextInput type="number" value={get('margin', ex.margin)} onChange={v => update({ margin:v })} suffix="%"/>
          </Field>
          <Field label="Default deposit" hint="Collected at signature.">
            <TextInput type="number" value={get('deposit', ex.deposit)} onChange={v => update({ deposit:v })} suffix="% of total"/>
          </Field>
        </div>
      </CardSection>

      <CardSection title="Good · Better · Best" hint="The tier system. The engine quotes all three by default.">
        <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
          {[
            { id:'good',   label:'Good',   uplift:0,  desc:'Baseline materials, standard warranty' },
            { id:'better', label:'Better', uplift:18, desc:'Premium line, 25-yr workmanship' },
            { id:'best',   label:'Best',   uplift:42, desc:'Architectural, lifetime, white-glove' },
          ].map(t => (
            <div key={t.id} style={{ padding:'12px 14px', background:'var(--paper-3)', borderRadius:12, border:'1px solid var(--line-2)' }}>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                <span style={{ fontFamily:'var(--font-display)', fontSize:15, fontWeight:600 }}>{t.label}</span>
                <span style={{ fontFamily:'var(--font-mono)', fontSize:12, color:'var(--lilac-700)' }}>+{t.uplift}%</span>
              </div>
              <div style={{ fontSize:12, color:'var(--mute-1)', marginTop:4 }}>{t.desc}</div>
            </div>
          ))}
        </div>
      </CardSection>

      <div style={{ gridColumn:'1 / -1' }}>
        <CardSection title="Add-on rates" hint="Quick-add items the engine should always price separately." accent="var(--lilac-500)">
          <div className="ob-grid-4col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr 1fr', gap:10 }}>
            {[
              ['Emergency uplift','emergencyUp', 35, '%'],
              ['Travel · per mi', 'travel',      2,  '$/mi'],
              ['After-hours rate','afterHours',  185,'$/hr'],
              ['Permit fee handling','permitFee', 12, '%'],
            ].map(([label, key, def, suf]) => (
              <Field key={key} label={label}>
                <TextInput type="number" value={get(key, def)} onChange={v => update({ [key]:v })} suffix={suf}/>
              </Field>
            ))}
          </div>
        </CardSection>
      </div>
    </div>
  );
}

/* 4. ESTIMATE FIELDS ============================================================ */
function StepFields({ cfg, get, update }) {
  const fields = get('fields', cfg.estimateFields);
  const setFields = (next) => update({ fields: next });
  return (
    <div>
      <CardSection title={`${cfg.industryLabel || cfg.serviceName} estimate form`}
        hint="We pre-loaded the defaults your trade actually uses. Reorder, toggle off, or add custom fields." accent="var(--chart-400)">
        <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
          {fields.map((f, i) => (
            <div key={f.id} style={{ display:'flex', alignItems:'center', gap:14, padding:'14px 16px', background:'var(--paper-3)', borderRadius:12, border:'1px solid var(--line-2)' }}>
              <span style={{ fontFamily:'var(--font-mono)', fontSize:11, color:'var(--mute-2)', width:28 }}>{String(i+1).padStart(2,'0')}</span>
              <span style={{ width:8, height:8, borderRadius:99, background:'var(--chart-400)' }}/>
              <div style={{ flex:1 }}>
                <div style={{ fontSize:15, fontWeight:600 }}>{f.name}</div>
                {f.opts && <div style={{ fontSize:11, color:'var(--mute-1)', marginTop:2 }}>{f.opts.slice(0,4).join(' · ')}{f.opts.length > 4 ? '…' : ''}</div>}
              </div>
              <span style={{ fontSize:10, color:'var(--mute-2)', background:'#fff', padding:'4px 10px', borderRadius:99, fontFamily:'var(--font-mono)' }}>{f.kind}</span>
              <button onClick={() => setFields(fields.filter(x => x.id !== f.id))} style={{ background:'transparent', border:0, color:'var(--mute-2)', cursor:'pointer', fontSize:18, lineHeight:1 }}>×</button>
            </div>
          ))}
          <button onClick={() => setFields([...fields, { id:`custom-${Date.now()}`, name:'Custom field', kind:'text' }])}
            style={{ marginTop:6, padding:'12px 16px', background:'transparent', border:'1.5px dashed var(--mute-3)', borderRadius:12, fontFamily:'var(--font-body)', fontSize:13, fontWeight:600, color:'var(--mute-1)', cursor:'pointer' }}>
            + Add custom field
          </button>
        </div>
      </CardSection>
    </div>
  );
}

/* 5. HISTORY (file upload) ============================================================ */
function StepHistory({ cfg, get, update }) {
  const uploaded = get('uploaded', cfg.sampleJobs.map((j, i) => ({ id:`job-${i}`, name:`Job-${100+i}.pdf`, size: `${Math.round(120 + Math.random()*180)} KB`, scope: j.scope, amt: j.amt, won: j.won })));
  return (
    <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1.2fr 1fr', gap:20 }}>
      <CardSection title="Drop your last 50 jobs" hint="PDFs, photos, invoices, screenshots, exports from your old tool — anything works. The AI learns your house style.">
        <div style={{ padding:'40px 24px', background:'var(--paper-3)', border:'2px dashed var(--mute-3)', borderRadius:18, textAlign:'center', cursor:'pointer' }}
          onDragOver={e => e.preventDefault()}
          onDrop={e => { e.preventDefault(); }}>
          <div style={{ fontSize:32, color:'var(--lilac-500)', marginBottom:10 }}>⤓</div>
          <div style={{ fontFamily:'var(--font-display)', fontSize:18, fontWeight:600, letterSpacing:'-0.02em' }}>Drop files here or click to browse</div>
          <div style={{ fontSize:12, color:'var(--mute-1)', marginTop:6 }}>PDF, JPG, PNG, CSV — up to 200MB total. We process privately and never share.</div>
          <button onClick={() => update({ uploaded: [...uploaded, { id:`job-${Date.now()}`, name:`Job-${100+uploaded.length}.pdf`, size:`${Math.round(120 + Math.random()*180)} KB`, scope:'Custom upload', amt:'—', won:true }] })}
            style={{ marginTop:18, background:'var(--ink)', color:'var(--chart-300)', border:0, padding:'10px 20px', borderRadius:99, fontFamily:'var(--font-body)', fontWeight:600, fontSize:13, cursor:'pointer' }}>
            Add a sample file
          </button>
        </div>

        <div style={{ marginTop:18 }}>
          <div className="eyebrow" style={{ color:'var(--mute-1)', marginBottom:10 }}>Or paste a link to a folder</div>
          <TextInput placeholder="dropbox.com/… · drive.google.com/… · onedrive.live.com/…" value={get('folder')} onChange={v => update({ folder:v })}/>
        </div>
      </CardSection>

      <CardSection title={`Jobs in library · ${uploaded.length}`} hint="The AI uses these as training data. Mark the won/lost so we learn what closes.">
        <div style={{ display:'flex', flexDirection:'column', gap:6, maxHeight:420, overflowY:'auto' }}>
          {uploaded.map((j, i) => (
            <div key={j.id} style={{ padding:'10px 12px', background:'var(--paper-3)', borderRadius:10, border:'1px solid var(--line-2)' }}>
              <div style={{ display:'flex', alignItems:'center', gap:10 }}>
                <span style={{ width:30, height:30, borderRadius:7, background:'var(--lilac-100)', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--lilac-700)', fontSize:11, fontWeight:800, fontFamily:'var(--font-mono)' }}>PDF</span>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontSize:12.5, fontWeight:600, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{j.name}</div>
                  <div style={{ fontSize:10.5, color:'var(--mute-1)' }}>{j.scope} · {j.size}</div>
                </div>
                <span style={{ fontSize:11, fontFamily:'var(--font-mono)', color:'var(--ink)' }}>{j.amt}</span>
              </div>
              <div style={{ marginTop:6, display:'flex', gap:6 }}>
                <button onClick={() => { uploaded[i] = { ...j, won:true };  update({ uploaded: [...uploaded] }); }}
                  style={{ background: j.won ? 'var(--chart-300)' : '#fff', color: j.won ? 'var(--ink)' : 'var(--mute-1)', border:'1px solid '+(j.won?'var(--chart-400)':'var(--line)'), padding:'4px 10px', borderRadius:99, fontSize:10.5, fontWeight:700, cursor:'pointer', letterSpacing:'0.05em' }}>WON</button>
                <button onClick={() => { uploaded[i] = { ...j, won:false }; update({ uploaded: [...uploaded] }); }}
                  style={{ background: j.won===false ? 'var(--ink)' : '#fff', color: j.won===false ? '#fff' : 'var(--mute-1)', border:'1px solid '+(j.won===false?'var(--ink)':'var(--line)'), padding:'4px 10px', borderRadius:99, fontSize:10.5, fontWeight:700, cursor:'pointer', letterSpacing:'0.05em' }}>LOST</button>
              </div>
            </div>
          ))}
        </div>
      </CardSection>
    </div>
  );
}

/* 6. INTAKE (lead questions) ============================================================ */
function StepIntake({ cfg, get, update }) {
  const qs = get('qs', cfg.leadQs);
  const setQs = (next) => update({ qs: next });
  return (
    <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1.5fr 1fr', gap:20, alignItems:'flex-start' }}>
      <CardSection title="The questions your AI asks every new lead" hint="These run in the chat the moment a lead lands. Toggle off anything you don't want asked." accent="var(--chart-400)">
        <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
          {qs.map((q, i) => (
            <div key={q.id} style={{ display:'flex', alignItems:'center', gap:12, padding:'13px 14px', background: q.on ? '#fff' : 'var(--paper-3)', borderRadius:12, border:'1px solid '+(q.on ? 'var(--line)' : 'transparent'), opacity: q.on ? 1 : 0.62 }}>
              <button onClick={() => { qs[i] = { ...q, on:!q.on }; setQs([...qs]); }}
                style={{ width:36, height:20, borderRadius:99, background: q.on ? 'var(--ink)' : 'var(--mute-3)', border:0, cursor:'pointer', position:'relative', flexShrink:0 }}>
                <span style={{ position:'absolute', top:2, left: q.on ? 18 : 2, width:16, height:16, borderRadius:99, background: q.on ? 'var(--chart-300)' : '#fff', transition:'left 0.2s' }}/>
              </button>
              <span style={{ fontFamily:'var(--font-mono)', fontSize:10, color:'var(--mute-2)', width:22 }}>{String(i+1).padStart(2,'0')}</span>
              <input value={q.q} onChange={e => { qs[i] = { ...q, q:e.target.value }; setQs([...qs]); }}
                style={{ flex:1, border:0, outline:0, background:'transparent', fontSize:14, fontWeight:500, color:'var(--ink)', fontFamily:'var(--font-body)' }}/>
              <button onClick={() => setQs(qs.filter(x => x.id !== q.id))} style={{ background:'transparent', border:0, color:'var(--mute-3)', cursor:'pointer', fontSize:18, lineHeight:1 }}>×</button>
            </div>
          ))}
          <button onClick={() => setQs([...qs, { id:`q-${Date.now()}`, q:'Custom question…', on:true }])}
            style={{ marginTop:6, padding:'12px 16px', background:'transparent', border:'1.5px dashed var(--mute-3)', borderRadius:12, fontFamily:'var(--font-body)', fontSize:13, fontWeight:600, color:'var(--mute-1)', cursor:'pointer' }}>+ Add a question</button>
        </div>
      </CardSection>

      <CardSection title="Preview" hint="Your live intake, in the customer's view." accent="var(--lilac-500)">
        <div style={{ background:'var(--ink)', borderRadius:18, padding:16, color:'#fff' }}>
          <div style={{ fontSize:10, color:'var(--chart-300)', fontWeight:700, letterSpacing:'0.12em' }}>{cfg.serviceName.toUpperCase()} · LIVE INTAKE</div>
          <div style={{ marginTop:10, display:'flex', flexDirection:'column', gap:6 }}>
            {qs.filter(q => q.on).slice(0,4).map((q, i) => (
              <div key={q.id} style={{ background:'rgba(255,255,255,0.08)', padding:'7px 11px', borderRadius:12, fontSize:11.5, lineHeight:1.4 }}>{q.q}</div>
            ))}
            <div style={{ alignSelf:'flex-end', padding:'7px 11px', background:'var(--chart-300)', color:'var(--ink)', borderRadius:12, fontSize:11.5, fontWeight:600 }}>Just looking, thanks!</div>
            <div style={{ background:'rgba(255,255,255,0.08)', padding:'7px 11px', borderRadius:12, fontSize:11.5 }}>Totally fair — when you're ready, I'm here.</div>
          </div>
        </div>
      </CardSection>
    </div>
  );
}

/* 7. VOICE (AI tone) ============================================================ */
function StepVoice({ cfg, get, update }) {
  const tone = get('tone', 55);
  const use = get('use', cfg.voiceVocab.use);
  const avoid = get('avoid', cfg.voiceVocab.avoid);
  const setUse   = (next) => update({ use: next });
  const setAvoid = (next) => update({ avoid: next });
  return (
    <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:20 }}>
      <CardSection title="Tone of voice" hint="Where on the spectrum does your brand sit?">
        <div style={{ position:'relative', padding:'30px 0 20px' }}>
          <input type="range" min="0" max="100" value={tone} onChange={e => update({ tone: Number(e.target.value) })}
            style={{ width:'100%', accentColor:'var(--ink)' }}/>
          <div style={{ display:'flex', justifyContent:'space-between', marginTop:14, fontSize:13 }}>
            <div style={{ textAlign:'left' }}>
              <div style={{ fontWeight:700 }}>Formal</div>
              <div style={{ color:'var(--mute-1)', fontSize:11 }}>"We'd be happy to assist."</div>
            </div>
            <div style={{ textAlign:'right' }}>
              <div style={{ fontWeight:700 }}>Casual</div>
              <div style={{ color:'var(--mute-1)', fontSize:11 }}>"Hey, let's get this fixed."</div>
            </div>
          </div>
        </div>
        <div style={{ marginTop:14, padding:'14px 16px', background:'var(--chart-100)', borderRadius:12, border:'1px solid var(--chart-300)' }}>
          <div className="eyebrow" style={{ color:'var(--chart-900)' }}>Sample line · {tone < 33 ? 'Formal' : tone > 66 ? 'Casual' : 'Friendly'}</div>
          <div style={{ marginTop:6, fontFamily:'var(--font-display)', fontSize:16, lineHeight:1.35 }}>
            {tone < 33 && '"Thank you for reaching out. I would be glad to schedule an evaluation at your convenience."'}
            {tone >= 33 && tone < 67 && '"Hey — thanks for reaching out! Want me to pencil you in for tomorrow morning?"'}
            {tone >= 67 && '"Heyo — got your message. Tomorrow morning work? I\'ll save you the spot."'}
          </div>
        </div>

        <div style={{ marginTop:20, display:'flex', gap:14, flexWrap:'wrap' }}>
          <Toggle value={get('emoji', tone > 60)} onChange={v => update({ emoji:v })} label="Allow emoji"/>
          <Toggle value={get('firstName', true)} onChange={v => update({ firstName:v })} label="Use first names"/>
          <Toggle value={get('jokes', false)} onChange={v => update({ jokes:v })} label="Light humor ok"/>
        </div>
      </CardSection>

      <div style={{ display:'flex', flexDirection:'column', gap:20 }}>
        <CardSection title="Words to use" hint="Trade jargon, brand vocab, regional terms — anything that signals you know your stuff." accent="var(--chart-400)">
          <VocabChips list={use} onAdd={(w) => setUse([...use, w])} onRemove={(w) => setUse(use.filter(x => x !== w))} colorBg="var(--chart-100)" colorFg="var(--chart-900)"/>
        </CardSection>
        <CardSection title="Words to avoid" hint="Off-brand terms, things competitors say, anything that sounds amateur." accent="var(--lilac-500)">
          <VocabChips list={avoid} onAdd={(w) => setAvoid([...avoid, w])} onRemove={(w) => setAvoid(avoid.filter(x => x !== w))} colorBg="var(--lilac-100)" colorFg="var(--lilac-800)"/>
        </CardSection>
      </div>
    </div>
  );
}

function VocabChips({ list, onAdd, onRemove, colorBg, colorFg }) {
  const [val, setVal] = useStateOB('');
  return (
    <div>
      <div style={{ display:'flex', flexWrap:'wrap', gap:5, marginBottom:10 }}>
        {list.map(w => (
          <span key={w} style={{ display:'inline-flex', alignItems:'center', gap:6, background:colorBg, color:colorFg, padding:'5px 4px 5px 10px', borderRadius:99, fontSize:12, fontWeight:600 }}>
            {w}
            <button onClick={() => onRemove(w)} style={{ background:'rgba(0,0,0,0.08)', border:0, borderRadius:99, width:16, height:16, fontSize:11, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', color:'inherit' }}>×</button>
          </span>
        ))}
      </div>
      <form onSubmit={e => { e.preventDefault(); if(val.trim()){ onAdd(val.trim()); setVal(''); } }} style={{ display:'flex', gap:8 }}>
        <input value={val} onChange={e => setVal(e.target.value)} placeholder="add a word…"
          style={{ flex:1, background:'#fff', border:'1px solid var(--line)', borderRadius:10, padding:'9px 13px', outline:0, fontFamily:'var(--font-body)', fontSize:13 }}/>
        <button type="submit" style={{ background:'var(--ink)', color:'#fff', border:0, padding:'9px 14px', borderRadius:10, fontWeight:600, fontSize:12, cursor:'pointer', fontFamily:'var(--font-body)' }}>Add</button>
      </form>
    </div>
  );
}

/* 8. CONNECT (integrations) ============================================================ */
const CONNECT_GROUPS = [
  { label:'CRM / dispatch',  items:[
    { id:'servicetitan', name:'ServiceTitan',  desc:'Two-way sync · jobs, customers, history' },
    { id:'jobber',       name:'Jobber',        desc:'Two-way sync · jobs, schedule' },
    { id:'housecallpro', name:'Housecall Pro', desc:'Sync customers, dispatch' },
    { id:'salesforce',   name:'Salesforce',    desc:'Sync leads + opps' },
  ] },
  { label:'Calendar', items:[
    { id:'google',  name:'Google Calendar', desc:'Crew + sales schedules' },
    { id:'outlook', name:'Outlook',         desc:'Crew + sales schedules' },
  ] },
  { label:'Payments', items:[
    { id:'stripe',  name:'Stripe',  desc:'Deposit + final · ACH, card, Apple Pay' },
    { id:'square',  name:'Square',  desc:'Card-present + invoices' },
    { id:'quickbooks', name:'QuickBooks', desc:'Push invoices + payments' },
  ] },
  { label:'Field tools', items:[
    { id:'companycam',  name:'CompanyCam',  desc:'Job photos, before/after' },
    { id:'tradeshift',  name:'Xactimate',   desc:'Insurance supplements' },
  ] },
];
function StepConnect({ cfg, get, update }) {
  const connected = get('connected', { google:true, stripe:true, companycam:true });
  const toggle = (id) => update({ connected: { ...connected, [id]: !connected[id] } });
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:18 }}>
      {CONNECT_GROUPS.map(g => (
        <CardSection key={g.label} title={g.label}>
          <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
            {g.items.map(it => {
              const on = !!connected[it.id];
              return (
                <button key={it.id} onClick={() => toggle(it.id)}
                  style={{ textAlign:'left', display:'flex', alignItems:'center', gap:12, padding:'14px 16px',
                    background: on ? 'var(--chart-100)' : '#fff',
                    border:'1.5px solid '+(on ? 'var(--chart-400)' : 'var(--line)'),
                    borderRadius:12, cursor:'pointer', fontFamily:'var(--font-body)', transition:'all 0.15s' }}>
                  <div style={{ width:38, height:38, borderRadius:9, background:'var(--ink)', color:'var(--chart-300)', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'var(--font-display)', fontWeight:800, fontSize:14, flexShrink:0 }}>
                    {it.name.slice(0,2)}
                  </div>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontSize:14, fontWeight:600, color:'var(--ink)' }}>{it.name}</div>
                    <div style={{ fontSize:11.5, color:'var(--mute-1)', marginTop:1 }}>{it.desc}</div>
                  </div>
                  <span style={{ fontSize:10, fontWeight:800, padding:'3px 9px', borderRadius:99, background: on ? 'var(--ink)' : 'var(--paper-3)', color: on ? 'var(--chart-300)' : 'var(--mute-1)', letterSpacing:'0.08em' }}>
                    {on ? 'CONNECTED' : 'CONNECT'}
                  </span>
                </button>
              );
            })}
          </div>
        </CardSection>
      ))}
      <CardSection title={`Industry partners · ${cfg.industryLabel || cfg.serviceName}`} hint={`Trade-specific tools we recognize for ${(cfg.industryLabel || cfg.serviceName).toLowerCase()}.`} accent="var(--lilac-500)">
        <div style={{ display:'flex', flexWrap:'wrap', gap:6 }}>
          {cfg.partners.map(p => (
            <span key={p} style={{ background:'#fff', border:'1px solid var(--line)', padding:'7px 14px', borderRadius:99, fontSize:13, fontWeight:600, color:'var(--ink)' }}>{p}</span>
          ))}
        </div>
      </CardSection>
    </div>
  );
}

/* 9. REVIEW + LAUNCH ============================================================ */
function StepReview({ cfg, answers }) {
  const w = answers.welcome || {};
  const s = answers.services || {};
  const p = answers.pricing || {};
  const f = answers.fields || {};
  const h = answers.history || {};
  const i = answers.intake || {};
  const v = answers.voice || {};
  const c = answers.connect || {};
  const fields = f.fields || cfg.estimateFields;
  const qs = i.qs || cfg.leadQs;
  const subs = s.subTrades || cfg.subTrades.slice(0, 4);
  const jobs = h.uploaded || cfg.sampleJobs;
  const connected = Object.entries(c.connected || {}).filter(([_,v]) => v).map(([k]) => k);

  return (
    <div>
      <div style={{ background:'var(--ink)', color:'#fff', borderRadius:24, padding:'36px 40px', marginBottom:20, position:'relative', overflow:'hidden' }}>
        <div style={{ position:'absolute', top:-100, right:-100, width:400, height:400, borderRadius:'50%', background:'var(--chart-700)', opacity:.3, filter:'blur(60px)' }}/>
        <div style={{ position:'relative' }}>
          <div className="eyebrow" style={{ color:'var(--chart-300)' }}>Ready to install</div>
          <h2 className="display" style={{ fontSize:56, fontWeight:600, letterSpacing:'-0.04em', lineHeight:1, margin:'14px 0 0' }}>
            {w.dba || w.company || 'Your company'} · <span className="serif-it" style={{ color:'var(--chart-300)' }}>{cfg.serviceName}</span>
          </h2>
          <p style={{ fontSize:17, color:'rgba(255,255,255,0.7)', marginTop:16, maxWidth:620, lineHeight:1.45 }}>
            We've got everything we need. A real human reaches out within 24 hrs to confirm install — usually 2 weeks from today, white-glove.
          </p>
          <div className="ob-grid-4col" style={{ marginTop:24, display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:10 }}>
            {[
              ['Sub-trades',     subs.length],
              ['Estimate fields', fields.length],
              ['Intake questions', qs.filter(q => q.on).length],
              ['Connections',    connected.length || 3],
            ].map(([l, val]) => (
              <div key={l} style={{ background:'rgba(255,255,255,0.06)', borderRadius:14, padding:'14px 16px' }}>
                <div style={{ fontSize:11, color:'rgba(255,255,255,0.55)', fontWeight:600, letterSpacing:'0.08em', textTransform:'uppercase' }}>{l}</div>
                <div className="display" style={{ fontSize:28, fontWeight:600, marginTop:4 }}>{val}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
      <div className="ob-grid-2col" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:18 }}>
        <CardSection title="What we'll install">
          <ul style={{ paddingLeft:18, margin:0, fontSize:13.5, lineHeight:1.7, color:'var(--mute-1)' }}>
            <li>Estimate engine configured for <strong style={{ color:'var(--ink)' }}>{cfg.serviceName}</strong></li>
            <li><strong style={{ color:'var(--ink)' }}>{fields.length}</strong> custom fields on every quote</li>
            <li>AI lead intake with <strong style={{ color:'var(--ink)' }}>{qs.filter(q => q.on).length}</strong> qualifying questions</li>
            <li>Pricing rules pulled from your job library ({jobs.length} jobs)</li>
            <li>Tone set to <strong style={{ color:'var(--ink)' }}>{(v.tone ?? 55) < 33 ? 'Formal' : (v.tone ?? 55) > 66 ? 'Casual' : 'Friendly'}</strong></li>
            <li><strong style={{ color:'var(--ink)' }}>{connected.length || 3}</strong> connections wired into your stack</li>
          </ul>
        </CardSection>
        <CardSection title="What happens next" accent="var(--lilac-500)">
          <ol style={{ paddingLeft:18, margin:0, fontSize:13.5, lineHeight:1.7, color:'var(--mute-1)' }}>
            <li>You hit <strong style={{ color:'var(--ink)' }}>Submit application</strong></li>
            <li>A real human reviews your fit (24 hrs)</li>
            <li>30-min install call to confirm everything</li>
            <li>We mirror your job library + connections</li>
            <li>Soft-launch: AI answers leads, you watch</li>
            <li>Hard-launch: AI quotes + closes</li>
          </ol>
        </CardSection>
      </div>
    </div>
  );
}

Object.assign(window, {
  Field, TextInput, SelectInput, Toggle, CardSection, Slider, VocabChips,
  StepWelcome, StepServices, StepPricing, StepFields, StepHistory, StepIntake, StepVoice, StepConnect, StepReview,
});
