"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/context/AuthContext";

export default function OnboardingPage() {
  const router = useRouter();
  const { user, loading, token, logout, refreshMeAndSession } = useAuth();

  // Step: 1=password, 2=username, 3=optional display name
  const [step, setStep] = useState<1 | 2 | 3>(1);

  // Password
  const [pw1, setPw1] = useState("");
  const [pw2, setPw2] = useState("");
  const [pwSaving, setPwSaving] = useState(false);
  const [pwMsg, setPwMsg] = useState<string | null>(null);

  // Username
  const [username, setUsername] = useState("");
  const [checking, setChecking] = useState(false);
  const [available, setAvailable] = useState<boolean | null>(null);
  const [userMsg, setUserMsg] = useState<string | null>(null);
  const [savingUsername, setSavingUsername] = useState(false);

  // Display name (optional)
  const [displayName, setDisplayName] = useState("");
  const [savingName, setSavingName] = useState(false);
  const [nameMsg, setNameMsg] = useState<string | null>(null);

  const hasUsername = useMemo(() => {
    const current = String((user as any)?.username ?? "").trim();
    return current.length > 0;
  }, [user]);

  const hasPassword = useMemo(() => {
    return !!(user as any)?.passwordSetAt;
  }, [user]);

  const pwMismatch = pw1.length > 0 && pw2.length > 0 && pw1 !== pw2;
  const pwTooShort = pw1.length > 0 && pw1.length < 8;
  const canSavePassword = !pwSaving && pw1.length >= 8 && pw1 === pw2;

  // Hydrate local inputs when user becomes available
  useEffect(() => {
    if (!user) return;
    setUsername(String((user as any)?.username ?? ""));
    setDisplayName(String(user.displayName ?? ""));
  }, [user]);

  // Route guards + step sync (NO redirects during render)
  useEffect(() => {
    if (loading) return;
    if (!user) return;

    // If complete, bounce them out
    if (hasUsername && hasPassword) {
      router.replace("/builder");
      return;
    }

    // Choose the right step based on what's missing
    if (!hasPassword) setStep(1);
    else if (!hasUsername) setStep(2);
    else setStep(3);
  }, [loading, user, hasUsername, hasPassword, router]);

  if (loading) return <div className="text-sm opacity-70">Loading…</div>;
  if (!user) return <div className="text-sm opacity-70">Not logged in.</div>;

  async function savePassword() {
    setPwMsg(null);

    if (pw1.length < 8) return setPwMsg("Password must be at least 8 characters.");
    if (pw1 !== pw2) return setPwMsg("Passwords don’t match.");

    setPwSaving(true);
    try {
      const res = await fetch(`/api/users/me/password`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ password: pw1 }),
      });

      if (!res.ok) {
        throw new Error((await res.text().catch(() => "")) || "Failed to set password");
      }

      await refreshMeAndSession();

      setPwMsg("Password saved ✅");
      setPw1("");
      setPw2("");
      // step will auto-sync via useEffect once user updates, but this makes UI feel instant:
      setStep(2);
    } catch (e: any) {
      setPwMsg(e?.message || "Couldn’t set password.");
    } finally {
      setPwSaving(false);
    }
  }

  async function checkUsername() {
    setChecking(true);
    setUserMsg(null);
    setAvailable(null);

    try {
      const u = username.trim().toLowerCase();
      const res = await fetch(
        `/api/users/me/username-available?username=${encodeURIComponent(u)}`,
        {
          headers: { ...(token ? { Authorization: `Bearer ${token}` } : {}) },
          cache: "no-store",
        }
      );

      if (!res.ok) {
        throw new Error((await res.text().catch(() => "")) || "Failed to check username");
      }

      const data = await res.json();
      setAvailable(!!data?.available);
    } catch (e: any) {
      setUserMsg(e?.message || "Couldn’t check username.");
    } finally {
      setChecking(false);
    }
  }

  async function saveUsername() {
    setSavingUsername(true);
    setUserMsg(null);

    try {
      const u = username.trim().toLowerCase();
      const res = await fetch(`/api/users/me`, {
        method: "PATCH",
        headers: {
          "Content-Type": "application/json",
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ username: u }),
      });

      if (!res.ok) {
        throw new Error((await res.text().catch(() => "")) || "Failed to save username");
      }

      await refreshMeAndSession();

      setAvailable(true);
      setUserMsg("Username saved ✅");
      setStep(3);
    } catch (e: any) {
      setUserMsg(e?.message || "Couldn’t save username.");
    } finally {
      setSavingUsername(false);
    }
  }

  async function saveDisplayName() {
    setSavingName(true);
    setNameMsg(null);

    try {
      const next = displayName.trim();
      const res = await fetch(`/api/users/me`, {
        method: "PATCH",
        headers: {
          "Content-Type": "application/json",
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ displayName: next }),
      });

      if (!res.ok) {
        throw new Error((await res.text().catch(() => "")) || "Failed to save display name");
      }

      await refreshMeAndSession();
      setNameMsg("Saved ✅");
    } catch (e: any) {
      setNameMsg(e?.message || "Couldn’t save display name.");
    } finally {
      setSavingName(false);
    }
  }

  return (
    <div className="rounded-2xl border border-amber-500/20 bg-amber-500/5 p-6">
      <h2 className="text-lg font-semibold">Welcome to the beta 👋</h2>
      <p className="mt-1 text-sm text-zinc-300/80">
        Step {step} of 3. Password + username required.
      </p>

      {step === 1 && (
        <div className="mt-6 space-y-3">
          <div className="text-sm font-medium">Set password *</div>

          <input
            type="password"
            value={pw1}
            onChange={(e) => setPw1(e.target.value)}
            placeholder="Password (min 8 chars)"
            className="w-full rounded-md border border-white/10 bg-black/40 px-3 py-2"
          />
          <input
            type="password"
            value={pw2}
            onChange={(e) => setPw2(e.target.value)}
            placeholder="Confirm password"
            className="w-full rounded-md border border-white/10 bg-black/40 px-3 py-2"
          />

          {(pwTooShort || pwMismatch) && (
            <div className="text-xs text-red-300">
              {pwTooShort ? "Password must be at least 8 characters." : "Passwords don’t match."}
            </div>
          )}

          <button
            type="button"
            onClick={savePassword}
            disabled={!canSavePassword}
            className="rounded-md bg-amber-400 px-4 py-2 text-sm font-medium text-black disabled:opacity-50"
          >
            {pwSaving ? "Saving…" : "Save password"}
          </button>

          {pwMsg && <div className="text-xs text-zinc-200/80">{pwMsg}</div>}

          <div className="pt-4 border-t border-white/10 flex items-center justify-between">
            <button
              type="button"
              onClick={logout}
              className="text-xs underline opacity-70 hover:opacity-100"
            >
              Log out
            </button>
          </div>
        </div>
      )}

      {step === 2 && (
        <div className="mt-6 space-y-3">
          <div className="text-sm font-medium">Choose username *</div>

          <input
            value={username}
            onChange={(e) => {
              setUsername(e.target.value);
              setAvailable(null);
              setUserMsg(null);
            }}
            placeholder="e.g. s2tactical"
            className="w-full rounded-md border border-white/10 bg-black/40 px-3 py-2"
          />

          <div className="flex items-center gap-2">
            <button
              type="button"
              onClick={checkUsername}
              disabled={checking || savingUsername || username.trim().length < 3}
              className="rounded-md border border-white/10 px-3 py-2 text-xs hover:bg-white/5 disabled:opacity-50"
            >
              {checking ? "Checking…" : "Check availability"}
            </button>

            <button
              type="button"
              onClick={saveUsername}
              disabled={savingUsername || available !== true}
              className="rounded-md bg-amber-400 px-3 py-2 text-xs font-medium text-black disabled:opacity-50"
            >
              {savingUsername ? "Saving…" : "Save username"}
            </button>

            {available !== null && (
              <span className={`text-xs ${available ? "text-emerald-300" : "text-red-300"}`}>
                {available ? "Available" : "Taken / invalid"}
              </span>
            )}
          </div>

          {userMsg && <div className="text-xs text-zinc-200/80">{userMsg}</div>}

          <div className="pt-4 border-t border-white/10 flex items-center justify-between">
            <button
              type="button"
              onClick={logout}
              className="text-xs underline opacity-70 hover:opacity-100"
            >
              Log out
            </button>
          </div>
        </div>
      )}

      {step === 3 && (
        <div className="mt-6 space-y-3">
          <div className="text-sm font-medium">
            Display name <span className="text-zinc-400">(optional)</span>
          </div>

          <input
            value={displayName}
            onChange={(e) => setDisplayName(e.target.value)}
            placeholder="e.g. Sean / S2Tactical / DirtNinja69"
            className="w-full rounded-md border border-white/10 bg-black/40 px-3 py-2"
          />

          <button
            type="button"
            onClick={saveDisplayName}
            disabled={savingName || displayName.trim().length === 0}
            className="rounded-md border border-white/10 px-3 py-2 text-xs hover:bg-white/5 disabled:opacity-50"
          >
            {savingName ? "Saving…" : "Save display name"}
          </button>

          {nameMsg && <div className="text-xs text-zinc-200/80">{nameMsg}</div>}

          <div className="mt-6 flex items-center justify-between border-t border-white/10 pt-4">
            <button
              type="button"
              onClick={() => router.replace("/builder")}
              disabled={!(hasUsername && hasPassword)}
              className="rounded-md bg-amber-400 px-4 py-2 text-sm font-medium text-black disabled:opacity-50"
            >
              Continue to Builder
            </button>

            <button
              type="button"
              onClick={() => router.replace("/account/profile")}
              className="text-xs underline opacity-70 hover:opacity-100"
            >
              I’ll finish later
            </button>
          </div>
        </div>
      )}
    </div>
  );
}