// DemoRequestForm.jsx
//
// The one real lead-capture form every "Request a Demo" CTA on the site
// points to. Posts multipart/form-data to /api/mail-handler.php (PHP +
// PHPMailer over SMTP, delivering into the real Google Workspace mailbox -
// see api/SETUP.md), not JSON to a placeholder endpoint - that's now a
// real, working backend, not forward-wired. FormData (not JSON) so this
// form and CareerApplicationForm.jsx share one submission shape, since the
// career form needs real file upload support and both hit the same
// endpoint.
//
// Because the backend is real now, this form surfaces real errors instead
// of always showing success - the previous "fake success no matter what"
// behavior was specifically because no backend existed yet to fail against
// (see git history / prior session notes); showing a false success on a
// genuine send failure would now be actively misleading.
//
// Spam guards, three layers: a honeypot field (visually hidden, tab-order
// excluded), a time-trap (elapsed ms since mount, re-checked server-side),
// and Cloudflare Turnstile (invisible, deferred to submit time via
// `execution: "execute"` so the token is always fresh, not one grabbed at
// mount and possibly stale by the time a slow filler submits). The
// Turnstile script and widget are managed entirely inside this component
// via a mount effect - no <script> tag needed in any page's HTML shell.
//
// Loaded as a classic (non-module) Babel-transformed script - see
// index.html's header comment. React 19 ships no UMD global, so
// `window.React` here is the bridge index.html's ESM import sets up; hooks
// are called as `React.useState` etc. (fully qualified) for the same
// shared-global-scope reason documented in Navbar.jsx.

const MAIL_ENDPOINT = "/api/mail-handler.php";
const MIN_HUMAN_FILL_TIME_MS = 2500;

// Public by design - a Turnstile site key is meant to be embedded in
// frontend code (the matching secret key, which actually matters for
// security, lives server-side only in api/.env, never here). Real site
// key, registered at https://dash.cloudflare.com/ -> Turnstile.
const TURNSTILE_SITE_KEY = "0x4AAAAAAD5vrHbmSavpdi46";

function loadTurnstileScript() {
  if (window.turnstile) return Promise.resolve();
  if (window.__turnstileLoading) return window.__turnstileLoading;
  window.__turnstileLoading = new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js";
    script.async = true;
    script.defer = true;
    script.onload = () => resolve();
    script.onerror = () => reject(new Error("Could not load verification script."));
    document.head.appendChild(script);
  });
  return window.__turnstileLoading;
}

// Shared by DemoRequestForm and CareerApplicationForm - each owns its own
// widget instance (own container ref), but the loader script is a single
// document-wide resource, deduped via window.__turnstileLoading above.
function useTurnstile() {
  const containerRef = React.useRef(null);
  const widgetIdRef = React.useRef(null);
  const resolverRef = React.useRef(null);

  React.useEffect(() => {
    let cancelled = false;
    loadTurnstileScript()
      .then(() => {
        if (cancelled || !containerRef.current || widgetIdRef.current !== null) return;
        widgetIdRef.current = window.turnstile.render(containerRef.current, {
          sitekey: TURNSTILE_SITE_KEY,
          // Turnstile has no true "invisible" size (only compact/flexible/
          // normal) - this is its real equivalent: the widget occupies no
          // visible space and never shows unless Cloudflare's risk engine
          // decides an actual interactive challenge is needed, which is
          // rare for genuine visitors.
          appearance: "interaction-only",
          execution: "execute",
          // A submit already gets a fresh token via .execute() on retry, so
          // Turnstile's own built-in retry-on-error is redundant here - left
          // on, it silently re-attempts every ~10s in the background even
          // after the form has already shown the user an error and moved on
          // (confirmed while testing: a bad sitekey looped indefinitely).
          retry: "never",
          callback: (token) => resolverRef.current?.resolve(token),
          "error-callback": () => resolverRef.current?.reject(new Error("Verification failed - please try again.")),
          "timeout-callback": () => resolverRef.current?.reject(new Error("Verification timed out - please try again.")),
        });
      })
      .catch((err) => {
        if (!cancelled) resolverRef.current?.reject(err);
      });
    return () => {
      cancelled = true;
      if (widgetIdRef.current !== null && window.turnstile) {
        window.turnstile.remove(widgetIdRef.current);
      }
    };
  }, []);

  const getToken = () =>
    new Promise((resolve, reject) => {
      if (widgetIdRef.current === null || !window.turnstile) {
        reject(new Error("Verification isn't ready yet - please try again in a moment."));
        return;
      }

      // A fundamentally broken sitekey fails at render time with just a
      // console warning - Turnstile's own error-callback never fires, so
      // without this the submit button would hang on "Submitting…"
      // forever (confirmed while testing against an invalid key). This
      // guarantees getToken() always eventually settles either way.
      const timeoutId = setTimeout(() => {
        resolverRef.current = null;
        reject(new Error("Verification is taking too long - please try again."));
      }, 15000);

      resolverRef.current = {
        resolve: (token) => {
          clearTimeout(timeoutId);
          resolve(token);
        },
        reject: (err) => {
          clearTimeout(timeoutId);
          reject(err);
        },
      };
      window.turnstile.execute(widgetIdRef.current);
    });

  return { containerRef, getToken };
}

function DemoRequestForm({ sourcePage, interestType = "demo_request", submitLabel = "Request a Demo" }) {
  const [form, setForm] = React.useState({ name: "", email: "", phone: "", companyName: "", message: "" });
  const [honeypot, setHoneypot] = React.useState("");
  const [errors, setErrors] = React.useState({});
  const [status, setStatus] = React.useState("idle"); // idle | submitting | done | error
  const [serverMessage, setServerMessage] = React.useState("");
  const mountedAt = React.useRef(Date.now());
  const { containerRef, getToken } = useTurnstile();

  const update = (field) => (e) => setForm((f) => ({ ...f, [field]: e.target.value }));

  const validate = () => {
    const next = {};
    if (!form.name.trim()) next.name = "Name is required.";
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) next.email = "Enter a valid email.";
    if (!form.companyName.trim()) next.companyName = "Company name is required.";
    setErrors(next);
    return Object.keys(next).length === 0;
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!validate()) return;

    setStatus("submitting");
    setServerMessage("");

    try {
      const token = await getToken();

      const body = new FormData();
      body.append("formType", "demo");
      body.append("name", form.name);
      body.append("email", form.email);
      body.append("phone", form.phone);
      body.append("companyName", form.companyName);
      body.append("message", form.message);
      body.append("interestType", interestType);
      body.append("sourcePage", sourcePage || "");
      body.append("company_website", honeypot);
      body.append("form_elapsed_ms", String(Date.now() - mountedAt.current));
      body.append("cf-turnstile-response", token);

      const res = await fetch(MAIL_ENDPOINT, { method: "POST", body });
      const data = await res.json();

      if (data.success) {
        setServerMessage(data.message || "");
        setStatus("done");
      } else {
        setServerMessage(data.message || "Something went wrong - please try again.");
        setStatus("error");
      }
    } catch (err) {
      setServerMessage("We couldn't reach the server - check your connection and try again.");
      setStatus("error");
    }
  };

  if (status === "done") {
    return (
      <div className="rounded-card border border-emerald-200 bg-emerald-50 p-8 text-center">
        <svg className="mx-auto h-10 w-10 text-emerald-600" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
          <circle cx="12" cy="12" r="9" />
          <path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4" />
        </svg>
        <h3 className="mt-4 text-lg font-bold text-brand-navy">Thanks, {form.name.split(" ")[0]}.</h3>
        <p className="mt-2 text-sm text-slate-600">
          {serverMessage ||
            (interestType === "demo_request"
              ? `We've got your details for ${form.companyName}. Our team will reach out to schedule your walkthrough.`
              : `We've got your message. Our team will get back to you directly.`)}
        </p>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} noValidate className="space-y-4 rounded-card border border-slate-200 bg-surface-card p-8 shadow-card">
      {/* Honeypot: real form fields never use this name/positioning combo, but
          it reads as a normal optional field to a bot filling every input it
          finds. Hidden from sighted users and screen readers, and excluded
          from tab order, so no real visitor can trip it. */}
      <div className="sr-only" aria-hidden="true">
        <label htmlFor="company_website">Company Website</label>
        <input
          id="company_website"
          type="text"
          name="company_website"
          tabIndex={-1}
          autoComplete="off"
          value={honeypot}
          onChange={(e) => setHoneypot(e.target.value)}
        />
      </div>

      {/* Turnstile renders nothing visible in invisible mode - this div is
          just the mount point the widget attaches to. */}
      <div ref={containerRef} />

      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <div>
          <label className="text-sm font-semibold text-brand-navy">Full name *</label>
          <input
            type="text"
            value={form.name}
            onChange={update("name")}
            className="mt-1.5 w-full rounded-lg border border-slate-200 px-3.5 py-2.5 text-sm text-ink focus:border-brand-navy/40 focus:outline-none focus:ring-2 focus:ring-emerald-500/20"
            placeholder="Jane Patel"
          />
          {errors.name && <p className="mt-1 text-xs text-red-600">{errors.name}</p>}
        </div>
        <div>
          <label className="text-sm font-semibold text-brand-navy">Work email *</label>
          <input
            type="email"
            value={form.email}
            onChange={update("email")}
            className="mt-1.5 w-full rounded-lg border border-slate-200 px-3.5 py-2.5 text-sm text-ink focus:border-brand-navy/40 focus:outline-none focus:ring-2 focus:ring-emerald-500/20"
            placeholder="jane@yourcompany.com"
          />
          {errors.email && <p className="mt-1 text-xs text-red-600">{errors.email}</p>}
        </div>
      </div>

      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <div>
          <label className="text-sm font-semibold text-brand-navy">Company name *</label>
          <input
            type="text"
            value={form.companyName}
            onChange={update("companyName")}
            className="mt-1.5 w-full rounded-lg border border-slate-200 px-3.5 py-2.5 text-sm text-ink focus:border-brand-navy/40 focus:outline-none focus:ring-2 focus:ring-emerald-500/20"
            placeholder="Your company"
          />
          {errors.companyName && <p className="mt-1 text-xs text-red-600">{errors.companyName}</p>}
        </div>
        <div>
          <label className="text-sm font-semibold text-brand-navy">Phone (optional)</label>
          <input
            type="tel"
            value={form.phone}
            onChange={update("phone")}
            className="mt-1.5 w-full rounded-lg border border-slate-200 px-3.5 py-2.5 text-sm text-ink focus:border-brand-navy/40 focus:outline-none focus:ring-2 focus:ring-emerald-500/20"
            placeholder="+91 98765 43210"
          />
        </div>
      </div>

      <div>
        <label className="text-sm font-semibold text-brand-navy">What are you hoping to automate? (optional)</label>
        <textarea
          value={form.message}
          onChange={update("message")}
          rows={3}
          className="mt-1.5 w-full rounded-lg border border-slate-200 px-3.5 py-2.5 text-sm text-ink focus:border-brand-navy/40 focus:outline-none focus:ring-2 focus:ring-emerald-500/20"
          placeholder="E.g. multi-warehouse inventory, Tally sync, production tracking…"
        />
      </div>

      {status === "error" && (
        <p className="rounded-lg border border-red-200 bg-red-50 px-3.5 py-2.5 text-sm text-red-700">{serverMessage}</p>
      )}

      <button
        type="submit"
        disabled={status === "submitting"}
        className="w-full rounded-card bg-emerald-600 px-6 py-3.5 text-sm font-semibold text-white shadow-card transition hover:bg-emerald-700 disabled:opacity-60"
      >
        {status === "submitting" ? "Sending…" : submitLabel}
      </button>
    </form>
  );
}
