import { type ComponentProps, useEffect, useRef, useState } from "react";

const PULSE_SCRIPT_URL =
  "https://kenshiki-pulse-worker-production.pulsekenshikilabscom.workers.dev/v1/pulse.js";
const PULSE_SESSION_ENDPOINT =
  "https://kenshiki-pulse-worker-production.pulsekenshikilabscom.workers.dev/api/v1/sessions";
const EXPECTED_WORKFLOW = "credit_application";
const EXPECTED_ACTION = "submit_application";

type PublicPulseSession = {
  id: string;
  nonce: string;
  qr_svg_url: string;
  universal_link: string;
  qr_payload?: string;
  websocket_url?: string;
  api_base_url?: string;
  expires_at?: string;
};

type PulseBondResult = {
  state: "bonded" | "killed" | "expired" | "step_up_required";
  sessionId?: string;
  session?: unknown;
};

type PulseClient = {
  requireBond(options: {
    session: PublicPulseSession;
    action: string;
    context?: Record<string, string | number | boolean>;
  }): Promise<PulseBondResult>;
};

function hasBondedSession(bond: PulseBondResult): bond is PulseBondResult & { sessionId: string } {
  return bond.state === "bonded" && typeof bond.sessionId === "string" && bond.sessionId.length > 0;
}

declare global {
  interface Window {
    KenshikiPulse?: {
      init(config: {
        publishableKey: string;
        workflow: string;
        containerId: string;
        sessionEndpoint: string;
      }): PulseClient;
    };
  }
}

async function createPulseSession(): Promise<{ session: PublicPulseSession }> {
  const response = await fetch("/api/pulse/sessions", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "same-origin",
    body: JSON.stringify({ workflow: EXPECTED_WORKFLOW, action: EXPECTED_ACTION }),
  });
  if (!response.ok) throw new Error("pulse_session_create_failed");
  return response.json();
}

export function PulseProtectedSubmit() {
  const pulseRef = useRef<PulseClient | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [status, setStatus] = useState("Scan Pulse before submitting.");

  useEffect(() => {
    function initializePulse() {
      pulseRef.current =
        window.KenshikiPulse?.init({
          publishableKey: "pk_beta_issued_by_kenshiki",
          workflow: EXPECTED_WORKFLOW,
          containerId: "pulse-trust-gate",
          sessionEndpoint: PULSE_SESSION_ENDPOINT,
        }) ?? null;
      if (pulseRef.current) setStatus("Pulse is ready.");
    }

    const existing = document.querySelector<HTMLScriptElement>(`script[src="${PULSE_SCRIPT_URL}"]`);
    if (existing) {
      initializePulse();
      existing.addEventListener("load", initializePulse, { once: true });
      return () => existing.removeEventListener("load", initializePulse);
    }

    const script = document.createElement("script");
    script.src = PULSE_SCRIPT_URL;
    script.async = true;
    script.addEventListener("load", initializePulse, { once: true });
    document.head.append(script);

    return () => script.remove();
  }, []);

  const onSubmit: NonNullable<ComponentProps<"form">["onSubmit"]> = async (event) => {
    event.preventDefault();

    const form = event.currentTarget;
    if (!form.reportValidity()) return;
    const pulse = pulseRef.current;
    if (!pulse) {
      setStatus("Pulse did not load. Please retry or route to manual review.");
      return;
    }

    setSubmitting(true);
    setStatus("Waiting for phone proof.");

    try {
      const created = await createPulseSession();
      const bond = await pulse.requireBond({
        session: created.session,
        action: EXPECTED_ACTION,
        context: { form_id: form.id || "application-form" },
      });

      if (!hasBondedSession(bond)) {
        setStatus("Pulse did not verify this action. Please retry or use manual review.");
        return;
      }

      const body = new FormData(form);
      body.set("bonded_session_id", bond.sessionId);
      setStatus("Phone verified. Submitting to your server.");

      // Your backend must verify bonded_session_id and complete the bond server-side after commit.
      const response = await fetch("/applications", { method: "POST", body });
      if (!response.ok) throw new Error("application_submit_failed");

      setStatus("Submitted.");
    } catch {
      setStatus("Submit did not complete. Please retry or use manual review.");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <form id="application-form" onSubmit={onSubmit}>
      {/* Keep existing customer fields here. */}
      <input name="bonded_session_id" type="hidden" />
      <p>
        Pulse manages the QR, phone handoff, help link, reassurance copy, fail-closed state, and trust status
        below. Keep the gate visible until submit completes.
      </p>
      <div className="pulse-trust-gate" id="pulse-trust-gate" />
      <p aria-live="polite">{status}</p>
      <button type="submit" disabled={submitting}>
        Submit application
      </button>
    </form>
  );
}
