/* crear.jsx — Hovex Express lead form (#crear).

   Short 4-field entry to the funnel: business name, rubro (free text + datalist),
   WhatsApp, and an optional Instagram/website link. Reuses the exact anti-abuse
   stack as getstarted.jsx (honeypot, time-trap, hCaptcha, cooldown) and the same
   validators from lib.jsx.

   On success: fires Meta Lead (pixel + CAPI, deduped by event_id), creates the
   intake on the VPS API (persists { state, token } to localStorage via HovexAPI),
   then navigates to the chat (#intake). */

const CREAR_SITEKEY = (window.AF_ENV && window.AF_ENV.HCAPTCHA_SITE_KEY) || "";
const CREAR_COOLDOWN_KEY = "af-crear-cooldown";
const CREAR_COOLDOWN_MS = 30000;

/* El servidor rechaza formDurationMs < 2 s (bot) o > 1 h (rancio) — ver
   MIN_FILL_MS/MAX_FILL_MS en hovex-express-api/src/routes/intake.create.ts. Una
   pestaña abierta una hora NO es un bot: sin este tope el envío moría con el
   error genérico y ningún reintento lo curaba, porque el reloj arranca al montar
   y solo se reiniciaba recargando. Acotamos por arriba; por debajo pasa el valor
   real, así el trap de los 2 s sigue intacto. */
const CREAR_MAX_REPORTED_FILL_MS = 30 * 60000; // 30 min — dentro del rango

/* Códigos que el backend puede devolver en `error`. Lista blanca: el código
   viaja del servidor a la pantalla, y así nunca se refleja en el DOM una cadena
   arbitraria llegada por la red. */
const CREAR_KNOWN_ERROR_CODES = [
  "captcha_failed", "timing", "rate_limited", "missing_fields",
  "bad_response", "internal_error", "not_found", "bad_token",
];

/* Traduce el fallo de createIntake a algo accionable. Antes todos los casos
   —`timing`, `rate_limited`, un 500, o que la petición ni saliera— caían en la
   misma frase genérica: el usuario no sabía si reintentar, recargar o esperar. */
function crearErrorMessage(err, lang) {
  const es = lang !== "en";
  const m = (esTxt, enTxt) => (es ? esTxt : enTxt);
  const code = err && err.code;

  switch (code) {
    case "captcha_failed":
      return m("El captcha no se pudo verificar. Intenta de nuevo.", "Captcha couldn't be verified. Try again.");
    case "timing":
      return m(
        "El formulario lleva demasiado tiempo abierto. Recarga la página e intenta de nuevo.",
        "This form has been open too long. Refresh the page and try again."
      );
    case "rate_limited":
      return m(
        "Demasiados intentos. Espera un minuto e intenta de nuevo.",
        "Too many attempts. Wait a minute and try again."
      );
    case "missing_fields":
      return m("Completa el nombre del negocio y el rubro.", "Fill in the business name and industry.");
    case "bad_response":
      /* El servidor aceptó pero no creó nada: el honeypot venía relleno. */
      return m(
        "Algo en el formulario no cuadra. Recarga la página e intenta de nuevo.",
        "Something in the form looks off. Refresh the page and try again."
      );
    case undefined:
      /* Ni código ni respuesta: la petición no llegó a completarse. */
      return m(
        "No pudimos conectar con el servidor. Revisa tu conexión e intenta de nuevo.",
        "We couldn't reach the server. Check your connection and try again."
      );
  }

  const shown = CREAR_KNOWN_ERROR_CODES.indexOf(code) !== -1 ? " (" + code + ")" : "";
  return m(
    "No pudimos iniciar tu proyecto. Intenta de nuevo en un momento." + shown,
    "We couldn't start your project. Please try again in a moment." + shown
  );
}

function CrearPage({ navigate }) {
  const { t, lang } = useT();
  const c = t.crear;
  const [data, setData] = useState({
    businessName: "",
    industryInput: "",
    whatsapp: "",
    instagramOrLink: "",
    company_url: "", // honeypot — must stay empty
  });
  const mountedAt = useRef(Date.now());
  const captcha = useHCaptcha(CREAR_SITEKEY);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");

  const trimmed = {
    businessName: cleanText(data.businessName, 80),
    industryInput: cleanText(data.industryInput, 80),
    whatsapp: cleanText(data.whatsapp, 24),
    instagramOrLink: cleanText(data.instagramOrLink, 200),
  };

  const errMsg = (es, en) => (lang === "es" ? es : en);

  const validate = () => {
    if (!trimmed.businessName || !trimmed.industryInput) {
      return errMsg("Completa el nombre del negocio y el rubro.", "Fill in the business name and industry.");
    }
    if (!trimmed.whatsapp || trimmed.whatsapp.replace(/[^0-9]/g, "").length < 7) {
      return errMsg("Ingresa un WhatsApp válido.", "Enter a valid WhatsApp number.");
    }
    // Optional link: if it looks like a URL, require https; plain @handles are fine.
    if (trimmed.instagramOrLink && /^https?:/i.test(trimmed.instagramOrLink) &&
        !validHttpsUrl(trimmed.instagramOrLink, { maxLen: 200 })) {
      return errMsg("El enlace debe empezar con https://", "The link must start with https://");
    }
    return "";
  };

  const valid = !validate();

  const submit = async (e) => {
    e.preventDefault();
    const v = validate();
    if (v) { setError(v); return; }

    if (!checkCooldown(CREAR_COOLDOWN_KEY, CREAR_COOLDOWN_MS)) {
      setError(errMsg("Espera un momento antes de intentar de nuevo.", "Please wait a moment before trying again."));
      return;
    }

    // On localhost, submit hCaptcha's official TEST token (the backend verifies
    // it against the test secret) so local dev doesn't depend on the widget.
    const captchaToken = (window.AF_ENV && window.AF_ENV.HOVEX_LOCAL_DEV)
      ? "10000000-aaaa-bbbb-cccc-000000000001"
      : captcha.getToken();
    if (!captchaToken) {
      setError(errMsg("Completa el captcha primero.", "Please complete the captcha first."));
      return;
    }

    setSubmitting(true);
    setError("");
    try {
      const utm = readUtm();
      const result = await window.HovexAPI.createIntake({
        businessName: trimmed.businessName,
        industryInput: trimmed.industryInput,
        whatsapp: trimmed.whatsapp,
        instagramOrLink: trimmed.instagramOrLink,
        locale: lang === "en" ? "en" : "es",
        landingVertical: (utm && utm.campaign) || "",
        utm,
        company_url: data.company_url,
        formDurationMs: Math.min(Date.now() - mountedAt.current, CREAR_MAX_REPORTED_FILL_MS),
        hCaptchaToken: captchaToken,
      });
      if (!result || !result.ok || !result.state) {
        /* 200 sin state = el honeypot venía relleno y el servidor ignoró el
           envío en silencio. Lo marcamos con código para no confundirlo con una
           caída de red, que también llega al catch sin código. */
        const bad = new Error("bad_response");
        bad.code = "bad_response";
        throw bad;
      }

      markCooldown(CREAR_COOLDOWN_KEY);

      // Conversion: Meta Lead (pixel + CAPI, deduped by event_id inside afTrack).
      if (window.afTrack) window.afTrack.lead(
        { form: "hovex-express", industry: trimmed.industryInput },
        {} // no verified PII at this step; WhatsApp isn't email/phone-hashable here
      );

      navigate("intake");
    } catch (err) {
      captcha.reset();
      setError(crearErrorMessage(err, lang));
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <section className="getstarted-section">
      <div className="shell getstarted-shell">
        <div className="getstarted-grid">
          <div className="getstarted-left">
            <Reveal>
              <div className="eyebrow">{c.eyebrow}</div>
            </Reveal>
            <h1 className="gs-title">
              <Words text={c.h1a} delay={100} />
              <em><Words text={c.h1b} delay={350} /></em>
            </h1>
            <Reveal delay={300}>
              <p className="gs-sub">{c.sub}</p>
            </Reveal>
            <Reveal delay={400}>
              <div className="gs-trust">
                {c.bullets.map((b, i) => (
                  <div className="gs-trust-row" key={i}>
                    <span className="dot moss" />
                    <span className="mono">{b}</span>
                  </div>
                ))}
              </div>
            </Reveal>
          </div>

          <Reveal delay={120}>
            <form className="gs-form" onSubmit={submit} noValidate>
              {/* Honeypot */}
              <div className="hp-field" aria-hidden="true">
                {/* Honeypot. Ni el name ni el label pueden decir «company»:
                    Chrome mapea ese token a su autocompletado `organization` y
                    rellenaba este campo al autocompletar el resto, con lo que el
                    servidor descartaba el lead en silencio. El nombre de cable
                    sigue siendo company_url (el payload se arma desde el estado). */}
                <label htmlFor="crear_ref_note">Reference</label>
                <input
                  type="text" id="crear_ref_note" name="hx_ref_note"
                  tabIndex={-1} autoComplete="off"
                  data-1p-ignore data-lpignore="true" data-form-type="other"
                  value={data.company_url}
                  onChange={e => setData({ ...data, company_url: e.target.value })}
                />
              </div>

              <div className="field">
                <label>{c.f.business}</label>
                <input type="text" required maxLength={80} autoComplete="organization"
                  value={data.businessName}
                  onChange={e => setData({ ...data, businessName: e.target.value })} />
              </div>

              <div className="field">
                <label>{c.f.industry}</label>
                <input type="text" required maxLength={80} list="crear-rubros"
                  autoComplete="off" placeholder={c.f.industryPh}
                  value={data.industryInput}
                  onChange={e => setData({ ...data, industryInput: e.target.value })} />
                <datalist id="crear-rubros">
                  {c.rubros.map(r => <option key={r} value={r} />)}
                </datalist>
              </div>

              <div className="field">
                <label>{c.f.whatsapp}</label>
                <input type="tel" required maxLength={24} autoComplete="tel" inputMode="tel"
                  placeholder="+1 555 000 0000"
                  value={data.whatsapp}
                  onChange={e => setData({ ...data, whatsapp: e.target.value })} />
              </div>

              <div className="field">
                <label>{c.f.link} <span className="muted">{c.f.linkOpt}</span></label>
                <input type="text" maxLength={200} autoComplete="off"
                  placeholder="@tunegocio / https://"
                  value={data.instagramOrLink}
                  onChange={e => setData({ ...data, instagramOrLink: e.target.value })} />
              </div>

              <div className="field field-captcha">
                <div ref={captcha.ref} className="h-captcha" />
              </div>
              {error && <div className="form-error mono" role="alert">{error}</div>}
              <button type="submit" className="btn btn-block btn-lg" disabled={!valid || submitting}>
                {submitting ? c.f.submitting : c.f.submit} <ArrowIcon />
              </button>
            </form>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

// Read UTM params from the current URL (best-effort, for ad attribution).
function readUtm() {
  try {
    const p = new URLSearchParams(window.location.search);
    const utm = {
      source: p.get("utm_source") || undefined,
      medium: p.get("utm_medium") || undefined,
      campaign: p.get("utm_campaign") || undefined,
      content: p.get("utm_content") || undefined,
    };
    return (utm.source || utm.medium || utm.campaign || utm.content) ? utm : undefined;
  } catch (_e) { return undefined; }
}

Object.assign(window, { CrearPage });
