const custStyles = {
  page:{maxWidth:560, margin:"0 auto", padding:"0 20px calc(96px + env(safe-area-inset-bottom))", minHeight:"100vh"},
  header:{display:"flex", alignItems:"center", gap:10, padding:"18px 0 6px"},
  footer:{position:"fixed", left:0, right:0, bottom:0, background:"var(--bg-1)", borderTop:"1px solid var(--border)", padding:"12px 20px calc(12px + env(safe-area-inset-bottom))", zIndex:5},
  footerInner:{maxWidth:560, margin:"0 auto", display:"flex", gap:"var(--s-3)", alignItems:"center"},
  label:{fontSize:13, fontWeight:500, color:"var(--fg-1)", marginBottom:8, display:"block"},
  hint:{fontSize:12, color:"var(--fg-3)", marginTop:6},
};
const WIZ_STEPS = [
  {id:"issue", label:"Problem"},
  {id:"category", label:"Type"},
  {id:"property", label:"Property"},
  {id:"timing", label:"Timing"},
  {id:"contact", label:"Contact"},
];
function WizardNav({nav}){
  return <div style={{marginBottom:"var(--s-6)"}}>
    <div style={{display:"flex", alignItems:"center", gap:4}}>
      {WIZ_STEPS.map((s,i)=>{
        const done = i < nav.idx, cur = i === nav.idx;
        return <React.Fragment key={s.id}>
          {i>0 && <span style={{flex:1, height:2, background:i<=nav.idx?"var(--blue-500)":"var(--ink-75)", borderRadius:1, minWidth:6}}></span>}
          <button onClick={()=>done && nav.onJump(i)} disabled={!done} aria-label={s.label+(done?" (done)":cur?" (current)":"")} style={{display:"flex", alignItems:"center", gap:5, border:"none", background:"none", padding:0, cursor:done?"pointer":"default"}}>
            <span style={{width:20, height:20, borderRadius:"50%", display:"flex", alignItems:"center", justifyContent:"center", flex:"none", fontSize:11, fontWeight:600, fontFamily:"var(--font-mono)", background:done?"var(--blue-500)":cur?"var(--ink-900)":"var(--ink-75)", color:done||cur?"#fff":"var(--fg-3)", transition:"background var(--dur-fast) var(--ease-standard)"}}>{done?<Icon name="check" size={11}></Icon>:i+1}</span>
            <span className={cur?"":"wiz-label"} style={{fontSize:11, fontWeight:500, whiteSpace:"nowrap", color:cur?"var(--fg-1)":done?"var(--fg-2)":"var(--fg-3)"}}>{s.label}</span>
          </button>
        </React.Fragment>;
      })}
    </div>
    {(nav.pending>0 || nav.loading) && <div className="fade" style={{marginTop:"var(--s-3)", display:"flex", alignItems:"center", gap:7, fontSize:12, color:"var(--fg-2)"}}>
      <Icon name={nav.loading?"loader":"message-circle"} size={13} style={{color:"var(--blue-500)"}}></Icon>
      <span>{nav.loading ? "Reading your description and photos…" : nav.pending+" quick question"+(nav.pending>1?"s":"")+" below — answers sharpen your quote"}</span>
    </div>}
  </div>;
}
function CustHeader({onBack, nav}){
  return <div>
    <div style={custStyles.header}>
      {onBack ? <button className="btn btn-ghost btn-sm" onClick={onBack} style={{paddingLeft:0, color:"var(--fg-2)"}}><Icon name="chevron-left" size={16}></Icon>Back</button> : <span style={{display:"flex", alignItems:"center", gap:9}}><BrandMark size={22}></BrandMark><span style={{fontWeight:600, fontSize:15, letterSpacing:"-.01em"}}>{BRAND}</span></span>}
    </div>
    {nav && nav.show && <WizardNav nav={nav}></WizardNav>}
    {nav && !nav.show && nav.idx>=0 && nav.idx<5 && <div style={{height:3, background:"var(--ink-75)", borderRadius:2, overflow:"hidden", marginBottom:"var(--s-6)"}}>
      <div style={{height:"100%", width:((nav.idx+1)/5*100)+"%", background:"var(--blue-500)", borderRadius:2, transition:"width var(--dur-standard) var(--ease-standard)"}}></div>
    </div>}
  </div>;
}
function StickyCTA({label, onClick, disabled, secondary}){
  return <div style={custStyles.footer}>
    <div style={custStyles.footerInner}>
      {secondary}
      <button className="btn btn-primary btn-lg btn-block" disabled={disabled} onClick={onClick}>{label}</button>
    </div>
  </div>;
}
function Field({label, hint, children}){
  return <div style={{marginBottom:"var(--s-6)"}}>
    <label style={custStyles.label}>{label}</label>
    {children}
    {hint && <div style={custStyles.hint}>{hint}</div>}
  </div>;
}
function emptyDraft(){
  return {category:null, categories:[], categoryOther:"", description:"", photos:[], property:{type:"", age:"", access:"", address:"", coords:null}, urgency:null, customer:{name:"", phone:"", email:"", pref:""}};
}
function CustomerApp({tweaks}){
  const t = tweaks || {};
  const inlineMode = t.questionsMode !== "End chat";
  const maxQ = Math.round(t.maxQuestions || 4);
  const [screen, setScreen] = useState("welcome");
  const [draft, setDraft] = useState(emptyDraft);
  const [qa, setQa] = useState([]);
  const [transcript, setTranscript] = useState([]);
  const [summary, setSummary] = useState(null);
  const [ref, setRef] = useState("");
  const [aiQ, setAiQ] = useState({loading:false, observation:"", list:[]});
  const genOnce = useRef(false);
  const summarizedCount = useRef(-1);
  const up = (patch)=>setDraft(d=>({...d, ...patch}));
  const answered = aiQ.list.filter(x=>x.answer!=null && x.answer!=="__skip");
  const pending = aiQ.list.filter(x=>x.answer==null);
  const genQuestions = ()=>{
    if(genOnce.current || !inlineMode) return;
    genOnce.current = true;
    setAiQ(s=>({...s, loading:true}));
    batchQuestions(draft, maxQ).then(res=>{
      setAiQ({loading:false, observation:res.observation||"", list:(res.questions||[]).slice(0, maxQ).map(x=>({id:uid(), q:x.question, quickReplies:(x.quickReplies||[]).slice(0,4), source:x.source==="photos"?"photos":"description", answer:null}))});
    }).catch(()=>{
      setAiQ({loading:false, observation:"", list:FALLBACK_QS.slice(0, Math.min(3, maxQ)).map(f=>({id:uid(), q:f.question, quickReplies:f.quickReplies||[], source:"description", answer:null}))});
    });
  };
  const answerQ = (id, text)=>setAiQ(s=>({...s, list:s.list.map(x=>x.id===id?{...x, answer:text}:x)}));
  const skipQ = (id)=>setAiQ(s=>({...s, list:s.list.map(x=>x.id===id?{...x, answer:"__skip"}:x)}));
  const inlineQa = ()=>answered.map(x=>({q:x.q, a:x.answer}));
  const openQs = ()=>aiQ.list.filter(x=>x.answer==null || x.answer==="__skip").map(x=>x.q);
  const inlineTranscript = ()=>{
    const msgs = [];
    if(aiQ.observation) msgs.push({role:"ai", text:aiQ.observation});
    aiQ.list.forEach(x=>{ if(x.answer!=null && x.answer!=="__skip"){ msgs.push({role:"ai", text:x.q}); msgs.push({role:"user", text:x.answer}); } });
    return msgs;
  };
  const buildAndReview = async (qaList, unanswered)=>{
    setScreen("building");
    let s; try{ s = await buildSummary(draft, qaList, unanswered); }catch(e){ s = fallbackSummary(draft, qaList); }
    summarizedCount.current = qaList.length;
    setSummary(s); setScreen("review");
  };
  const submit = async ()=>{
    let s = summary;
    const qaList = inlineMode ? inlineQa() : qa;
    if(inlineMode && qaList.length !== summarizedCount.current){
      setScreen("building");
      try{ s = await buildSummary(draft, qaList, openQs()); }catch(e){}
    }
    const reqRef = "QR-" + (2400 + Math.floor(Math.random()*500));
    const req = {id:uid(), ref:reqRef, createdAt:Date.now(), status:"new", category:draft.categories[0]||"handyman", categories:draft.categories, categoryOther:draft.categoryOther, urgency:draft.urgency,
      customer:draft.customer, property:draft.property, description:draft.description, photos:draft.photos,
      transcript:inlineMode ? inlineTranscript() : transcript, ai:s, quote:null};
    saveRequests([req, ...loadRequests()]);
    setRef(reqRef); setScreen("done");
  };
  const idx = screen==="welcome" ? -1 : ["review","building","done"].includes(screen) ? 5 : WIZ_STEPS.findIndex(s=>s.id===screen);
  const nav = {show:t.sectionNav!==false, idx, onJump:(i)=>setScreen(WIZ_STEPS[i].id), pending:inlineMode?pending.length:0, loading:inlineMode&&aiQ.loading};
  const screens = {
    welcome: <Welcome onStart={()=>setScreen("issue")}></Welcome>,
    issue: <StepIssue draft={draft} up={up} nav={nav} onBack={()=>setScreen("welcome")} onNext={()=>setScreen("category")}></StepIssue>,
    category: <StepCategory draft={draft} up={up} nav={nav} onBack={()=>setScreen("issue")} onNext={()=>{genQuestions(); setScreen("property");}}></StepCategory>,
    property: <StepProperty draft={draft} up={up} nav={nav} onBack={()=>setScreen("category")} onNext={()=>setScreen("timing")}></StepProperty>,
    timing: <StepTiming draft={draft} up={up} nav={nav} onBack={()=>setScreen("property")} onNext={()=>setScreen("contact")}></StepTiming>,
    contact: <StepContact draft={draft} up={up} nav={nav} onBack={()=>setScreen("timing")} onNext={()=>{ inlineMode ? buildAndReview(inlineQa(), openQs()) : setScreen("chat"); }}></StepContact>,
    chat: <ChatScreen draft={draft} qa={qa} setQa={setQa} transcript={transcript} setTranscript={setTranscript} maxQ={maxQ}
      onDone={(finalQa)=>buildAndReview(finalQa, [])}></ChatScreen>,
    building: <BuildingScreen></BuildingScreen>,
    review: <ReviewScreen draft={draft} summary={summary} nav={nav} pendingCount={inlineMode?pending.length:0} onSend={submit} onBack={()=>setScreen("contact")}></ReviewScreen>,
    done: <DoneScreen refCode={ref} urgency={draft.urgency} onNew={()=>{setDraft(emptyDraft()); setQa([]); setTranscript([]); setSummary(null); setAiQ({loading:false, observation:"", list:[]}); genOnce.current=false; summarizedCount.current=-1; setScreen("welcome");}}></DoneScreen>,
  };
  const showInline = inlineMode && ["property","timing","contact","review"].includes(screen);
  return <div style={screen==="chat" ? {...custStyles.page, padding:"0 20px"} : custStyles.page}>
    {screens[screen]}
    {showInline && <InlineQuestion aiQ={aiQ} onAnswer={answerQ} onSkip={skipQ}></InlineQuestion>}
  </div>;
}
function Welcome({onStart}){
  return <div className="fade" data-screen-label="Customer · Welcome">
    <CustHeader></CustHeader>
    <div style={{padding:"var(--s-12) 0 var(--s-8)"}}>
      <div className="t-eyebrow" style={{marginBottom:"var(--s-3)"}}>Repair quotes</div>
      <h3 style={{margin:0}}>Get a quote without the phone tag.</h3>
      <p className="t-body-lg" style={{color:"var(--fg-2)", marginTop:"var(--s-4)"}}>Tell us what's broken. Our assistant asks the few questions we'd ask on a site visit, so your quote is accurate the first time.</p>
    </div>
    <div className="card" style={{padding:"var(--s-6)"}}>
      {[["clipboard-list","Describe the problem","2 minutes, photos help"],["message-circle","Answer a few smart questions","Asked as you go — only what affects the price"],["file-text","Get your quote","We reply within 1 business day"]].map((s,i)=>
        <div key={i} style={{display:"flex", gap:14, alignItems:"flex-start", padding:i?"var(--s-4) 0 0":"0", marginTop:i?"var(--s-4)":0, borderTop:i?"1px solid var(--border)":"none"}}>
          <span style={{width:36, height:36, borderRadius:"var(--r-md)", background:"var(--blue-50)", color:"var(--blue-500)", display:"flex", alignItems:"center", justifyContent:"center", flex:"none"}}><Icon name={s[0]} size={18}></Icon></span>
          <span><span style={{display:"block", fontWeight:500, fontSize:15}}>{s[1]}</span><span style={{display:"block", fontSize:13, color:"var(--fg-2)", marginTop:2}}>{s[2]}</span></span>
        </div>)}
    </div>
    <p style={{fontSize:13, color:"var(--fg-3)", marginTop:"var(--s-4)"}}>No account needed. Your details go to {BRAND} only.</p>
    <StickyCTA label="Start my quote" onClick={onStart}></StickyCTA>
  </div>;
}
function StepIssue({draft, up, nav, onBack, onNext}){
  const fileRef = useRef();
  const [busy, setBusy] = useState(false);
  const valid = draft.description.trim().length >= 10;
  const addPhotos = async (files)=>{
    setBusy(true);
    const list = [...draft.photos];
    for(const f of Array.from(files).slice(0, 6-list.length)){
      try{ list.push(await resizePhoto(f)); }catch(e){}
    }
    up({photos:list}); setBusy(false);
  };
  return <div className="fade" data-screen-label="Customer · Step 1 Issue">
    <CustHeader nav={nav} onBack={onBack}></CustHeader>
    <h4 style={{margin:"0 0 var(--s-6)"}}>What needs fixing?</h4>
    <Field label="Describe the problem" hint="What's happening, where, and since when. Plain words are fine — we'll work out the trade.">
      <textarea className="input" placeholder="e.g. Water dripping from the pipe under the kitchen sink, cabinet floor is wet…" value={draft.description} onChange={e=>up({description:e.target.value})}></textarea>
    </Field>
    <Field label="Photos" hint="Optional, but a photo often saves a site visit. Up to 6.">
      <div style={{display:"flex", flexWrap:"wrap", gap:"var(--s-2)"}}>
        {draft.photos.map((p,i)=><span key={i} style={{position:"relative"}}>
          <img src={p} alt={"Photo "+(i+1)} style={{width:72, height:72, objectFit:"cover", borderRadius:"var(--r-md)", border:"1px solid var(--border)", display:"block"}}></img>
          <button aria-label="Remove photo" onClick={()=>up({photos:draft.photos.filter((_,j)=>j!==i)})} style={{position:"absolute", top:-6, right:-6, width:22, height:22, borderRadius:"50%", border:"none", background:"var(--ink-900)", color:"#fff", cursor:"pointer", display:"flex", alignItems:"center", justifyContent:"center", padding:0}}><Icon name="x" size={12}></Icon></button>
        </span>)}
        {draft.photos.length<6 && <button className="chip" style={{width:72, height:72, borderRadius:"var(--r-md)", justifyContent:"center", borderStyle:"dashed"}} onClick={()=>fileRef.current.click()} disabled={busy}>
          <Icon name={busy?"loader":"camera"} size={20} style={{color:"var(--fg-2)"}}></Icon>
        </button>}
      </div>
      <input ref={fileRef} type="file" accept="image/*" multiple style={{display:"none"}} onChange={e=>{addPhotos(e.target.files); e.target.value="";}}></input>
    </Field>
    <StickyCTA label="Continue" disabled={!valid} onClick={onNext}></StickyCTA>
  </div>;
}
function StepCategory({draft, up, nav, onBack, onNext}){
  const [guessing, setGuessing] = useState(!draft.categories.length);
  const [showOther, setShowOther] = useState(!!draft.categoryOther);
  const guessed = useRef(false);
  useEffect(()=>{
    if(draft.categories.length || guessed.current) return;
    guessed.current = true;
    classifyCategory(draft.description).then(cats=>{ up({categories:cats}); setGuessing(false); });
  }, []);
  const toggle = (id)=>up({categories: draft.categories.includes(id) ? draft.categories.filter(c=>c!==id) : [...draft.categories, id]});
  const valid = draft.categories.length>0 || draft.categoryOther.trim();
  return <div className="fade" data-screen-label="Customer · Step 2 Type of work">
    <CustHeader nav={nav} onBack={onBack}></CustHeader>
    <h4 style={{margin:"0 0 var(--s-2)"}}>Type of work</h4>
    <p style={{color:"var(--fg-2)", margin:"0 0 var(--s-6)"}}>{guessing ? "Reading your description…" : "Based on your description — tap to adjust, pick as many as apply."}</p>
    {guessing ? <div className="typing" style={{padding:"var(--s-4) 0"}}><span></span><span></span><span></span></div>
    : <div>
      <div style={{display:"flex", flexWrap:"wrap", gap:"var(--s-2)"}}>
        {CATEGORIES.map(c=><button key={c.id} className={"chip"+(draft.categories.includes(c.id)?" on":"")} onClick={()=>toggle(c.id)}><Icon name={c.icon} size={15}></Icon>{c.label}</button>)}
        <button className={"chip"+(showOther?" on":"")} onClick={()=>{ if(showOther) up({categoryOther:""}); setShowOther(!showOther); }}><Icon name="plus" size={15}></Icon>Other</button>
      </div>
      {showOther && <input className="input fade" style={{marginTop:"var(--s-3)"}} placeholder="Tell us the trade, e.g. Pest control" value={draft.categoryOther} onChange={e=>up({categoryOther:e.target.value})}></input>}
    </div>}
    <StickyCTA label="Continue" disabled={!valid} onClick={onNext}></StickyCTA>
  </div>;
}
async function reverseGeocode(lat, lng){
  const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`, {headers:{Accept:"application/json"}});
  const j = await res.json();
  const a = j.address || {};
  const line = [ [a.house_number, a.road].filter(Boolean).join(" "), a.suburb || a.neighbourhood, a.city || a.town || a.village ].filter(Boolean).join(", ");
  return line || j.display_name || "";
}
function LocateMap({coords, onMove}){
  const mapRef = useRef(null);
  const objRef = useRef(null);
  useEffect(()=>{
    if(!coords || !window.L || !mapRef.current) return;
    if(!objRef.current){
      const map = L.map(mapRef.current).setView([coords.lat, coords.lng], 16);
      L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {attribution:"© OpenStreetMap contributors"}).addTo(map);
      const marker = L.marker([coords.lat, coords.lng], {draggable:true}).addTo(map);
      marker.on("dragend", ()=>{ const p = marker.getLatLng(); onMove({lat:p.lat, lng:p.lng}); });
      objRef.current = {map, marker};
      setTimeout(()=>map.invalidateSize(), 50);
    } else {
      objRef.current.marker.setLatLng([coords.lat, coords.lng]);
      objRef.current.map.setView([coords.lat, coords.lng]);
    }
  }, [coords]);
  useEffect(()=>()=>{ if(objRef.current){ objRef.current.map.remove(); objRef.current = null; } }, []);
  if(!coords) return null;
  return <div className="fade" style={{marginTop:"var(--s-3)"}}>
    <div ref={mapRef} style={{height:200, borderRadius:"var(--r-md)", border:"1px solid var(--border)", overflow:"hidden", zIndex:0, position:"relative"}}></div>
    <div style={{fontSize:12, color:"var(--fg-3)", marginTop:6}}>Drag the pin if it's slightly off.</div>
  </div>;
}
function StepProperty({draft, up, nav, onBack, onNext}){
  const p = draft.property;
  const upP = (patch)=>up({property:{...draft.property, ...patch}});
  const [locating, setLocating] = useState(false);
  const [locErr, setLocErr] = useState("");
  const applyCoords = async (coords, fillAddress)=>{
    upP({coords});
    try{
      const line = await reverseGeocode(coords.lat, coords.lng);
      if(line && fillAddress) up({property:{...draft.property, coords, address:line}});
    }catch(e){}
  };
  const locate = ()=>{
    setLocErr("");
    if(!navigator.geolocation){ setLocErr("Location isn't available on this device."); return; }
    setLocating(true);
    navigator.geolocation.getCurrentPosition(
      pos=>{ setLocating(false); applyCoords({lat:pos.coords.latitude, lng:pos.coords.longitude}, !p.address.trim()); },
      ()=>{ setLocating(false); setLocErr("Couldn't get your location — you can type the address instead."); },
      {enableHighAccuracy:true, timeout:10000}
    );
  };
  return <div className="fade" data-screen-label="Customer · Step 3 Property">
    <CustHeader nav={nav} onBack={onBack}></CustHeader>
    <h4 style={{margin:"0 0 var(--s-6)"}}>About the property</h4>
    <Field label="Property type">
      <div style={{display:"flex", gap:"var(--s-2)", flexWrap:"wrap"}}>
        {["House","Apartment","Commercial"].map(t=><button key={t} className={"chip"+(p.type===t?" on":"")} onClick={()=>upP({type:t})}>{t}</button>)}
      </div>
    </Field>
    <Field label="Roughly how old is the building?">
      <div style={{display:"flex", gap:"var(--s-2)", flexWrap:"wrap"}}>
        {["Under 10 years","10–30 years","30+ years","Not sure"].map(t=><button key={t} className={"chip"+(p.age===t?" on":"")} onClick={()=>upP({age:t})}>{t}</button>)}
      </div>
    </Field>
    <Field label="Address or area" hint={locErr || "Street address, or just the neighborhood for now."}>
      <div style={{display:"flex", gap:"var(--s-2)"}}>
        <input className="input" placeholder="e.g. 84 Alder Street" value={p.address} onChange={e=>upP({address:e.target.value})}></input>
        <button className="btn btn-secondary" onClick={locate} disabled={locating} style={{flex:"none", padding:"0 16px"}}><Icon name={locating?"loader":"locate-fixed"} size={16}></Icon>{locating?"Locating…":"Locate me"}</button>
      </div>
      <LocateMap coords={p.coords} onMove={c=>applyCoords(c, false)}></LocateMap>
    </Field>
    <Field label="Access notes" hint="Parking, stairs, keys, pets, times you're home — anything we should know.">
      <input className="input" placeholder="e.g. Home after 4pm, driveway parking" value={p.access} onChange={e=>upP({access:e.target.value})}></input>
    </Field>
    <StickyCTA label="Continue" disabled={!p.type} onClick={onNext}></StickyCTA>
  </div>;
}
function StepTiming({draft, up, nav, onBack, onNext}){
  return <div className="fade" data-screen-label="Customer · Step 4 Timing">
    <CustHeader nav={nav} onBack={onBack}></CustHeader>
    <h4 style={{margin:"0 0 var(--s-6)"}}>How urgent is it?</h4>
    <div style={{display:"flex", flexDirection:"column", gap:"var(--s-3)"}}>
      {URGENCIES.map(u=><button key={u.id} onClick={()=>up({urgency:u.id})} className="card" style={{display:"flex", alignItems:"center", gap:14, padding:"var(--s-4)", cursor:"pointer", textAlign:"left", borderColor:draft.urgency===u.id?"var(--blue-500)":"var(--border)", boxShadow:draft.urgency===u.id?"0 0 0 3px var(--blue-100)":"none", transition:"all var(--dur-fast) var(--ease-standard)", background:"var(--bg-1)"}}>
        <span style={{width:20, height:20, borderRadius:"50%", border:draft.urgency===u.id?"6px solid var(--blue-500)":"2px solid var(--ink-200)", flex:"none", transition:"all var(--dur-fast) var(--ease-standard)"}}></span>
        <span><span style={{display:"block", fontWeight:500, fontSize:15}}>{u.label}</span><span style={{display:"block", fontSize:13, color:"var(--fg-2)", marginTop:2}}>{u.sub}</span></span>
      </button>)}
    </div>
    {draft.urgency==="emergency" && <div className="fade" style={{marginTop:"var(--s-4)", padding:"var(--s-4)", borderRadius:"var(--r-md)", background:"#FFF2E0", color:"var(--warning-ink)", fontSize:14, display:"flex", gap:10, alignItems:"flex-start"}}><Icon name="phone" size={16} style={{marginTop:2}}></Icon><span>For a same-day emergency, calling is faster: <strong>(415) 555-0100</strong>. You can still finish this form.</span></div>}
    <StickyCTA label="Continue" disabled={!draft.urgency} onClick={onNext}></StickyCTA>
  </div>;
}
function StepContact({draft, up, nav, onBack, onNext}){
  const c = draft.customer;
  const upC = (patch)=>up({customer:{...c, ...patch}});
  const valid = c.name.trim() && (c.phone.trim() || c.email.trim());
  return <div className="fade" data-screen-label="Customer · Step 5 Contact">
    <CustHeader nav={nav} onBack={onBack}></CustHeader>
    <h4 style={{margin:"0 0 var(--s-6)"}}>Where should the quote go?</h4>
    <Field label="Your name"><input className="input" autoComplete="name" value={c.name} onChange={e=>upC({name:e.target.value})}></input></Field>
    <Field label="Phone"><input className="input" type="tel" autoComplete="tel" placeholder="(415) 555-0123" value={c.phone} onChange={e=>upC({phone:e.target.value})}></input></Field>
    <Field label="Email"><input className="input" type="email" autoComplete="email" placeholder="you@example.com" value={c.email} onChange={e=>upC({email:e.target.value})}></input></Field>
    <Field label="Preferred contact">
      <div style={{display:"flex", gap:"var(--s-2)", flexWrap:"wrap"}}>
        {["Phone call","Text","Email","WhatsApp"].map(t=><button key={t} className={"chip"+(c.pref===t?" on":"")} onClick={()=>upC({pref:t})}>{t}</button>)}
      </div>
    </Field>
    <StickyCTA label="Review my request" disabled={!valid} onClick={onNext}></StickyCTA>
  </div>;
}
function InlineQuestion({aiQ, onAnswer, onSkip}){
  const q = aiQ.list.find(x=>x.answer==null);
  const [val, setVal] = useState("");
  useEffect(()=>{ setVal(""); }, [q && q.id]);
  if(aiQ.loading) return <div className="card" style={{padding:"var(--s-4)", display:"flex", gap:12, alignItems:"center"}}>
    <div className="typing"><span></span><span></span><span></span></div>
    <span style={{fontSize:13, color:"var(--fg-2)"}}>Checking your photos and description for anything that affects the price…</span>
  </div>;
  if(!q) return null;
  const num = aiQ.list.filter(x=>x.answer!=null).length + 1;
  return <div className="card fade" style={{padding:"var(--s-4)", borderColor:"var(--blue-300)", boxShadow:"var(--shadow-1)"}}>
    <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:"var(--s-2)"}}>
      <span className="t-eyebrow" style={{display:"inline-flex", alignItems:"center", gap:5}}><Icon name={q.source==="photos"?"image":"message-circle"} size={12}></Icon>{q.source==="photos"?"From your photos":"Quick question"}</span>
      <span className="t-mono" style={{marginLeft:"auto", fontSize:11, color:"var(--fg-3)"}}>{num} of {aiQ.list.length}</span>
    </div>
    {aiQ.observation && num===1 && <p style={{fontSize:13, color:"var(--fg-2)", margin:"0 0 var(--s-2)"}}>{aiQ.observation}</p>}
    <div style={{fontSize:15, fontWeight:500, letterSpacing:"-.01em", marginBottom:"var(--s-3)"}}>{q.q}</div>
    {q.quickReplies.length>0 && <div style={{display:"flex", flexWrap:"wrap", gap:"var(--s-2)", marginBottom:"var(--s-2)"}}>
      {q.quickReplies.map((r,i)=><button key={i} className="chip" onClick={()=>onAnswer(q.id, r)}>{r}</button>)}
    </div>}
    <div style={{display:"flex", gap:"var(--s-2)"}}>
      <input className="input" style={{fontSize:14, padding:"9px 12px"}} placeholder="Type an answer…" value={val} onChange={e=>setVal(e.target.value)} onKeyDown={e=>{if(e.key==="Enter" && val.trim()) onAnswer(q.id, val.trim());}}></input>
      <button className="btn btn-primary btn-sm" aria-label="Send answer" disabled={!val.trim()} onClick={()=>onAnswer(q.id, val.trim())} style={{padding:"0 14px"}}><Icon name="arrow-up" size={15}></Icon></button>
    </div>
    <button className="btn btn-ghost btn-sm" style={{marginTop:4, paddingLeft:0, color:"var(--fg-3)"}} onClick={()=>onSkip(q.id)}>I don't know this one</button>
  </div>;
}
function ChatScreen({draft, qa, setQa, transcript, setTranscript, maxQ, onDone}){
  const [input, setInput] = useState("");
  const [pending, setPending] = useState(null);
  const [thinking, setThinking] = useState(false);
  const [fallbackIdx, setFallbackIdx] = useState(0);
  const started = useRef(false);
  const transcriptRef = useRef(transcript);
  const scroll = ()=>{ const el = document.getElementById("chat-scroll"); if(el) el.scrollTop = el.scrollHeight; };
  useEffect(scroll, [transcript, thinking, pending]);
  const pushMsg = (m)=>{ transcriptRef.current = [...transcriptRef.current, m]; setTranscript(transcriptRef.current); };
  const ask = async (curQa)=>{
    if(curQa.length >= maxQ){ onDone(curQa); return; }
    setThinking(true);
    let res;
    try{ res = await nextQuestion(draft, curQa, maxQ); }
    catch(e){
      const fq = FALLBACK_QS[fallbackIdx];
      res = fq && curQa.length < 3 ? {done:false, ...fq} : {done:true};
      setFallbackIdx(i=>i+1);
    }
    setThinking(false);
    if(res.done || !res.question){ onDone(curQa); return; }
    if(res.note) pushMsg({role:"ai", text:res.note});
    setPending({question:res.question, quickReplies:res.quickReplies||[]});
    pushMsg({role:"ai", text:res.question});
  };
  useEffect(()=>{
    if(started.current) return; started.current = true;
    transcriptRef.current = [];
    setTranscript([]);
    const first = draft.customer.name.split(" ")[0];
    pushMsg({role:"ai", text:`Thanks ${first}. ${draft.photos.length?"We're looking at your photos and description":"Based on your description"} — just a few questions so ${BRAND} can price this accurately.`});
    ask([]);
  }, []);
  const answer = (text)=>{
    if(!text.trim() || !pending) return;
    pushMsg({role:"user", text:text.trim()});
    const newQa = [...qa, {q:pending.question, a:text.trim()}];
    setQa(newQa); setPending(null); setInput("");
    ask(newQa);
  };
  const skip = ()=>{
    if(!pending) return;
    pushMsg({role:"user", text:"Not sure"});
    const newQa = [...qa, {q:pending.question, a:"Customer doesn't know"}];
    setQa(newQa); setPending(null);
    ask(newQa);
  };
  return <div data-screen-label="Customer · AI questions" style={{display:"flex", flexDirection:"column", height:"100dvh", margin:"0 -20px", position:"relative"}}>
    <div style={{padding:"0 20px", background:"var(--bg-2)"}}>
      <CustHeader></CustHeader>
      <div style={{display:"flex", alignItems:"center", gap:"var(--s-3)", padding:"var(--s-2) 0 var(--s-3)", borderBottom:"1px solid var(--border)"}}>
        {draft.photos.length>0 && <span style={{display:"flex", gap:4, flex:"none"}}>{draft.photos.slice(0,3).map((p,i)=><img key={i} src={p} alt="" style={{width:32, height:32, objectFit:"cover", borderRadius:"var(--r-sm)", border:"1px solid var(--border)"}}></img>)}</span>}
        <span style={{fontSize:13, color:"var(--fg-2)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap", minWidth:0}}>{catsLabel(draft)} · {draft.description}</span>
        <span className="t-mono" style={{fontSize:12, color:"var(--fg-3)", whiteSpace:"nowrap", marginLeft:"auto"}}>{Math.min(qa.length+1, maxQ)} of {maxQ} max</span>
      </div>
    </div>
    <div id="chat-scroll" style={{flex:1, overflowY:"auto", padding:"var(--s-4) 20px", display:"flex", flexDirection:"column", gap:"var(--s-3)"}}>
      {transcript.map((m,i)=><div key={i} className={"bubble fade "+(m.role==="ai"?"bubble-ai":"bubble-user")}>{m.text}</div>)}
      {thinking && <div className="bubble bubble-ai typing" aria-label="Assistant is typing"><span></span><span></span><span></span></div>}
    </div>
    <div style={{background:"var(--bg-1)", borderTop:"1px solid var(--border)", padding:"12px 20px calc(12px + env(safe-area-inset-bottom))"}}>
      {pending && pending.quickReplies.length>0 && <div style={{display:"flex", gap:"var(--s-2)", flexWrap:"wrap", marginBottom:"var(--s-3)"}}>
        {pending.quickReplies.map((r,i)=><button key={i} className="chip" onClick={()=>answer(r)}>{r}</button>)}
      </div>}
      <div style={{display:"flex", gap:"var(--s-2)"}}>
        <input className="input" placeholder={pending?"Type your answer…":"One moment…"} disabled={!pending} value={input} onChange={e=>setInput(e.target.value)} onKeyDown={e=>{if(e.key==="Enter") answer(input);}}></input>
        <button className="btn btn-primary" aria-label="Send" disabled={!pending || !input.trim()} onClick={()=>answer(input)} style={{padding:"0 18px"}}><Icon name="arrow-up" size={18}></Icon></button>
      </div>
      {pending && <button className="btn btn-ghost btn-sm" onClick={skip} style={{marginTop:6, color:"var(--fg-3)"}}>I don't know this one</button>}
    </div>
  </div>;
}
function BuildingScreen(){
  return <div className="fade" data-screen-label="Customer · Building summary" style={{display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", minHeight:"70vh", textAlign:"center", gap:"var(--s-4)"}}>
    <div className="typing" style={{transform:"scale(1.4)"}}><span></span><span></span><span></span></div>
    <h5 style={{margin:0}}>Putting your request together.</h5>
    <p style={{color:"var(--fg-2)", margin:0, maxWidth:320}}>We're writing up what you told us so the quote is right the first time.</p>
  </div>;
}
function ReviewScreen({draft, summary, nav, pendingCount, onSend, onBack}){
  return <div className="fade" data-screen-label="Customer · Review">
    <CustHeader nav={nav} onBack={onBack}></CustHeader>
    <h4 style={{margin:"0 0 var(--s-2)"}}>Here's what we'll send.</h4>
    <p style={{color:"var(--fg-2)", margin:"0 0 var(--s-6)"}}>Check it reads right — then it goes straight to {BRAND}.</p>
    <div className="card" style={{padding:"var(--s-6)", marginBottom:"var(--s-6)"}}>
      <div className="t-eyebrow" style={{marginBottom:"var(--s-2)"}}>{catsLabel(draft)} · {urgOf(draft.urgency).label}</div>
      <h5 style={{margin:"0 0 var(--s-3)"}}>{summary.title}</h5>
      <p style={{margin:"0 0 var(--s-4)", color:"var(--fg-2)"}}>{summary.summary}</p>
      <KeyFacts facts={summary.keyFacts}></KeyFacts>
      {draft.photos.length>0 && <div style={{display:"flex", gap:"var(--s-2)", marginTop:"var(--s-4)"}}>
        {draft.photos.map((p,i)=><img key={i} src={p} alt={"Photo "+(i+1)} style={{width:56, height:56, objectFit:"cover", borderRadius:"var(--r-sm)", border:"1px solid var(--border)"}}></img>)}
      </div>}
    </div>
    {pendingCount>0 && <p style={{fontSize:13, color:"var(--fg-3)", margin:"0 0 var(--s-4)"}}>{pendingCount} question{pendingCount>1?"s":""} left below — answering now makes the quote sharper, or send as is.</p>}
    <StickyCTA label="Send my request" onClick={onSend}></StickyCTA>
  </div>;
}
function DoneScreen({refCode, urgency, onNew}){
  return <div className="fade" data-screen-label="Customer · Confirmation" style={{textAlign:"center", paddingTop:"var(--s-12)"}}>
    <span style={{width:56, height:56, borderRadius:"50%", background:"#E8F7ED", color:"var(--success-ink)", display:"inline-flex", alignItems:"center", justifyContent:"center", marginBottom:"var(--s-6)"}}><Icon name="check" size={28}></Icon></span>
    <h4 style={{margin:"0 0 var(--s-2)"}}>Request sent.</h4>
    <p style={{color:"var(--fg-2)", margin:"0 auto var(--s-6)", maxWidth:340}}>{BRAND} has everything they need. You'll get a quote {urgency==="emergency"?"as soon as possible today":"within 1 business day"} — no site visit needed for most jobs.</p>
    <div className="card" style={{display:"inline-block", padding:"var(--s-4) var(--s-8)", marginBottom:"var(--s-8)"}}>
      <div className="t-micro" style={{marginBottom:4}}>Your reference</div>
      <div className="t-mono" style={{fontSize:24, fontWeight:700, letterSpacing:0}}>{refCode}</div>
    </div>
    <div><button className="btn btn-secondary" onClick={onNew}>Start another request</button></div>
  </div>;
}
Object.assign(window, {CustomerApp});
