/* ============================================================
   VKTR TCO Platform — Customer Needs Intake Wizard (v1.7.3)
   ------------------------------------------------------------
   Two ways to fill it in:
   - "Quick Questions" (default, free, no sign-in): 5 short questions,
     mapped onto a subset of DEFAULT_STATE and merged the same way a
     preset load is ({...DEFAULT_STATE, ...partial}).
   - "Describe in your own words" (AI-assisted, gated): one
     free-text box, sent through the Cloudflare Worker proxy
     (cf-worker/) to Claude with a forced structured-output tool
     call. Requires Google sign-in AND admin-granted apiAccess
     (see auth.jsx / admin_panel.jsx) -- this file only ever reads
     that state for display, the Worker is the real enforcement
     point. Extracted answers land in the exact same summary
     screen as Quick Questions before anything is applied -- never
     silently trusted.

   In both modes, the user lands on Screen 2 (Vehicle Selection) to
   pick the actual vehicles being compared — that choice is
   deliberately NOT guessed at here (nor by the AI): segment/brand
   matching from a few words is unreliable, and picking the wrong
   vehicle silently would undermine the whole comparison.

   v1.7.7: the project-type question and its conditional "what do you
   currently operate?" follow-up (existingVehicleId/existingVehicleHint)
   were removed along with the rest of the project-type concept --
   platform is Greenfield-only now.
   ============================================================ */

// Fixed order (v1.7.7: project-type/existing-vehicle question removed --
// platform is Greenfield-only).
function getIntakeQuestions(answers) {
  const qs = [
    { key: "ecosystemId", en: "Which industry is this fleet for?", id: "Untuk industri apa armada ini?" },
  ];
  qs.push(
    { key: "fleetSize", en: "About how many vehicles are you comparing?", id: "Sekitar berapa unit kendaraan yang Anda bandingkan?" },
    { key: "dailyKm", en: "About how far does each vehicle travel per day?", id: "Sekitar seberapa jauh setiap kendaraan menempuh jarak per hari?" },
    // v1.7.8: payload question added specifically to sharpen the Recommended
    // Vehicles step below -- payload/GVW is the strongest real differentiator
    // between candidate vehicles in the catalog; without it, a recommendation
    // can only go on segment (from industry) and price, which is too coarse.
    { key: "payloadKg", en: "About how much cargo weight per trip?", id: "Sekitar berapa berat muatan per perjalanan?" },
    { key: "terrainManual", en: "What's the terrain like on your route?", id: "Seperti apa medan pada rute Anda?" },
    { key: "payment", en: "How do you plan to pay for the vehicles?", id: "Bagaimana rencana Anda membayar kendaraan ini?" },
  );
  return qs;
}

// v1.7.7: "Lease" is not a payment method anymore (that concept was removed
// along with the old Commercial Scheme Ladder -- see CHANGELOG.md [v1.7.7]).
// Choosing it here instead pre-applies the Customer/VKTR Expense-Bucket
// model's "Sewa Unit" preset (VKTR bears UNIT/capital) -- see finish()
// below -- so the option still means something real, wired to the current
// financial model instead of writing an unsupported payment value.
const NEEDS_INTAKE_PAYMENT_OPTIONS = [
  { id: "cash", icon: "💰", en: "Cash", id_: "Tunai", desc_en: "Pay the full price upfront.", desc_id: "Bayar penuh di muka." },
  { id: "loan", icon: "🏦", en: "Loan / Credit", id_: "Kredit", desc_en: "Finance through a bank loan.", desc_id: "Dibiayai melalui pinjaman bank." },
  { id: "lease", icon: "📋", en: "Lease", id_: "Sewa", desc_en: "VKTR bears the capital cost, you pay a rate instead of owning it outright.", desc_id: "VKTR menanggung biaya modal, Anda membayar tarif alih-alih memiliki penuh." },
  { id: "notsure", icon: "🤔", en: "Not sure yet", id_: "Belum tahu", desc_en: "Start with Cash — change this anytime on Screen 5.", desc_id: "Mulai dengan Tunai — ubah kapan saja di Layar 5." },
];

// ---- v1.7.8: Recommended Vehicles (up to 2 EV + 2 ICE) ----
// Ecosystem -> preferred vehicle segment(s), first-pass heuristic. Not
// derived from any VKTR source data (no such mapping exists in the
// codebase) -- a reasonable starting guess meant to be tuned once real
// usage patterns are known. "others"/no match -> no segment filter, rank
// across the whole catalog instead of returning nothing.
const NEEDS_INTAKE_SEGMENT_BY_ECOSYSTEM = {
  logistics: ["LDT", "MDT"],
  mining: ["HDT", "TH"],
  public_transport: ["BUS"],
  industrial: ["MDT", "HDT"],
};

// Ranks window.VEHICLES by fit to the wizard's answers and returns up to 2
// EV + 2 ICE candidates. Payload is the primary differentiator when given
// (closest relative match to the stated cargo weight, GVW as a fallback
// proxy when a vehicle has no payload figure); price is the tiebreaker.
// With no payload answer, candidates are ranked by price alone within the
// segment filter -- a real but coarser signal than skipping the step.
function recommendVehicles(answers) {
  const segments = NEEDS_INTAKE_SEGMENT_BY_ECOSYSTEM[answers.ecosystemId] || null;
  const payloadKg = Math.max(0, Number(answers.payloadKg) || 0);
  const pool = segments ? window.VEHICLES.filter(v => segments.includes(v.segment)) : window.VEHICLES;
  const candidates = pool.length > 0 ? pool : window.VEHICLES;

  function scoreVeh(v) {
    if (payloadKg <= 0) return 0;
    if (v.payload) return Math.abs(v.payload - payloadKg) / Math.max(payloadKg, v.payload);
    if (v.gvw) return Math.abs(v.gvw - payloadKg) / Math.max(payloadKg, v.gvw) + 0.05; // proxy penalty
    return 1; // no payload/GVW at all -- rank last among same-price ties
  }

  function topN(powertrain, n) {
    return candidates
      .filter(v => v.powertrain === powertrain)
      .map(v => ({ v, score: scoreVeh(v) }))
      .sort((x, y) => x.score - y.score || (x.v.price || 0) - (y.v.price || 0))
      .slice(0, n)
      .map(x => x.v);
  }

  return { ev: topN("EV", 2), ice: topN("ICE", 2) };
}

// Builds a throwaway state for window.computeTCO -- reuses the real engine
// (not a parallel simplified formula) with DEFAULT_STATE's financial
// assumptions (WACC, diesel/electricity prices, horizon, interest, etc.)
// standing in for what Screen 5 will later collect for real. Labeled
// "Indicative" everywhere it's shown -- this is a preview, not the actual
// comparison the rest of the platform produces once real assumptions are set.
function buildPreviewState(answers, vehAId, vehBId) {
  const operatingDaysPerYear = 300;
  const fleetSize = Math.max(1, Math.round(Number(answers.fleetSize) || 1));
  const dailyKm = Math.max(0, Number(answers.dailyKm) || 0);
  const paymentMethod = answers.payment === "loan" ? "loan" : "cash";
  return {
    ...window.DEFAULT_STATE,
    vehA: vehAId, vehB: vehBId, priceA: null, priceB: null,
    ecosystemId: answers.ecosystemId || "others",
    fleetSize,
    dailyMileageKm: dailyKm, operatingDaysPerYear,
    annualKm: Math.round(dailyKm * operatingDaysPerYear),
    terrainManual: answers.terrainManual || "Flat",
    paymentA: paymentMethod, paymentB: paymentMethod,
  };
}

// Pairs ev[i] against ice[i] (index-wise) and runs the real computeTCO for
// each pair, returning a flat { vehicle, calc } list in ev/ice display
// order. calc is null if computeTCO couldn't resolve that pairing (e.g. a
// thin segment left one side without a match).
function computeRecommendationPreviews(answers, ev, ice) {
  const results = [];
  const maxLen = Math.max(ev.length, ice.length);
  for (let i = 0; i < maxLen; i++) {
    const iceVeh = ice[i] || ice[0] || null;
    const evVeh = ev[i] || ev[0] || null;
    const tco = (iceVeh && evVeh) ? window.computeTCO(buildPreviewState(answers, iceVeh.id, evVeh.id)) : null;
    if (i < ice.length) results.push({ vehicle: ice[i], calc: tco ? tco.A : null });
    if (i < ev.length) results.push({ vehicle: ev[i], calc: tco ? tco.B : null });
  }
  return results;
}

const NEEDS_INTAKE_TERRAIN_OPTIONS = [
  { id: "Flat", icon: "🛣️", en: "Flat", id_: "Datar", desc_en: "Mostly level roads.", desc_id: "Sebagian besar jalan datar." },
  { id: "Rolling", icon: "〰️", en: "Rolling", id_: "Bergelombang", desc_en: "Gentle ups and downs.", desc_id: "Naik-turun ringan." },
  { id: "Hilly", icon: "⛰️", en: "Hilly", id_: "Berbukit", desc_en: "Steep grades, mountain/mine routes.", desc_id: "Tanjakan curam, rute gunung/tambang." },
  { id: "Mixed", icon: "🔀", en: "Mixed", id_: "Campuran", desc_en: "A bit of everything along the route.", desc_id: "Campuran berbagai medan di sepanjang rute." },
];

// ---- AI mode: calls the Cloudflare Worker proxy (cf-worker/), never Anthropic directly ----
async function callNeedsIntakeAI(text) {
  if (typeof firebase === "undefined" || !firebase.auth().currentUser) throw new Error("not-signed-in");
  if (!window.API_PROXY_URL || window.API_PROXY_URL === "REPLACE_ME") throw new Error("API proxy not configured yet");
  const idToken = await firebase.auth().currentUser.getIdToken();
  const res = await fetch(window.API_PROXY_URL, {
    method: "POST",
    headers: { "Authorization": `Bearer ${idToken}`, "Content-Type": "application/json" },
    body: JSON.stringify({ action: "needs_intake_extract", text }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.error || `Request failed (${res.status})`);
  return data.extracted || {};
}

function AiIntakePanel({ onExtracted }) {
  const { lang } = useLang();
  const { user, profile, loading, signInGoogle } = useAuth();
  const [text, setText] = useState("");
  const [status, setStatus] = useState("idle"); // idle | loading | error
  const [errorMsg, setErrorMsg] = useState("");

  if (loading) return null;

  if (!user) {
    return (
      <div className="needs-intake-ai-gate">
        <p>{tr(lang, "Sign in with Google to use AI-assisted intake — this feature requires admin-approved API access.", "Masuk dengan Google untuk menggunakan isian berbasis AI — fitur ini memerlukan akses API yang disetujui admin.")}</p>
        <button type="button" className="btn btn-primary" onClick={signInGoogle}>🟢 {tr(lang, "Sign in with Google", "Masuk dengan Google")}</button>
      </div>
    );
  }

  if (!window.canUseGatedApi(profile)) {
    return (
      <WarnHint label={tr(lang, "API Unavailable", "API Tidak Tersedia")}
        note={tr(lang, "API not supported for this account. Ask your admin to enable it, or use the Quick Questions tab instead.", "API tidak didukung untuk akun ini. Minta admin mengaktifkannya, atau gunakan tab Pertanyaan Cepat.")} />
    );
  }

  const submit = async () => {
    if (!text.trim()) return;
    setStatus("loading");
    setErrorMsg("");
    try {
      const extracted = await callNeedsIntakeAI(text.trim());
      onExtracted(extracted);
      setStatus("idle");
    } catch (e) {
      setStatus("error");
      setErrorMsg(e.message || String(e));
    }
  };

  return (
    <div className="needs-intake-ai">
      <TextArea
        value={text}
        onChange={setText}
        rows={6}
        placeholder={tr(lang,
          "e.g. We run 12 diesel trucks hauling coal in Kalimantan, about 180km a day on hilly mine roads, and want to compare against VKTR EVs financed on lease.",
          "cth. Kami mengoperasikan 12 truk diesel angkut batu bara di Kalimantan, sekitar 180km per hari di rute tambang berbukit, dan ingin membandingkan dengan VKTR EV dengan skema sewa.")}
      />
      <button type="button" className="btn btn-primary" disabled={status === "loading" || !text.trim()} onClick={submit}>
        {status === "loading" ? tr(lang, "Analyzing…", "Menganalisis…") : tr(lang, "✨ Analyze with AI", "✨ Analisis dengan AI")}
      </button>
      {status === "error" && <Alert kind="error">{errorMsg}</Alert>}
    </div>
  );
}

function NeedsIntakeWizard({ onComplete, onClose }) {
  const { lang } = useLang();
  const [mode, setMode] = useState("quick"); // "quick" | "ai"
  const [step, setStep] = useState(0);
  const [answers, setAnswers] = useState({
    ecosystemId: null,
    fleetSize: "", dailyKm: "", payloadKg: "", terrainManual: null, payment: null,
  });
  const [aiNotes, setAiNotes] = useState("");
  // v1.7.8: which recommended vehicle (if any) the user tapped as A/B on the
  // Recommended Vehicles step -- both stay null if they skip it entirely,
  // preserving the pre-v1.7.8 behavior of landing on Screen 2 with nothing
  // pre-filled.
  const [selectedA, setSelectedA] = useState(null);
  const [selectedB, setSelectedB] = useState(null);
  const pickAsA = (vehId) => { setSelectedA(vehId); if (selectedB === vehId) setSelectedB(null); };
  const pickAsB = (vehId) => { setSelectedB(vehId); if (selectedA === vehId) setSelectedA(null); };

  const questions = getIntakeQuestions(answers);
  // v1.7.8: a "Recommended Vehicles" step is inserted between the last real
  // question and the final summary -- recoStep shows it, last (the summary)
  // is now one index further out than before.
  const recoStep = questions.length;
  const last = step === questions.length + 1;
  const q = questions[step];
  const setA = (k, v) => setAnswers(a => ({ ...a, [k]: v }));

  const isAnswered = (key) => {
    if (key === "fleetSize") return Number(answers.fleetSize) > 0;
    if (key === "dailyKm") return Number(answers.dailyKm) > 0;
    if (key === "payloadKg") return true; // optional -- doesn't apply to passenger/bus fleets
    return !!answers[key];
  };
  const canNext = !q || isAnswered(q.key);

  // AI extraction lands here: merge whatever fields Claude confidently
  // returned (never overwrite with null/undefined), then jump straight to
  // the Recommended Vehicles step for review — nothing from the AI is auto-applied.
  const handleExtracted = (extracted) => {
    const merged = { ...answers };
    if (extracted.ecosystemId) merged.ecosystemId = extracted.ecosystemId;
    if (extracted.fleetSize) merged.fleetSize = String(extracted.fleetSize);
    if (extracted.dailyKm) merged.dailyKm = String(extracted.dailyKm);
    if (extracted.terrainManual) merged.terrainManual = extracted.terrainManual;
    if (extracted.payment) merged.payment = extracted.payment;
    setAnswers(merged);
    setAiNotes(extracted.confidence_notes || "");
    setMode("quick");
    setStep(getIntakeQuestions(merged).length); // summary index for the merged answer set
  };

  const finish = () => {
    // v1.9.5 (2026-07-17): SUPERSEDES the v1.8 comment this replaced, which
    // deliberately left ritaseDistanceKm unset here (RD=0, the platform
    // default) reasoning that guessing a Ritase Distance from one coarse
    // daily-km answer would "fabricate precision." That left Screen 3's
    // Annual Mileage permanently stuck on "Not Yet Computed" (raw-editable)
    // for anyone who picked a vehicle via this wizard -- directly
    // contradicting Rija's explicit v1.9.4 mandate ("I WANT THE ANNUAL
    // MILEAGE TO BE AUTOMATED ... DO NOT MAKE ANNUAL MILEAGE USER
    // EDITABLE"), reported as still "screwed up" after picking A/B here.
    // Seeding ritaseDistanceKm = dailyKm (same rough-estimate tier as
    // dailyMileageKm/annualKm below, already labeled "indicative only,
    // refine on Screen 5" throughout this wizard) lets the real
    // Ritase-Cycle Engine / resolveAutoAnnualMileage (data.jsx) take over
    // immediately instead of blocking -- the user refines the real Ritase
    // Distance on Screen 3, same as before, just starting from a computed
    // number instead of a stuck one.
    const operatingDaysPerYear = 300;
    const fleetSize = Math.max(1, Math.round(Number(answers.fleetSize) || 1));
    const dailyKm = Math.max(0, Number(answers.dailyKm) || 0);
    // "Lease" isn't a real payment-method value (removed with the old
    // Commercial Scheme Ladder) -- the vehicle itself is still bought cash
    // (no customer-side loan), and the actual "VKTR bears the capital"
    // arrangement is expressed through the Expense Bucket Toggle instead.
    const paymentMethod = answers.payment === "loan" ? "loan" : "cash";
    const leaseChosen = answers.payment === "lease";
    const sewaUnitPreset = window.EXPENSE_BUCKET_PRESETS.find(p => p.id === "sewa_unit");
    onComplete({
      ecosystemId: answers.ecosystemId,
      approxFleetSize: fleetSize,
      fleetSize,
      dailyMileageKm: dailyKm,
      ritaseDistanceKm: dailyKm,
      operatingDaysPerYear,
      annualKm: Math.round(dailyKm * operatingDaysPerYear),
      terrainManual: answers.terrainManual || "Flat",
      paymentA: paymentMethod,
      paymentB: paymentMethod,
      ...(leaseChosen && sewaUnitPreset ? { expenseBucketState: { ...sewaUnitPreset.state } } : {}),
      // v1.7.8: only set if the user actually tapped a pick on the
      // Recommended Vehicles step -- otherwise vehA/vehB stay untouched,
      // same as before that step existed.
      ...(selectedA ? { vehA: selectedA } : {}),
      ...(selectedB ? { vehB: selectedB } : {}),
    });
  };

  return (
    <div className="preset-modal-overlay" onClick={onClose}>
      <div className={"preset-modal needs-intake-modal" + (mode === "quick" && step === recoStep ? " wide" : "")} onClick={e => e.stopPropagation()}>
        <div className="preset-modal-head">
          <h3>🧭 {tr(lang, "Quick Needs Assessment", "Penilaian Kebutuhan Cepat")}</h3>
          <button className="btn btn-ghost" onClick={onClose}>✕</button>
        </div>

        <div className="needs-intake-mode-toggle">
          <PillToggle
            value={mode}
            onChange={setMode}
            left={{ value: "quick", icon: "📝 ", label: tr(lang, "Quick Questions", "Pertanyaan Cepat") }}
            right={{ value: "ai", icon: "✨ ", label: tr(lang, "Describe in Your Words", "Jelaskan Sendiri") }}
          />
        </div>

        {mode === "ai" ? (
          <AiIntakePanel onExtracted={handleExtracted} />
        ) : (
          <>
            <div className="needs-intake-progress">
              {questions.map((_, i) => (
                <div key={i} className={"needs-intake-dot" + (i === step ? " active" : i < step ? " done" : "")} />
              ))}
            </div>

            {step < recoStep ? (
              <div className="needs-intake-step">
                <div className="needs-intake-question">{tr(lang, q.en, q.id)}</div>

                {q.key === "ecosystemId" && (
                  <div className="option-card-grid">
                    {window.ECOSYSTEM_OPTIONS.map(eco => (
                      <div key={eco.id} className={"option-card" + (answers.ecosystemId === eco.id ? " active" : "")}
                        onClick={() => setA("ecosystemId", eco.id)}>
                        <div className="oc-icon">{eco.icon}</div>
                        <div className="oc-label">{tr(lang, eco.label, eco.labelId)}</div>
                      </div>
                    ))}
                  </div>
                )}

                {q.key === "fleetSize" && (
                  <div className="needs-intake-input">
                    <AffixInput value={answers.fleetSize} suffix={tr(lang, "vehicles", "kendaraan")}
                      placeholder="e.g. 20"
                      onChange={v => setA("fleetSize", v.replace(/\D/g, ""))} />
                  </div>
                )}

                {q.key === "dailyKm" && (
                  <div className="needs-intake-input">
                    <AffixInput value={answers.dailyKm} suffix="km/day"
                      placeholder="e.g. 150"
                      onChange={v => setA("dailyKm", v.replace(/\D/g, ""))} />
                    <div className="needs-intake-hint">
                      {tr(lang, "Rough estimate is fine — you can refine this later on the Operation screen.", "Perkiraan kasar tidak masalah — Anda bisa menyempurnakannya nanti di layar Operasi.")}
                    </div>
                  </div>
                )}

                {q.key === "payloadKg" && (
                  <div className="needs-intake-input">
                    <AffixInput value={answers.payloadKg} suffix="kg"
                      placeholder="e.g. 5000"
                      onChange={v => setA("payloadKg", v.replace(/\D/g, ""))} />
                    <div className="needs-intake-hint">
                      {tr(lang, "Optional — leave blank if not applicable (e.g. passenger transport). Sharpens the vehicle suggestions on the next step.", "Opsional — kosongkan jika tidak relevan (mis. transportasi penumpang). Mempertajam usulan kendaraan pada langkah berikutnya.")}
                    </div>
                  </div>
                )}

                {q.key === "terrainManual" && (
                  <div className="option-card-grid">
                    {NEEDS_INTAKE_TERRAIN_OPTIONS.map(t => (
                      <div key={t.id} className={"option-card" + (answers.terrainManual === t.id ? " active" : "")}
                        onClick={() => setA("terrainManual", t.id)}>
                        <div className="oc-icon">{t.icon}</div>
                        <div className="oc-label">{tr(lang, t.en, t.id_)}</div>
                        <div className="oc-desc">{tr(lang, t.desc_en, t.desc_id)}</div>
                      </div>
                    ))}
                  </div>
                )}

                {q.key === "payment" && (
                  <div className="option-card-grid">
                    {NEEDS_INTAKE_PAYMENT_OPTIONS.map(p => (
                      <div key={p.id} className={"option-card" + (answers.payment === p.id ? " active" : "")}
                        onClick={() => setA("payment", p.id)}>
                        <div className="oc-icon">{p.icon}</div>
                        <div className="oc-label">{tr(lang, p.en, p.id_)}</div>
                        <div className="oc-desc">{tr(lang, p.desc_en, p.desc_id)}</div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            ) : step === recoStep ? (
              <div className="needs-intake-step">
                <div className="needs-intake-question">
                  {tr(lang, "Recommended Vehicles", "Kendaraan yang Disarankan")}
                </div>
                <div className="needs-intake-reco-hint">
                  {tr(lang,
                    "Based on your answers — indicative only, using default financial assumptions (refine on Screen 5). Tap a card to set it as Vehicle A or B, or skip and pick manually on the next screen.",
                    "Berdasarkan jawaban Anda — hanya indikatif, memakai asumsi keuangan default (sempurnakan di Layar 5). Ketuk kartu untuk menjadikannya Kendaraan A atau B, atau lewati dan pilih manual di layar berikutnya.")}
                </div>
                {(() => {
                  const reco = recommendVehicles(answers);
                  const previews = computeRecommendationPreviews(answers, reco.ev, reco.ice);
                  if (previews.length === 0) {
                    return (
                      <Alert kind="info">
                        {tr(lang, "No matching vehicles found for this industry yet — skip ahead and pick manually on the next screen.", "Belum ada kendaraan yang cocok untuk industri ini — lewati dan pilih manual di layar berikutnya.")}
                      </Alert>
                    );
                  }
                  return (
                    <div className="needs-intake-reco-grid">
                      {previews.map(({ vehicle: v, calc }) => {
                        const isA = selectedA === v.id, isB = selectedB === v.id;
                        return (
                          <div key={v.id} className={"needs-intake-reco-card" + (isA ? " picked-a" : "") + (isB ? " picked-b" : "")}>
                            <div className="needs-intake-reco-head">
                              <div>
                                <div className="needs-intake-reco-name">{v.name}</div>
                                <div className="needs-intake-reco-brand">{v.brand}</div>
                              </div>
                              <Badge kind={v.powertrain === "EV" ? "ev" : "ice"}>{v.powertrain}</Badge>
                            </div>
                            <div className="needs-intake-reco-rows">
                              <div className="r"><span>{tr(lang, "Price", "Harga")}</span><b>{fmt.rpShort(v.price || 0)}</b></div>
                              <div className="r"><span>GVW</span><b>{fmt.num(v.gvw || 0)} kg</b></div>
                              <div className="r"><span>{tr(lang, "Payload", "Muatan")}</span><b>{v.payload ? `${fmt.num(v.payload)} kg` : "—"}</b></div>
                              <div className="r"><span>{tr(lang, "Power", "Daya")}</span><b>{v.power ? `${fmt.num(v.power)} kW` : "—"}</b></div>
                              <div className="r"><span>{tr(lang, "Energy", "Energi")}</span><b>{v.energy}</b></div>
                            </div>
                            <div className="needs-intake-reco-tco">
                              {calc ? (
                                <>{tr(lang, "Indicative", "Indikatif")} {window.DEFAULT_STATE.horizon}{tr(lang, "yr TCO", "th TCO")}: {fmt.rpShort(calc.tco)}</>
                              ) : (
                                <span style={{ color: "var(--text-muted)", fontWeight: 400 }}>{tr(lang, "Estimate unavailable", "Estimasi tidak tersedia")}</span>
                              )}
                            </div>
                            <div className="needs-intake-reco-picks">
                              <button type="button" className={isA ? "on-a" : ""} onClick={() => pickAsA(v.id)}>{tr(lang, "Set as A", "Jadikan A")}</button>
                              <button type="button" className={isB ? "on-b" : ""} onClick={() => pickAsB(v.id)}>{tr(lang, "Set as B", "Jadikan B")}</button>
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  );
                })()}
              </div>
            ) : (
              <div className="needs-intake-step">
                <div className="needs-intake-question">
                  {tr(lang, "Ready to build your comparison", "Siap membuat perbandingan Anda")}
                </div>
                {aiNotes && (
                  <Alert kind="info">
                    <b>{tr(lang, "AI notes:", "Catatan AI:")}</b> {aiNotes}
                  </Alert>
                )}
                <div className="needs-intake-summary">
                  <div><b>{tr(lang, "Industry", "Industri")}:</b> {(window.ECOSYSTEM_OPTIONS.find(e => e.id === answers.ecosystemId) || {}).icon} {tr(lang, (window.ECOSYSTEM_OPTIONS.find(e => e.id === answers.ecosystemId) || {}).label, (window.ECOSYSTEM_OPTIONS.find(e => e.id === answers.ecosystemId) || {}).labelId)}</div>
                  <div><b>{tr(lang, "Fleet size", "Ukuran armada")}:</b> {answers.fleetSize} {tr(lang, "vehicles", "kendaraan")}</div>
                  <div><b>{tr(lang, "Daily mileage", "Jarak harian")}:</b> {answers.dailyKm} km/day (~{fmt.num(Math.round((Number(answers.dailyKm) || 0) * 300))} km/{tr(lang, "yr", "thn")})</div>
                  {Number(answers.payloadKg) > 0 && (
                    <div><b>{tr(lang, "Payload", "Muatan")}:</b> {fmt.num(Number(answers.payloadKg))} kg</div>
                  )}
                  <div><b>{tr(lang, "Terrain", "Medan")}:</b> {tr(lang, (NEEDS_INTAKE_TERRAIN_OPTIONS.find(t => t.id === answers.terrainManual) || {}).en, (NEEDS_INTAKE_TERRAIN_OPTIONS.find(t => t.id === answers.terrainManual) || {}).id_)}</div>
                  <div><b>{tr(lang, "Payment", "Pembayaran")}:</b> {tr(lang, (NEEDS_INTAKE_PAYMENT_OPTIONS.find(p => p.id === answers.payment) || {}).en, (NEEDS_INTAKE_PAYMENT_OPTIONS.find(p => p.id === answers.payment) || {}).id_)}</div>
                  {(selectedA || selectedB) && (
                    <div><b>{tr(lang, "Vehicles picked", "Kendaraan dipilih")}:</b>{" "}
                      {selectedA ? `A: ${(window.findVeh(selectedA) || {}).name || selectedA}` : tr(lang, "A: (pick on next screen)", "A: (pilih di layar berikutnya)")}
                      {" · "}
                      {selectedB ? `B: ${(window.findVeh(selectedB) || {}).name || selectedB}` : tr(lang, "B: (pick on next screen)", "B: (pilih di layar berikutnya)")}
                    </div>
                  )}
                </div>
                <Alert kind="info">
                  <Tr en="This starts a new profile using these answers. You'll land on Vehicle Selection to pick the exact models being compared — everything else stays fully editable."
                      id="Ini memulai profil baru menggunakan jawaban ini. Anda akan diarahkan ke Pemilihan Kendaraan untuk memilih model yang dibandingkan — semua yang lain tetap dapat diedit." />
                </Alert>
              </div>
            )}

            <div className="needs-intake-nav">
              <button className="btn btn-ghost" disabled={step === 0} onClick={() => setStep(s => Math.max(0, s - 1))}>
                {tr(lang, "Back", "Kembali")}
              </button>
              {!last ? (
                <button className="btn btn-primary" disabled={!canNext} onClick={() => setStep(s => s + 1)}>
                  {tr(lang, "Next", "Lanjut")}
                </button>
              ) : (
                <button className="btn btn-primary" onClick={finish}>
                  {tr(lang, "Start My Comparison", "Mulai Perbandingan Saya")}
                </button>
              )}
            </div>
          </>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { NeedsIntakeWizard });
