// Scan input pages — one unique form per scan type, plus the loading screen.

const { useState: useStateI, useRef: useRefI, useEffect: useEffectI } = React;

// ============================================================
// Shared chrome for a scan input page
// ============================================================
function ScanPageShell({ scan, balance, headline, sub, costNote, onBack, children }) {
  const Icon = window[scan.icon] || IconScan;
  const enough = balance >= scan.cost;
  // Banner header art per product (replaces the icon + title + subtitle)
  const SCAN_BANNERS = {
    "new-person":   "assets/headers/person-check.jpg",
    "face":         "assets/headers/face.jpg",
    "dating-app":   "assets/headers/dating-app.jpg",
    "tinder-sonar": "assets/headers/tinder-sonar.jpg"
  };
  const banner = SCAN_BANNERS[scan.id];
  // Darker product colors keep a near-black headline; vivid ones colorize it.
  const darkHeadline = scan.id === "new-person" || scan.id === "face";
  return (
    <div
      className="scanpage"
      data-screen-label={"03 Scan Input — " + scan.name}
      style={{
        ['--accent']: scan.color,
        ['--icon-tint']: scan.color,
        ['--headline-color']: darkHeadline ? "var(--sw-fg-strong)" : scan.color
      }}
    >
      <button className="linkback" onClick={onBack}>
        <IconArrowLeft size={14} />
        Back to Dashboard
      </button>

      <div className={"scanpage__head" + (banner ? " scanpage__head--banner" : "")}>
        {banner ? (
          <img className="scanpage__banner" src={banner} alt={scan.name} />
        ) : (
          <div className="scanpage__head-left">
            <span className="scanpage__icon" style={{ ['--icon-tint']: scan.color }}><Icon size={26} /></span>
            <div>
              <h1 className="scanpage__title">{headline || scan.name}</h1>
              <p className="scanpage__sub">{sub || scan.desc}</p>
            </div>
          </div>
        )}
        <div className={"costreminder" + (enough ? "" : " costreminder--low")}>
          <div className="costreminder__label">This scan costs</div>
          <div className="costreminder__amt">
            <IconChip size={14} /> {formatTokens(scan.cost)} tokens
          </div>
          <div className="costreminder__bal">
            You have <strong>{formatTokens(balance)}</strong>
          </div>
          {costNote && <div className="costreminder__note">{costNote}</div>}
        </div>
      </div>

      {children}

      <div className="scanpage__assure">
        <IconLock size={14} />
        <span>100% Anonymous. We only search publicly available data.</span>
      </div>
    </div>
  );
}

function CtaBlock({ label, hint, disabled, onClick }) {
  return (
    <div className="scanpage__cta-wrap">
      <button className="sw-btn sw-btn--lg" onClick={onClick} disabled={disabled}>
        {label} <IconArrowRight size={16} />
      </button>
      <div className="scanpage__hint">{hint}</div>
    </div>
  );
}

// ============================================================
// 1. Dating App Scan — platform chips + example preview
// ============================================================
const DATING_APP_PLATFORMS = ["Tinder", "Bumble", "Hinge", "Match.com", "OnlyFans", "43 others"];
function DatingAppScanInput({ scan, balance, onBack, onSubmit, onTopUp }) {
  const [form, setForm] = useStateI({ name: "", age: "", city: "" });
  const [platforms, setPlatforms] = useStateI(new Set(DATING_APP_PLATFORMS));
  const [exampleOpen, setExampleOpen] = useStateI(false);
  const enough = balance >= scan.cost;
  const valid = form.name.trim() && platforms.size > 0;

  const toggle = (p) => {
    const next = new Set(platforms);
    if (next.has(p)) next.delete(p); else next.add(p);
    setPlatforms(next);
  };

  const tryRun = () => {
    if (!valid) return;
    if (!enough) { onTopUp && onTopUp(); return; }
    onSubmit(scan, { ...form, platforms: Array.from(platforms) });
  };

  return (
    <ScanPageShell scan={scan} balance={balance} onBack={onBack} headline="Find out what they're hiding.">
      <form className="sw-card scanpage__form" onSubmit={(e) => { e.preventDefault(); tryRun(); }}>
        <FormField label="Full name" required>
          <input className="sw-input sw-input--field" placeholder="e.g. Alex Morgan"
            value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })}/>
        </FormField>
        <div className="form-grid form-grid--narrow">
          <FormField label="Age" hint="Optional">
            <input className="sw-input sw-input--field" inputMode="numeric" placeholder="e.g. 32"
              value={form.age} onChange={(e) => setForm({ ...form, age: e.target.value })}/>
          </FormField>
          <FormField label="City / Location" hint="City, state, or metro">
            <input className="sw-input sw-input--field" placeholder="e.g. Brooklyn, NY"
              value={form.city} onChange={(e) => setForm({ ...form, city: e.target.value })}/>
          </FormField>
        </div>
        <div className="field">
          <div className="field__label">Platforms to scan
            <span className="field__hint"> · {platforms.size}/{DATING_APP_PLATFORMS.length} selected</span>
          </div>
          <div className="chip-row">
            {DATING_APP_PLATFORMS.map(p => (
              <button type="button" key={p}
                className={"toggle-chip" + (platforms.has(p) ? " is-on" : "")}
                onClick={() => toggle(p)}>
                {platforms.has(p) && <IconCheck size={12} />}
                {p}
              </button>
            ))}
          </div>
        </div>

        <CtaBlock
          label={enough
            ? `Start Dating App Scan — ${formatTokens(scan.cost)} tokens`
            : `Not enough tokens — Top Up`}
          hint="We'll sweep 40+ platforms and surface any hidden activity."
          disabled={!valid}
          onClick={tryRun}
        />

        <DatingAppExamplePreview onOpen={() => setExampleOpen(true)} />
      </form>
      <DatingAppExampleModal open={exampleOpen} onClose={() => setExampleOpen(false)} />
    </ScanPageShell>
  );
}

// ============================================================
// 2. Face Scan — photo upload + scan intent
// ============================================================
const FACE_INTENTS = [
  "Find all online profiles",
  "Check for dating app presence",
  "Identify who this person is",
  "Find lookalikes"
];
function FaceScanInput({ scan, balance, onBack, onSubmit, onTopUp }) {
  const [photo, setPhoto] = useStateI(null);
  const [photoUrl, setPhotoUrl] = useStateI(null);
  const [intent, setIntent] = useStateI("");
  const [dragOver, setDragOver] = useStateI(false);
  const [exampleOpen, setExampleOpen] = useStateI(false);
  const [waiverOpen, setWaiverOpen] = useStateI(false);
  const inputRef = useRefI(null);
  const enough = balance >= scan.cost;

  const pick = (file) => {
    if (!file) return;
    setPhoto({ name: file.name, size: (file.size / 1024 / 1024).toFixed(1) + " MB" });
    try { setPhotoUrl(URL.createObjectURL(file)); } catch (e) {}
  };

  const handleDrop = (e) => {
    e.preventDefault();
    setDragOver(false);
    const f = e.dataTransfer.files && e.dataTransfer.files[0];
    if (f) pick(f);
  };

  const valid = !!photo && !!intent;
  const tryRun = () => {
    if (!valid) return;
    if (!enough) { onTopUp && onTopUp(); return; }
    setWaiverOpen(true);
  };

  const handleAgree = () => {
    setWaiverOpen(false);
    onSubmit(scan, { photo, photoUrl, intent });
  };

  return (
    <ScanPageShell scan={scan} balance={balance} onBack={onBack}>
      <form className="sw-card scanpage__form" onSubmit={(e) => { e.preventDefault(); tryRun(); }}>
        {!photo ? (
          <div
            className={"dropzone" + (dragOver ? " is-drag" : "")}
            onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
            onDragLeave={() => setDragOver(false)}
            onDrop={handleDrop}
            onClick={() => inputRef.current && inputRef.current.click()}
          >
            <span className="dropzone__icon">
              <IconImage size={32} />
            </span>
            <div className="dropzone__title">Drop a photo here or click to upload</div>
            <div className="dropzone__sub">JPG, PNG or HEIC · Max 10MB · Face must be visible</div>
            <input ref={inputRef} type="file" accept="image/*" hidden onChange={(e) => pick(e.target.files[0])}/>
          </div>
        ) : (
          <div className="filepicked">
            <div className="filepicked__thumb">
              {photoUrl ? (
                <img src={photoUrl} alt="" />
              ) : (
                <IconImage size={26} />
              )}
            </div>
            <div className="filepicked__body">
              <div className="filepicked__name">
                <IconCheck size={14} /> {photo.name}
              </div>
              <div className="filepicked__meta">{photo.size} · Ready to scan</div>
            </div>
            <button type="button" className="sw-btn sw-btn--ghost sw-btn--sm" onClick={() => { setPhoto(null); setPhotoUrl(null); }}>
              Replace
            </button>
          </div>
        )}

        <FormField label="What are you looking for?">
          <div className="select-wrap">
            <select
              className={"sw-input sw-input--field sw-select" + (intent ? "" : " sw-select--empty")}
              value={intent} onChange={(e) => setIntent(e.target.value)}>
              <option value="">Choose a goal for this scan…</option>
              {FACE_INTENTS.map(opt => <option key={opt} value={opt}>{opt}</option>)}
            </select>
            <span className="select-wrap__chev"><IconChevronDown size={14} /></span>
          </div>
        </FormField>

        <FaceScanExamplePreview onOpen={() => setExampleOpen(true)} />

        <CtaBlock
          label={enough
            ? `Run Face Scan — ${formatTokens(scan.cost)} tokens`
            : `Not enough tokens — Top Up`}
          hint="Results ready in under 3 minutes. 100% anonymous."
          disabled={!valid}
          onClick={tryRun}
        />
      </form>
      <FaceScanExampleModal open={exampleOpen} onClose={() => setExampleOpen(false)} />
      <FaceWaiverModal
        open={waiverOpen}
        onClose={() => setWaiverOpen(false)}
        onAgree={handleAgree}
        scan={scan}
      />
    </ScanPageShell>
  );
}

// ============================================================
// 3. New Person Check — unified form with confidence indicator
// ============================================================
const NPC_AGE_RANGES = ["Under 20", "20–25", "25–30", "30–35", "35–40", "40–50", "50+"];
const NPC_SOCIAL_FIELDS = [
  { key: "linkedin",  label: "LinkedIn",    logo: SOCIAL_LOGOS.linkedin,  placeholder: "LinkedIn profile or username" },
  { key: "facebook",  label: "Facebook",    logo: SOCIAL_LOGOS.facebook,  placeholder: "Facebook profile or username" },
  { key: "instagram", label: "Instagram",   logo: SOCIAL_LOGOS.instagram, placeholder: "Instagram handle" },
  { key: "twitter",   label: "X (Twitter)", logo: SOCIAL_LOGOS.x,         placeholder: "X / Twitter handle" }
];

function NewPersonCheckInput({ scan, balance, onBack, onSubmit, onTopUp }) {
  const [form, setForm] = useStateI({
    first: "", last: "", alias: "", email: "", phone: "",
    ageRange: "", location: "", socialMedia: false,
    linkedin: "", facebook: "", instagram: "", twitter: ""
  });
  const [exampleOpen, setExampleOpen] = useStateI(false);
  const enough = balance >= scan.cost;

  // Confidence: 5+ filled fields = 90-100%, scale ~20% per field
  const filledCount =
    (form.first.trim() ? 1 : 0) +
    (form.last.trim() ? 1 : 0) +
    (form.alias.trim() ? 1 : 0) +
    (form.email.trim() ? 1 : 0) +
    (form.phone.trim() ? 1 : 0) +
    (form.ageRange ? 1 : 0) +
    (form.location.trim() ? 1 : 0) +
    (form.socialMedia ? 1 : 0);
  const confidence = Math.min(100, filledCount * 20);
  const confTone =
    filledCount === 0 ? "empty"
    : filledCount < 5 ? "blue"
    : "green";
  const confLabel =
    filledCount === 0 ? "Add at least one detail to search"
    : filledCount === 1 ? "Good start — results may be broad"
    : filledCount === 2 ? "Looking better — keep going"
    : filledCount < 5 ? "Getting better — results are narrowing"
    : "Great — we have a lot to work with";

  const valid = filledCount >= 1;
  const submit = () => {
    if (!valid) return;
    if (!enough) { onTopUp && onTopUp(); return; }
    const name = [form.first, form.last].filter(Boolean).join(" ").trim()
      || form.alias || form.email || form.phone || null;
    onSubmit(scan, { ...form, name });
  };

  const set = (k) => (e) => setForm({ ...form, [k]: e.target.value });

  let ctaLabel;
  if (filledCount === 0)      ctaLabel = "Fill in at least one field to search";
  else if (!enough)           ctaLabel = "Not enough tokens — Top Up";
  else                        ctaLabel = `Run Person Check — ${formatTokens(scan.cost)} tokens`;

  return (
    <ScanPageShell
      scan={scan}
      balance={balance}
      onBack={onBack}
      headline="Who are you looking for?"
      sub="Enter whatever you know — the more you add, the more accurate your results."
      costNote="Covers identity, location, social, dating activity and public records."
    >
      <div className="scanpage__note">
        <IconInfo size={12} />
        Fill in whatever you have — even just a first name is enough to start.
      </div>

      <form className="sw-card npc-form" onSubmit={(e) => { e.preventDefault(); submit(); }}>
        {/* Confidence bar — pinned to the top */}
        <div className={"npc-conf npc-conf--top npc-conf--" + confTone}>
          <div className="npc-conf__track">
            <span className="npc-conf__fill" style={{ width: confidence + "%" }} />
          </div>
          <div className="npc-conf__label">{confLabel}</div>
        </div>

        {/* Group 1 — Who they are */}
        <div className="npc-group">
          <div className="npc-input">
            <span className="npc-input__ico"><IconUser size={16} /></span>
            <input className="sw-input npc-field" placeholder="What's their first name?"
              value={form.first} onChange={set("first")} aria-label="First name" />
          </div>
          <div className="npc-input">
            <span className="npc-input__ico"><IconUser size={16} /></span>
            <input className="sw-input npc-field" placeholder="And their last name?"
              value={form.last} onChange={set("last")} aria-label="Last name" />
          </div>
          <div className="npc-input">
            <span className="npc-input__ico"><IconTag size={16} /></span>
            <input className="sw-input npc-field" placeholder="Any nickname or alias they go by?"
              value={form.alias} onChange={set("alias")} aria-label="Nickname or alias" />
          </div>
        </div>

        {/* Group 2 — How to find them */}
        <div className="npc-group">
          <div className="npc-input">
            <span className="npc-input__ico"><IconMail size={16} /></span>
            <input className="sw-input npc-field" type="email" placeholder="Their email address if you have it"
              value={form.email} onChange={set("email")} aria-label="Email" />
          </div>
          <div className="npc-input">
            <span className="npc-input__ico"><IconPhone size={16} /></span>
            <input className="sw-input npc-field" inputMode="tel" placeholder="A phone number helps a lot"
              value={form.phone} onChange={set("phone")} aria-label="Phone number" />
          </div>
          <div className="npc-input npc-input--select">
            <span className="npc-input__ico"><IconCalendar size={16} /></span>
            <select
              className={"sw-input npc-field npc-select" + (form.ageRange ? "" : " npc-select--empty")}
              value={form.ageRange} onChange={set("ageRange")} aria-label="Age range">
              <option value="">Roughly how old are they?</option>
              {NPC_AGE_RANGES.map(a => <option key={a} value={a}>{a}</option>)}
            </select>
            <span className="npc-input__chev"><IconChevronDown size={14} /></span>
          </div>
          <div className="npc-input">
            <span className="npc-input__ico"><IconMapPin size={16} /></span>
            <input className="sw-input npc-field" placeholder="What city are they in?"
              value={form.location} onChange={set("location")} aria-label="Location" />
          </div>

          <button
            type="button"
            role="switch"
            aria-checked={form.socialMedia}
            className={"npc-toggle" + (form.socialMedia ? " is-on" : "")}
            onClick={() => setForm({ ...form, socialMedia: !form.socialMedia })}
          >
            <span className="npc-toggle__ico"><IconGlobe size={18} /></span>
            <div className="npc-toggle__body">
              <div className="npc-toggle__title">Add their social media accounts</div>
              <div className="npc-toggle__sub">Know their handles? Add them so we can pinpoint the right profiles.</div>
            </div>
            <span className={"settings-switch" + (form.socialMedia ? " is-on" : "")} aria-hidden>
              <span className="settings-switch__thumb" />
            </span>
          </button>

          {form.socialMedia && (
            <div className="npc-socials-fields">
              {NPC_SOCIAL_FIELDS.map(f => (
                <div className="npc-input" key={f.key}>
                  <span className="npc-input__ico npc-input__ico--logo"><img src={f.logo} alt="" /></span>
                  <input className="sw-input npc-field" placeholder={f.placeholder}
                    value={form[f.key]} onChange={set(f.key)} aria-label={f.label} />
                </div>
              ))}
            </div>
          )}
        </div>

        <NewPersonExamplePreview onOpen={() => setExampleOpen(true)} />

        <CtaBlock
          label={ctaLabel}
          hint="Results ready in under 2 minutes. 100% anonymous."
          disabled={!valid}
          onClick={submit}
        />
      </form>
      <NewPersonExampleModal open={exampleOpen} onClose={() => setExampleOpen(false)} />
    </ScanPageShell>
  );
}

// ============================================================
// 5. Relationship Status — context toggle
// ============================================================
function RelationshipStatusInput({ scan, balance, onBack, onSubmit, onTopUp }) {
  const [form, setForm] = useStateI({ name: "", age: "", city: "" });
  const [context, setContext] = useStateI("personal"); // personal | online
  const enough = balance >= scan.cost;
  const valid = form.name.trim() && form.city.trim();
  const tryRun = () => {
    if (!valid) return;
    if (!enough) { onTopUp && onTopUp(); return; }
    onSubmit(scan, { ...form, context });
  };

  const hint = context === "personal"
    ? "We'll check their dating activity and recent social signals across your shared network."
    : "We'll check dating apps, public profiles, and signals from how they present themselves online.";

  return (
    <ScanPageShell scan={scan} balance={balance} onBack={onBack} headline="Is someone off the market?">
      <div className="sw-card scanpage__form">
        <FormField label="Full name" required>
          <input className="sw-input sw-input--field" placeholder="e.g. Alex Morgan"
            value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })}/>
        </FormField>
        <div className="form-grid form-grid--narrow">
          <FormField label="Age" hint="Optional">
            <input className="sw-input sw-input--field" inputMode="numeric" placeholder="e.g. 32"
              value={form.age} onChange={(e) => setForm({ ...form, age: e.target.value })}/>
          </FormField>
          <FormField label="City" required>
            <input className="sw-input sw-input--field" placeholder="e.g. Brooklyn, NY"
              value={form.city} onChange={(e) => setForm({ ...form, city: e.target.value })}/>
          </FormField>
        </div>
        <div className="field">
          <div className="field__label">How do you know them?</div>
          <div className="segmented">
            <button type="button"
              className={"segmented__opt" + (context === "personal" ? " is-on" : "")}
              onClick={() => setContext("personal")}>
              <IconUser size={14} /> I know them personally
            </button>
            <button type="button"
              className={"segmented__opt" + (context === "online" ? " is-on" : "")}
              onClick={() => setContext("online")}>
              <IconLink size={14} /> I met them online
            </button>
          </div>
        </div>
        <CtaBlock
          label={enough
            ? `Check Relationship Status — ${formatTokens(scan.cost)} tokens`
            : `Not enough tokens — Top Up`}
          hint={hint}
          disabled={!valid}
          onClick={tryRun}
        />
      </div>
    </ScanPageShell>
  );
}

// ============================================================
// 6. Tinder Sonar — check if ex / target has seen your profile
// ============================================================
function TinderSonarInput({ scan, balance, onBack, onSubmit, onTopUp }) {
  const [form, setForm] = useStateI({ first: "", age: "", loc1: "", loc2: "" });
  const [secondLocOpen, setSecondLocOpen] = useStateI(false);
  const [gender, setGender] = useStateI(null); // "woman" | "man" — no default
  const [photo, setPhoto] = useStateI(null);
  const [photoUrl, setPhotoUrl] = useStateI(null);
  const [dragOver, setDragOver] = useStateI(false);
  const [exampleOpen, setExampleOpen] = useStateI(false);
  const photoInputRef = useRefI(null);
  const enough = balance >= scan.cost;
  const valid = form.first.trim() && gender;

  const pickPhoto = (file) => {
    if (!file) return;
    setPhoto({ name: file.name, size: (file.size / 1024 / 1024).toFixed(1) + " MB" });
    try { setPhotoUrl(URL.createObjectURL(file)); } catch (e) {}
  };
  const clearPhoto = () => { setPhoto(null); setPhotoUrl(null); };
  const handleDrop = (e) => {
    e.preventDefault();
    setDragOver(false);
    const f = e.dataTransfer.files && e.dataTransfer.files[0];
    if (f) pickPhoto(f);
  };

  const removeSecondLoc = () => {
    setSecondLocOpen(false);
    setForm({ ...form, loc2: "" });
  };

  const tryRun = () => {
    if (!valid) return;
    if (!enough) { onTopUp && onTopUp(); return; }
    onSubmit(scan, {
      ...form,
      name: form.first,
      locations: [form.loc1, form.loc2].filter(Boolean),
      gender,
      photo,
      photoUrl
    });
  };

  return (
    <ScanPageShell
      scan={scan}
      balance={balance}
      onBack={onBack}
      headline="Tinder Sonar"
      sub="We'll detect whether this person has seen your Tinder profile, swiped left, or gone inactive."
    >
      <form className="sw-card scanpage__form scanpage__form--tinder" onSubmit={(e) => { e.preventDefault(); tryRun(); }}>
        <div className="form-grid form-grid--narrow">
          <FormField label="First name" required>
            <input className="sw-input sw-input--field" placeholder="e.g. Alex"
              value={form.first} onChange={(e) => setForm({ ...form, first: e.target.value })}/>
          </FormField>
          <FormField label="Age" hint="Optional">
            <input className="sw-input sw-input--field" inputMode="numeric" placeholder="e.g. 29"
              value={form.age} onChange={(e) => setForm({ ...form, age: e.target.value })}/>
          </FormField>
        </div>

        <div className="field">
          <div className="field__label">City / Location</div>
          <div className="loc-stack">
            <input className="sw-input sw-input--field" placeholder="e.g. Brooklyn, NY"
              value={form.loc1} onChange={(e) => setForm({ ...form, loc1: e.target.value })}/>
            {!secondLocOpen ? (
              <button type="button" className="loc-add" onClick={() => setSecondLocOpen(true)}>
                <IconPlus size={12} /> Add a second location
              </button>
            ) : (
              <div className="loc-row">
                <input className="sw-input sw-input--field" placeholder="e.g. Miami, FL"
                  value={form.loc2} onChange={(e) => setForm({ ...form, loc2: e.target.value })}/>
                <button type="button" className="loc-remove" onClick={removeSecondLoc} aria-label="Remove second location">
                  <IconX size={14} />
                </button>
              </div>
            )}
            <div className="field__hint loc-help">
              Add a second city if you're not sure where they currently live.
            </div>
          </div>
        </div>

        <div className="field">
          <div className="field__label">Upload a photo of them
            <span className="field__hint"> · Optional</span>
          </div>
          <div className="field__sub">Helps us locate the right profile — a clear face photo works best.</div>
          {!photo ? (
            <div
              className={"dropzone dropzone--compact" + (dragOver ? " is-drag" : "")}
              onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
              onDragLeave={() => setDragOver(false)}
              onDrop={handleDrop}
              onClick={() => photoInputRef.current && photoInputRef.current.click()}
              role="button"
              tabIndex={0}
            >
              <span className="dropzone__icon dropzone__icon--sm">
                <IconImage size={18} />
              </span>
              <div className="dropzone__compact-body">
                <div className="dropzone__title">Click to upload or drag here</div>
                <div className="dropzone__sub">JPG, PNG · Max 10MB</div>
              </div>
              <input ref={photoInputRef} type="file" accept="image/*" hidden
                onChange={(e) => pickPhoto(e.target.files[0])}/>
            </div>
          ) : (
            <div className="photo-pick">
              <div className="photo-pick__thumb">
                {photoUrl
                  ? <img src={photoUrl} alt="" />
                  : <IconImage size={20} />}
              </div>
              <div className="photo-pick__body">
                <div className="photo-pick__name">
                  <IconCheck size={12} /> {photo.name}
                </div>
                <div className="photo-pick__meta">{photo.size} · Ready</div>
              </div>
              <button type="button" className="photo-pick__remove" onClick={clearPhoto} aria-label="Remove photo">
                <IconX size={14} />
              </button>
            </div>
          )}
        </div>

        <div className="field">
          <div className="field__label">
            Gender I'm looking for
            <span className="field__req"> *</span>
          </div>
          <div className="segmented segmented--red">
            <button type="button"
              className={"segmented__opt" + (gender === "woman" ? " is-on" : "")}
              onClick={() => setGender("woman")}>
              Woman
            </button>
            <button type="button"
              className={"segmented__opt" + (gender === "man" ? " is-on" : "")}
              onClick={() => setGender("man")}>
              Man
            </button>
          </div>
        </div>

        <div className="howto-strip" aria-label="How it works">
          <div className="howto-strip__step">
            <span className="howto-strip__ico"><IconRadar size={16} /></span>
            <div className="howto-strip__label">We locate their Tinder profile</div>
          </div>
          <span className="howto-strip__sep" aria-hidden />
          <div className="howto-strip__step">
            <span className="howto-strip__ico"><IconEye size={16} /></span>
            <div className="howto-strip__label">We check if they've seen yours</div>
          </div>
          <span className="howto-strip__sep" aria-hidden />
          <div className="howto-strip__step">
            <span className="howto-strip__ico"><IconCheck size={16} /></span>
            <div className="howto-strip__label">We report what they did next</div>
          </div>
        </div>

        <TinderSonarExamplePreview onOpen={() => setExampleOpen(true)} />

        <CtaBlock
          label={enough
            ? `Run Tinder Sonar — ${formatTokens(scan.cost)} tokens`
            : `Not enough tokens — Top Up`}
          hint="Results delivered within 2–5 minutes. 100% anonymous."
          disabled={!valid}
          onClick={tryRun}
        />
      </form>
      <TinderSonarExampleModal open={exampleOpen} onClose={() => setExampleOpen(false)} />
    </ScanPageShell>
  );
}

// ============================================================
// Shared field component
// ============================================================
function FormField({ label, hint, required, children }) {
  return (
    <label className="field">
      <div className="field__label">
        {label}
        {required && <span className="field__req"> *</span>}
        {hint && !required && <span className="field__hint"> · {hint}</span>}
      </div>
      {children}
    </label>
  );
}

// ============================================================
// Scan loading page (animated progress + rotating status)
// ============================================================
const STATUS_LINES = [
  "Checking dating apps…",
  "Cross-referencing profiles…",
  "Scanning social platforms…",
  "Indexing public records…",
  "Matching photo signals…",
  "Compiling results…"
];
const FACE_STATUS_LINES = [
  "Checking social networks…",
  "Cross-referencing image databases…",
  "Analyzing profile matches…"
];
function ScanLoadingPage({ scan, subject, photoUrl, onComplete, onCancel }) {
  const isFace = scan.id === "face";
  const [progress, setProgress] = useStateI(isFace ? 0 : 2);
  const [statusIdx, setStatusIdx] = useStateI(0);
  const [candidateIdx, setCandidateIdx] = useStateI(0);
  const [faceStatusIdx, setFaceStatusIdx] = useStateI(0);
  const [phase, setPhase] = useStateI(isFace ? "queue" : "scanning");
  const phaseRef = useRefI(phase);
  useEffectI(() => { phaseRef.current = phase; }, [phase]);

  useEffectI(() => {
    // Hold "queue" state briefly for face scans before progress starts climbing
    let queueTimeout;
    if (isFace) {
      queueTimeout = setTimeout(() => setPhase("scanning"), 1300);
    }
    const a = setInterval(() => {
      setProgress(p => {
        if (phaseRef.current === "queue") return 0;
        if (p >= 100) { clearInterval(a); return 100; }
        const delta = p < 70 ? 4 : p < 90 ? 1.6 : 0.6;
        return Math.min(100, p + delta);
      });
    }, 180);
    const b = setInterval(() => setStatusIdx(i => (i + 1) % STATUS_LINES.length), 1200);
    const c = setInterval(() => setCandidateIdx(i => (i + 1) % PROFILE_IMAGES.length), 380);
    const d = setInterval(() => setFaceStatusIdx(i => (i + 1) % FACE_STATUS_LINES.length), 2000);
    return () => {
      clearTimeout(queueTimeout);
      clearInterval(a); clearInterval(b); clearInterval(c); clearInterval(d);
    };
  }, []);

  useEffectI(() => {
    if (progress >= 100) {
      const t = setTimeout(() => onComplete && onComplete(), 600);
      return () => clearTimeout(t);
    }
  }, [progress]);

  const Icon = window[scan.icon] || IconScan;

  // Face-specific loading: dashed scanner card with cycling candidate + status
  if (isFace) {
    const inQueue = phase === "queue";
    return (
      <div className="loading face-loading" data-screen-label={"04 Scanning — " + scan.name}>
        <div className="face-scanner">
          <h2 className="face-scanner__title">
            {inQueue
              ? "Waiting in queue. 1st place"
              : <>Scanning faces... <span className="face-scanner__pct">{Math.round(progress)}%</span></>
            }
          </h2>

          <div className="face-scanner__compare">
            <div className="face-scanner__slot">
              {photoUrl ? (
                <img src={photoUrl} alt="Your photo" />
              ) : (
                <div className="face-scanner__placeholder"><IconImage size={32} /></div>
              )}
              <span className="face-scanner__corner face-scanner__corner--tl" />
              <span className="face-scanner__corner face-scanner__corner--tr" />
              <span className="face-scanner__corner face-scanner__corner--bl" />
              <span className="face-scanner__corner face-scanner__corner--br" />
              <span className="face-scanner__tag">Your photo</span>
            </div>

            <div className={"face-scanner__slot face-scanner__slot--candidate" + (inQueue ? " is-queue" : "")}>
              {inQueue ? (
                <div className="face-scanner__spinner" aria-hidden>
                  <svg viewBox="0 0 50 50" width="48" height="48">
                    <circle cx="25" cy="25" r="20" fill="none" stroke="rgba(37,99,235,0.18)" strokeWidth="4" />
                    <circle cx="25" cy="25" r="20" fill="none" stroke="#2563EB" strokeWidth="4"
                      strokeLinecap="round" strokeDasharray="40 80"
                      transform="rotate(-90 25 25)">
                      <animateTransform attributeName="transform" type="rotate"
                        from="-90 25 25" to="270 25 25" dur="0.9s" repeatCount="indefinite" />
                    </circle>
                  </svg>
                </div>
              ) : (
                <img key={candidateIdx} src={PROFILE_IMAGES[candidateIdx]} alt="" />
              )}
              {!inQueue && <span className="face-scanner__scan-line" aria-hidden />}
              {!inQueue && <span className="face-scanner__tint" aria-hidden />}
              <span className="face-scanner__corner face-scanner__corner--tl" />
              <span className="face-scanner__corner face-scanner__corner--tr" />
              <span className="face-scanner__corner face-scanner__corner--bl" />
              <span className="face-scanner__corner face-scanner__corner--br" />
              <span className="face-scanner__tag">{inQueue ? "Queued" : "Candidate"}</span>
            </div>
          </div>

          <div className="face-scanner__bar" role="progressbar"
               aria-valuenow={Math.round(progress)} aria-valuemin="0" aria-valuemax="100">
            <div className="face-scanner__fill" style={{ width: progress + "%" }} />
          </div>
        </div>

        <div className="face-scanner__foot">
          <div className="face-scanner__foot-title">Searching across 200+ platforms and databases</div>
          <div className="face-scanner__statuses" aria-live="polite">
            {FACE_STATUS_LINES.map((s, i) => (
              <span key={i} className={"face-scanner__statusline" + (i === faceStatusIdx ? " is-active" : "")}>{s}</span>
            ))}
          </div>
          <button className="sw-link loading__cancel" onClick={onCancel}>Cancel scan</button>
        </div>
      </div>
    );
  }

  return (
    <div className="loading" data-screen-label={"04 Scanning — " + scan.name}>
      <div className="sw-card loading__card">
        <div className="loading__icon" style={{ ['--icon-tint']: scan.color }}>
          <span className="loading__pulse" />
          <Icon size={28} />
        </div>
        <h2 className="loading__title">Scanning 200+ platforms…</h2>
        <p className="loading__sub">{scan.name} for <strong>{subject || "your subject"}</strong></p>

        <div className="loading__bar" role="progressbar" aria-valuenow={Math.round(progress)} aria-valuemin="0" aria-valuemax="100">
          <div className="loading__fill" style={{ width: progress + "%" }} />
        </div>
        <div className="loading__pct">{Math.round(progress)}%</div>

        <div className="loading__status">
          {STATUS_LINES.map((s, i) => (
            <span key={i} className={"loading__statusline" + (i === statusIdx ? " is-active" : "")}>{s}</span>
          ))}
        </div>

        <div className="loading__steps">
          {["Lookup", "Cross-reference", "Compile"].map((s, i) => {
            const reached = progress > (i + 1) * 25;
            return (
              <div key={s} className={"loading__step" + (reached ? " is-done" : "")}>
                <span className="loading__stepdot">{reached ? <IconCheck size={11} /> : i + 1}</span>
                {s}
              </div>
            );
          })}
        </div>

        <button className="sw-link loading__cancel" onClick={onCancel}>Cancel scan</button>
      </div>
    </div>
  );
}

Object.assign(window, {
  DatingAppScanInput, FaceScanInput, NewPersonCheckInput, RelationshipStatusInput,
  TinderSonarInput,
  ScanLoadingPage, FormField
});
