"use client";

import {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
  type ClipboardEvent,
  type FormEvent,
  type KeyboardEvent,
} from "react";
import Link from "next/link";
import { AnimatePresence, motion } from "framer-motion";
import {
  AlertCircle,
  Check,
  CheckCircle2,
  Circle,
  Eye,
  EyeOff,
  Loader2,
  Mail,
  Sparkles,
} from "lucide-react";
import { requestPasswordReset } from "@/lib/auth";

const PUBLISHABLE_KEY =
  process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "";
const MEDUSA_URL =
  process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL || "https://ot.azulado.cloud";

type Step = 1 | 2 | 3 | 4;

const emailOk = (value: string) =>
  /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim().toLowerCase());

function maskEmail(email: string) {
  const [user, domain] = email.split("@");
  if (!user || !domain) return email;
  return `${user.slice(0, 2)}••••@${domain}`;
}

function passwordChecks(password: string) {
  return [
    { id: "len", label: "Mínimo 8 caracteres", ok: password.length >= 8 },
    { id: "upper", label: "Una mayúscula", ok: /[A-Z]/.test(password) },
    { id: "num", label: "Un número", ok: /\d/.test(password) },
    { id: "sym", label: "Un símbolo", ok: /[^A-Za-z0-9]/.test(password) },
  ];
}

function strengthScore(password: string) {
  const ok = passwordChecks(password).filter((c) => c.ok).length;
  if (!password) return { score: 0, label: "Escribe una clave" };
  if (ok <= 1) return { score: 1, label: "Débil" };
  if (ok === 2) return { score: 2, label: "Aceptable" };
  if (ok === 3) return { score: 3, label: "Segura" };
  return { score: 4, label: "Muy segura" };
}

const stepMeta = [
  { n: 1, label: "Email" },
  { n: 2, label: "Código" },
  { n: 3, label: "Clave" },
  { n: 4, label: "Listo" },
];

const fade = {
  initial: { opacity: 0, y: 18, scale: 0.98 },
  animate: { opacity: 1, y: 0, scale: 1 },
  exit: { opacity: 0, y: -12, scale: 0.98 },
};

const AUTH_HEADERS = {
  "Content-Type": "application/json",
  accept: "application/json",
  ...(PUBLISHABLE_KEY ? { "x-publishable-api-key": PUBLISHABLE_KEY } : {}),
};

export function ResetWizard() {
  const [step, setStep] = useState<Step>(1);
  const [email, setEmail] = useState("");
  const [otp, setOtp] = useState(["", "", "", "", "", ""]);
  const [ticket, setTicket] = useState("");
  const [password, setPassword] = useState("");
  const [confirm, setConfirm] = useState("");
  const [showPass, setShowPass] = useState(false);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);
  const otpRefs = useRef<Array<HTMLInputElement | null>>([]);

  const validEmail = emailOk(email);
  const checks = useMemo(() => passwordChecks(password), [password]);
  const strength = useMemo(() => strengthScore(password), [password]);
  const match = confirm.length > 0 && confirm === password;
  const mismatch = confirm.length > 0 && confirm !== password;
  const canSave = checks.every((c) => c.ok) && match;

  const sendCode = async (e?: FormEvent) => {
    e?.preventDefault();
    if (!validEmail || busy) return;
    setError(null);
    setBusy(true);
    try {
      await requestPasswordReset(email);
      setOtp(["", "", "", "", "", ""]);
      setInfo("Te enviamos un código de 6 dígitos.");
      setStep(2);
      setTimeout(() => otpRefs.current[0]?.focus(), 250);
    } catch {
      setError("No se pudo enviar el código. Inténtalo de nuevo.");
    } finally {
      setBusy(false);
    }
  };

  const verifyOtp = useCallback(
    async (code: string) => {
      if (code.length !== 6 || busy) return;
      setError(null);
      setBusy(true);
      try {
        const res = await fetch(`${MEDUSA_URL}/store/ot-reset/verify`, {
          method: "POST",
          headers: AUTH_HEADERS,
          body: JSON.stringify({ email: email.trim().toLowerCase(), otp: code }),
        });
        const data = (await res.json().catch(() => ({}))) as {
          ticket?: string;
          message?: string;
        };
        if (!res.ok || !data.ticket) {
          throw new Error(data.message || "Código incorrecto.");
        }
        setTicket(data.ticket);
        setInfo("Código verificado.");
        setStep(3);
      } catch (err) {
        setError(err instanceof Error ? err.message : "Código incorrecto.");
        setOtp(["", "", "", "", "", ""]);
        setTimeout(() => otpRefs.current[0]?.focus(), 50);
      } finally {
        setBusy(false);
      }
    },
    [busy, email]
  );

  const savePassword = async (e: FormEvent) => {
    e.preventDefault();
    if (!canSave || busy) return;
    setError(null);
    setBusy(true);
    try {
      const res = await fetch(`${MEDUSA_URL}/store/ot-reset/complete`, {
        method: "POST",
        headers: AUTH_HEADERS,
        body: JSON.stringify({ ticket, password }),
      });
      const data = (await res.json().catch(() => ({}))) as { message?: string };
      if (!res.ok) {
        throw new Error(data.message || "No se pudo guardar la contraseña.");
      }
      setStep(4);
    } catch (err) {
      setError(err instanceof Error ? err.message : "No se pudo guardar.");
    } finally {
      setBusy(false);
    }
  };

  const onOtpChange = (index: number, raw: string) => {
    const value = raw.replace(/\D/g, "").slice(-1);
    const next = [...otp];
    next[index] = value;
    setOtp(next);
    if (value && index < 5) otpRefs.current[index + 1]?.focus();
    const code = next.join("");
    if (code.length === 6) verifyOtp(code);
  };

  const onOtpKey = (index: number, e: KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Backspace" && !otp[index] && index > 0) {
      otpRefs.current[index - 1]?.focus();
    }
    if (e.key === "Enter") {
      e.preventDefault();
      const code = otp.join("");
      if (code.length === 6) verifyOtp(code);
    }
  };

  const onOtpPaste = (e: ClipboardEvent<HTMLInputElement>) => {
    e.preventDefault();
    const text = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, 6);
    if (!text) return;
    const next = ["", "", "", "", "", ""];
    text.split("").forEach((d, i) => {
      next[i] = d;
    });
    setOtp(next);
    otpRefs.current[Math.min(text.length, 5)]?.focus();
    if (text.length === 6) verifyOtp(text);
  };

  useEffect(() => {
    setError(null);
  }, [step]);

  return (
    <div className="relative min-h-[100dvh] overflow-hidden bg-[#07140f] text-white">
      <div className="pointer-events-none absolute -top-24 left-[-10%] h-[420px] w-[420px] rounded-full bg-[#7c5cbf]/25 blur-[90px]" />
      <div className="pointer-events-none absolute top-[20%] right-[-8%] h-[380px] w-[380px] rounded-full bg-[#a68b5b]/20 blur-[100px]" />
      <div className="pointer-events-none absolute bottom-[-12%] left-[20%] h-[340px] w-[340px] rounded-full bg-[#002d20]/80 blur-[80px]" />

      <div className="relative z-10 mx-auto flex min-h-[100dvh] max-w-lg flex-col justify-center px-4 py-10">
        <p className="mb-6 text-center font-serif text-3xl tracking-[0.2em] text-[#f2efe9]">
          OT
        </p>

        <div className="overflow-hidden rounded-2xl bg-white text-[#141414] shadow-[0_30px_80px_rgba(0,0,0,0.35)]">
          <div
            className="h-[3px] w-full"
            style={{
              background:
                "linear-gradient(90deg, #7c5cbf 0%, #a68b5b 50%, #002d20 100%)",
            }}
          />

          <div className="px-6 pb-8 pt-6 sm:px-8">
            <div className="mb-7 flex items-center justify-center gap-2">
              {stepMeta.map((item) => (
                <motion.span
                  key={item.n}
                  layout
                  className="h-1.5 rounded-full"
                  animate={{
                    width: step === item.n ? 36 : 10,
                    backgroundColor:
                      step >= item.n ? "#002d20" : "rgba(20,20,20,0.12)",
                  }}
                  transition={{ type: "spring", stiffness: 320, damping: 28 }}
                  title={item.label}
                />
              ))}
            </div>

            <AnimatePresence mode="wait">
              {step === 1 && (
                <motion.form
                  key="email"
                  {...fade}
                  transition={{ duration: 0.28 }}
                  onSubmit={sendCode}
                  className="space-y-5"
                >
                  <div>
                    <p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-[#a68b5b]">
                      Paso 1 de 4
                    </p>
                    <h1 className="mt-2 text-[1.85rem] font-semibold leading-tight tracking-tight">
                      Clave de OLD TENNIS
                    </h1>
                    <p className="mt-2 text-sm text-[#6f685e]">
                      Te enviaremos un código para crear o cambiar la clave de
                      esta tienda. No modifica tu Gmail ni tu acceso con Google.
                    </p>
                  </div>
                  <label className="block">
                    <span className="mb-1.5 block text-xs font-medium text-[#6f685e]">
                      Email
                    </span>
                    <div className="relative">
                      <Mail
                        size={16}
                        className="pointer-events-none absolute left-3.5 top-1/2 -translate-y-1/2 text-[#6f685e]"
                      />
                      <input
                        type="email"
                        autoComplete="email"
                        autoFocus
                        value={email}
                        onChange={(e) => setEmail(e.target.value)}
                        placeholder="tú@email.com"
                        className="w-full rounded-xl border border-black/10 bg-[#fbfaf7] py-3.5 pl-10 pr-10 text-sm outline-none transition focus:border-[#002d20]"
                      />
                      {validEmail && (
                        <CheckCircle2
                          size={16}
                          className="absolute right-3.5 top-1/2 -translate-y-1/2 text-[#002d20]"
                        />
                      )}
                    </div>
                    {email.length > 3 && !validEmail && (
                      <p className="mt-2 flex items-center gap-1.5 text-xs text-red-700">
                        <AlertCircle size={13} />
                        Escribe un email válido.
                      </p>
                    )}
                  </label>
                  {error && (
                    <p className="flex items-center gap-1.5 text-sm text-red-700">
                      <AlertCircle size={15} />
                      {error}
                    </p>
                  )}
                  <button
                    type="submit"
                    disabled={!validEmail || busy}
                    className="flex w-full items-center justify-center gap-2 rounded-xl bg-[#002d20] py-3.5 text-sm font-semibold text-[#f7f3ea] transition hover:bg-[#1a4334] disabled:opacity-40"
                  >
                    {busy ? <Loader2 size={16} className="animate-spin" /> : null}
                    {busy ? "Enviando…" : "Enviar código"}
                  </button>
                </motion.form>
              )}

              {step === 2 && (
                <motion.form
                  key="otp"
                  {...fade}
                  transition={{ duration: 0.28 }}
                  onSubmit={(e) => {
                    e.preventDefault();
                    verifyOtp(otp.join(""));
                  }}
                  className="space-y-5"
                >
                  <div>
                    <p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-[#a68b5b]">
                      Paso 2 de 4
                    </p>
                    <h1 className="mt-2 text-[1.85rem] font-semibold leading-tight tracking-tight">
                      Revisa tu correo
                    </h1>
                    <p className="mt-2 text-sm text-[#6f685e]">
                      Enviamos un código de OLD TENNIS a{" "}
                      <strong className="text-[#141414]">{maskEmail(email)}</strong>
                      . Sirve solo para la clave de la tienda, no para Gmail.
                    </p>
                  </div>
                  <div className="flex justify-between gap-2">
                    {otp.map((digit, i) => (
                      <input
                        key={i}
                        ref={(el) => {
                          otpRefs.current[i] = el;
                        }}
                        inputMode="numeric"
                        autoComplete={i === 0 ? "one-time-code" : "off"}
                        maxLength={1}
                        value={digit}
                        onChange={(e) => onOtpChange(i, e.target.value)}
                        onKeyDown={(e) => onOtpKey(i, e)}
                        onPaste={onOtpPaste}
                        className="h-14 w-full rounded-xl border border-black/10 bg-[#fbfaf7] text-center text-xl font-semibold outline-none transition focus:border-[#002d20] focus:shadow-[0_0_0_3px_rgba(0,45,32,0.12)]"
                      />
                    ))}
                  </div>
                  {info && !error && (
                    <p className="flex items-center gap-1.5 text-sm text-[#002d20]">
                      <CheckCircle2 size={15} />
                      {info}
                    </p>
                  )}
                  {error && (
                    <p className="flex items-center gap-1.5 text-sm text-red-700">
                      <AlertCircle size={15} />
                      {error}
                    </p>
                  )}
                  <button
                    type="submit"
                    disabled={otp.join("").length !== 6 || busy}
                    className="flex w-full items-center justify-center gap-2 rounded-xl bg-[#002d20] py-3.5 text-sm font-semibold text-[#f7f3ea] disabled:opacity-40"
                  >
                    {busy ? <Loader2 size={16} className="animate-spin" /> : null}
                    {busy ? "Verificando…" : "Verificar código"}
                  </button>
                  <button
                    type="button"
                    className="w-full text-center text-xs text-[#6f685e] hover:text-[#002d20]"
                    onClick={() => sendCode()}
                    disabled={busy}
                  >
                    Reenviar código
                  </button>
                </motion.form>
              )}

              {step === 3 && (
                <motion.form
                  key="password"
                  {...fade}
                  transition={{ duration: 0.28 }}
                  onSubmit={savePassword}
                  className="space-y-5"
                >
                  <div>
                    <p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-[#a68b5b]">
                      Paso 3 de 4
                    </p>
                    <h1 className="mt-2 text-[1.85rem] font-semibold leading-tight tracking-tight">
                      Nueva clave de OLD TENNIS
                    </h1>
                    <p className="mt-2 text-sm text-[#6f685e]">
                      Esta clave es solo para entrar a la tienda con correo.
                    </p>
                  </div>
                  <label className="block">
                    <span className="mb-1.5 block text-xs font-medium text-[#6f685e]">
                      Clave de OLD TENNIS
                    </span>
                    <div className="relative">
                      <input
                        type={showPass ? "text" : "password"}
                        autoComplete="new-password"
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        placeholder="Crea una clave solo para la tienda"
                        className="w-full rounded-xl border border-black/10 bg-[#fbfaf7] py-3.5 px-4 pr-11 text-sm outline-none focus:border-[#002d20]"
                      />
                      <button
                        type="button"
                        onClick={() => setShowPass((v) => !v)}
                        className="absolute right-3.5 top-1/2 -translate-y-1/2 text-[#6f685e] hover:text-[#002d20]"
                        aria-label={showPass ? "Ocultar contraseña" : "Ver contraseña"}
                      >
                        {showPass ? <EyeOff size={17} /> : <Eye size={17} />}
                      </button>
                    </div>
                  </label>
                  <div>
                    <div className="flex gap-1">
                      {[1, 2, 3, 4].map((n) => (
                        <span
                          key={n}
                          className={`h-1.5 flex-1 rounded-full ${
                            n <= strength.score
                              ? strength.score >= 4
                                ? "bg-[#002d20]"
                                : strength.score === 3
                                  ? "bg-[#1a4334]"
                                  : strength.score === 2
                                    ? "bg-[#a68b5b]"
                                    : "bg-red-700"
                              : "bg-black/10"
                          }`}
                        />
                      ))}
                    </div>
                    <p className="mt-2 text-xs font-medium text-[#002d20]">
                      {strength.label}
                    </p>
                    <ul className="mt-3 space-y-1.5">
                      {checks.map((c) => (
                        <li
                          key={c.id}
                          className={`flex items-center gap-2 text-xs ${
                            c.ok ? "text-[#002d20]" : "text-[#6f685e]"
                          }`}
                        >
                          {c.ok ? <Check size={13} /> : <Circle size={13} />}
                          {c.label}
                        </li>
                      ))}
                    </ul>
                  </div>
                  <label className="block">
                    <span className="mb-1.5 block text-xs font-medium text-[#6f685e]">
                      Confirmar
                    </span>
                    <input
                      type={showPass ? "text" : "password"}
                      autoComplete="new-password"
                      value={confirm}
                      onChange={(e) => setConfirm(e.target.value)}
                      placeholder="Repite la clave de OLD TENNIS"
                      className={`w-full rounded-xl border bg-[#fbfaf7] py-3.5 px-4 text-sm outline-none ${
                        mismatch
                          ? "border-red-700"
                          : match
                            ? "border-[#002d20]"
                            : "border-black/10 focus:border-[#002d20]"
                      }`}
                    />
                    {match && (
                      <p className="mt-2 flex items-center gap-1.5 text-xs text-[#002d20]">
                        <CheckCircle2 size={13} />
                        Las claves coinciden.
                      </p>
                    )}
                    {mismatch && (
                      <p className="mt-2 flex items-center gap-1.5 text-xs text-red-700">
                        <AlertCircle size={13} />
                        No coinciden todavía.
                      </p>
                    )}
                  </label>
                  {error && (
                    <p className="flex items-center gap-1.5 text-sm text-red-700">
                      <AlertCircle size={15} />
                      {error}
                    </p>
                  )}
                  <button
                    type="submit"
                    disabled={!canSave || busy}
                    className="flex w-full items-center justify-center gap-2 rounded-xl bg-[#002d20] py-3.5 text-sm font-semibold text-[#f7f3ea] disabled:opacity-40"
                  >
                    {busy ? <Loader2 size={16} className="animate-spin" /> : null}
                    {busy ? "Guardando…" : "Guardar clave de OLD TENNIS"}
                  </button>
                </motion.form>
              )}

              {step === 4 && (
                <motion.div
                  key="ok"
                  initial={{ opacity: 0, y: 16 }}
                  animate={{ opacity: 1, y: 0 }}
                  transition={{ type: "spring", stiffness: 220, damping: 22 }}
                  className="text-center"
                >
                  <div className="relative overflow-hidden rounded-2xl bg-[#f7f3ea] px-5 py-10 sm:px-8">
                    <div
                      className="pointer-events-none absolute inset-x-0 top-0 h-[3px]"
                      style={{
                        background:
                          "linear-gradient(90deg, #7c5cbf 0%, #a68b5b 50%, #002d20 100%)",
                      }}
                    />
                    <motion.div
                      initial={{ scale: 0.6, opacity: 0 }}
                      animate={{ scale: 1, opacity: 1 }}
                      transition={{ type: "spring", stiffness: 280, damping: 16, delay: 0.08 }}
                      className="mx-auto grid h-[4.5rem] w-[4.5rem] place-items-center rounded-full bg-[#002d20] text-[#f2efe9] shadow-[0_10px_28px_rgba(0,45,32,0.28)] ring-[6px] ring-[#a68b5b]/25"
                    >
                      <CheckCircle2 size={34} strokeWidth={1.75} />
                    </motion.div>
                    <p className="mt-6 inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.22em] text-[#a68b5b]">
                      <Sparkles size={12} />
                      Listo
                    </p>
                    <h1 className="mt-2 font-serif text-[2rem] leading-tight tracking-tight text-[#002d20]">
                      Clave de OLD TENNIS lista
                    </h1>
                    <p className="mx-auto mt-3 max-w-[16rem] text-sm leading-relaxed text-[#6f685e]">
                      Ya puedes entrar con tu correo y esta clave.
                    </p>
                    <Link
                      href="/account?mode=login"
                      className="mt-8 inline-flex w-full items-center justify-center rounded-xl bg-[#002d20] py-3.5 text-sm font-semibold tracking-[0.08em] text-[#f7f3ea] uppercase transition hover:bg-[#1a4334]"
                    >
                      Bienvenido
                    </Link>
                  </div>
                </motion.div>
              )}
            </AnimatePresence>
          </div>
        </div>

        {step !== 4 && (
          <Link
            href="/account"
            className="mt-6 text-center text-xs tracking-[0.14em] uppercase text-white/55 hover:text-white"
          >
            Volver a la cuenta
          </Link>
        )}
      </div>
    </div>
  );
}
