import axios from "axios";
import { FormEvent, useEffect, useState } from "react";
import { checkEmailStatus, registerRequest } from "../api/auth";
import { useAuthStore } from "../store/authStore";

type Step = "email" | "password" | "register" | "otp";
const AUTH_NOTICE_KEY = "bm_auth_notice";

export function AuthPanel() {
  const login = useAuthStore((s) => s.login);
  const loading = useAuthStore((s) => s.loading);
  const [step, setStep] = useState<Step>("email");
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [otpCode, setOtpCode] = useState("");
  const [recoveryCode, setRecoveryCode] = useState("");
  const [useRecoveryCode, setUseRecoveryCode] = useState(false);
  const [checkingEmail, setCheckingEmail] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);

  useEffect(() => {
    const notice = window.localStorage.getItem(AUTH_NOTICE_KEY);
    if (!notice) {
      return;
    }
    setSuccess(notice);
    window.localStorage.removeItem(AUTH_NOTICE_KEY);
  }, []);

  async function onSubmit(event: FormEvent) {
    event.preventDefault();
    setError(null);
    setSuccess(null);
    try {
      if (step === "email") {
        const normalizedEmail = email.trim().toLowerCase();
        if (!normalizedEmail) {
          setError("Enter email.");
          return;
        }
        setCheckingEmail(true);
        try {
          const status = await checkEmailStatus(normalizedEmail);
          setEmail(normalizedEmail);
          setStep(status.registered ? "password" : "register");
        } finally {
          setCheckingEmail(false);
        }
        return;
      }

      if (step === "register") {
        await registerRequest(email, name, username, password);
        setSuccess("Account created. Verify email and continue login.");
        setStep("password");
        return;
      }

      if (step === "password") {
        await login(email, password);
        return;
      }

      await login(
        email,
        password,
        useRecoveryCode ? undefined : (otpCode.trim() || undefined),
        useRecoveryCode ? (recoveryCode.trim() || undefined) : undefined
      );
    } catch (err) {
      const message = getErrorMessage(err);
      if (step === "password" && message.toLowerCase().includes("2fa code required")) {
        setStep("otp");
        setError(null);
        setSuccess("Enter 2FA code or use a recovery code.");
        return;
      }
      setError(message);
      setSuccess(null);
    }
  }

  function resetToEmail() {
    setStep("email");
    setPassword("");
    setOtpCode("");
    setRecoveryCode("");
    setUseRecoveryCode(false);
    setName("");
    setUsername("");
    setError(null);
    setSuccess(null);
  }

  const submitLabel =
    step === "email"
      ? "Continue"
      : step === "register"
        ? "Create account"
        : step === "password"
          ? "Next"
          : "Sign in";

  const isBusy = loading || checkingEmail;

  return (
    <div className="mx-auto mt-16 w-full max-w-md rounded-2xl border border-slate-700/70 bg-panel p-6 shadow-xl">
      <p className="mb-1 text-xl font-semibold">
        {step === "email" ? "Sign in to BenyaMessenger" : step === "register" ? "Create account" : "Enter credentials"}
      </p>
      <p className="mb-4 text-sm text-slate-400">
        {step === "email"
          ? "Enter your email to continue"
          : step === "register"
            ? "This email is not registered yet. Complete registration."
            : step === "password"
              ? "Enter your password"
              : "Two-factor authentication is enabled"}
      </p>

      <form className="space-y-3" onSubmit={onSubmit}>
        <div className="space-y-2">
          <input
            className="w-full rounded bg-slate-800 px-3 py-2"
            disabled={step !== "email"}
            placeholder="Email"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
          {step !== "email" ? (
            <button className="text-xs text-sky-300 hover:text-sky-200" onClick={resetToEmail} type="button">
              Change email
            </button>
          ) : null}
        </div>

        {step === "register" ? (
          <>
            <input className="w-full rounded bg-slate-800 px-3 py-2" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
            <input
              className="w-full rounded bg-slate-800 px-3 py-2"
              placeholder="Username"
              value={username}
              onChange={(e) => setUsername(e.target.value.replace("@", ""))}
            />
          </>
        ) : null}

        {step === "password" || step === "register" || step === "otp" ? (
          <input
            className="w-full rounded bg-slate-800 px-3 py-2"
            placeholder="Password"
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
        ) : null}

        {step === "otp" ? (
          <>
            <button
              className="text-xs text-sky-300 hover:text-sky-200"
              onClick={() => setUseRecoveryCode((v) => !v)}
              type="button"
            >
              {useRecoveryCode ? "Use 2FA code instead" : "Use recovery code"}
            </button>
            {useRecoveryCode ? (
              <input
                className="w-full rounded bg-slate-800 px-3 py-2"
                placeholder="Recovery code"
                value={recoveryCode}
                onChange={(e) => setRecoveryCode(e.target.value.toUpperCase().replace(/[^A-Z0-9-]/g, "").slice(0, 24))}
              />
            ) : (
              <input
                className="w-full rounded bg-slate-800 px-3 py-2"
                placeholder="2FA code"
                value={otpCode}
                onChange={(e) => setOtpCode(e.target.value.replace(/\D/g, "").slice(0, 8))}
              />
            )}
          </>
        ) : null}

        <button className="w-full rounded bg-accent px-3 py-2 font-semibold text-black disabled:opacity-50" disabled={isBusy} type="submit">
          {submitLabel}
        </button>
      </form>
      {error ? <p className="mt-3 text-sm text-red-400">{error}</p> : null}
      {success ? <p className="mt-3 text-sm text-emerald-400">{success}</p> : null}
    </div>
  );
}

function getErrorMessage(err: unknown): string {
  if (axios.isAxiosError(err)) {
    const detail = err.response?.data?.detail;
    if (typeof detail === "string" && detail.trim()) {
      return detail;
    }
    if (typeof err.message === "string" && err.message.trim()) {
      return err.message;
    }
  }
  if (err instanceof Error && err.message) {
    return err.message;
  }
  return "Auth request failed.";
}
