import { useEffect, useRef, useState } from "react";
import { api } from "./api/client";
import "./OnboardingWizard.css";
import type { AuthResponse } from "./types/api";

type Step = "name" | "garmin";

// Replaces the old CreateProfile.tsx + ConnectGarmin.tsx: a single wizard,
// since nothing is persisted to the database until Garmin actually
// connects (see
// docs/superpowers/specs/2026-07-26-onboarding-wizard-deferred-commit-design.md).
// Quitting partway through (closing the tab) leaves no trace in the
// database -- there's no half-created account to clean up or re-prompt
// for later, so there's deliberately no "Log out" escape hatch anywhere in
// this flow: closing the tab *is* the escape hatch.
export function OnboardingWizard({ onCreated }: { onCreated: (displayName: string) => void }) {
  const [step, setStep] = useState<Step>("name");
  const [displayName, setDisplayName] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [code, setCode] = useState("");
  const [auth, setAuth] = useState<AuthResponse | null>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const completeTriggered = useRef(false);

  function submitName(e: React.FormEvent) {
    e.preventDefault();
    if (!displayName.trim()) {
      setError("Please enter a display name.");
      return;
    }
    setError(null);
    setStep("garmin");
  }

  async function submitGarmin(e: React.FormEvent) {
    e.preventDefault();
    if (!email.trim() || !password) {
      setError("Please enter your Garmin email and password.");
      return;
    }
    setBusy(true);
    setError(null);
    try {
      setAuth(await api.setupGarminLogin(email.trim(), password));
    } catch (err) {
      setError(err instanceof Error ? err.message : "Something went wrong, please try again.");
    } finally {
      setBusy(false);
    }
  }

  async function submitMFA() {
    if (!code.trim()) return;
    setBusy(true);
    setError(null);
    try {
      setAuth(await api.setupGarminMFA(code.trim()));
      setCode("");
    } catch (err) {
      setError(err instanceof Error ? err.message : "Something went wrong, please try again.");
    } finally {
      setBusy(false);
    }
  }

  async function complete() {
    setBusy(true);
    setError(null);
    try {
      const result = await api.setupComplete(displayName.trim());
      onCreated(result.display_name);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Something went wrong, please try again.");
      setBusy(false);
    }
  }

  // Once Garmin reports success (whether MFA was needed or not), finish
  // setup immediately -- no "Continue to geniusrun" click required. Guarded
  // by a ref (not just the effect's dependency array) so this can never
  // fire twice, e.g. under React StrictMode's double-invoked effects in
  // development.
  useEffect(() => {
    if (auth?.status === "authenticated" && !completeTriggered.current) {
      completeTriggered.current = true;
      complete();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [auth?.status]);

  if (step === "name") {
    return (
      <div className="onboarding-wizard">
        <h1>🧞‍♀️ Welcome to geniusrun</h1>
        <p>Let's set up your profile. You'll connect your Garmin account next.</p>
        <form onSubmit={submitName}>
          <div className="onboarding-wizard-name-row">
            <input
              type="text"
              placeholder="Display name"
              value={displayName}
              onChange={(e) => setDisplayName(e.target.value)}
              autoFocus
            />
            <button type="submit" className="onboarding-wizard-icon-button" title="Continue" aria-label="Continue">
              ✓
            </button>
          </div>
          {error && <p className="onboarding-wizard-error">{error}</p>}
        </form>
      </div>
    );
  }

  return (
    <div className="onboarding-wizard">
      <h1>🧞‍♀️ Connect your Garmin account</h1>
      <p>geniusrun needs your Garmin credentials to sync your activities.</p>

      {auth?.status === "authenticated" ? (
        <>
          <p className="onboarding-wizard-message">Connected to Garmin — finishing setup…</p>
          {error && (
            <>
              <p className="onboarding-wizard-error">{error}</p>
              <button type="button" disabled={busy} onClick={complete}>
                {busy ? "Finishing…" : "Retry"}
              </button>
            </>
          )}
        </>
      ) : auth?.status === "mfa_required" ? (
        <div className="onboarding-wizard-mfa">
          <input
            placeholder="MFA code"
            value={code}
            onChange={(e) => setCode(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && submitMFA()}
            disabled={busy}
            autoFocus
          />
          {auth.message && <p className="onboarding-wizard-message">{auth.message}</p>}
          {error && <p className="onboarding-wizard-error">{error}</p>}
          <button type="button" disabled={busy} onClick={submitMFA}>
            Submit code
          </button>
        </div>
      ) : (
        <form onSubmit={submitGarmin}>
          <input
            type="text"
            placeholder="Garmin email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            disabled={busy}
            autoFocus
          />
          <input
            type="password"
            placeholder="Garmin password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            disabled={busy}
          />
          {auth?.message && <p className="onboarding-wizard-message">{auth.message}</p>}
          {error && <p className="onboarding-wizard-error">{error}</p>}
          <button type="submit" disabled={busy}>
            {busy ? "Connecting…" : "Login"}
          </button>
        </form>
      )}
    </div>
  );
}
