import { useState, useEffect, useRef } from "react";
import { Navigate } from "react-router-dom";
import { motion, AnimatePresence } from "framer-motion";
import { useAuth } from "../context/AuthContext";
import { useAlert } from "../context/AlertContext";
import { useTheme } from "../../context/ThemeContext";
import {
  shouldShowSessionExpiredAlert,
  shouldShowLogoutAlert,
} from "../utils/api";
import FormField from "../components/FormField";

export default function Login() {
  const { login, verify2FA, isAuthenticated, loading: authLoading } = useAuth();
  const alert = useAlert();
  const { theme, toggleTheme } = useTheme();
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [remember, setRemember] = useState(false);
  const [loading, setLoading] = useState(false);
  const [shake, setShake] = useState(false);
  const [animatingOut, setAnimatingOut] = useState(false);

  // 2FA state
  const [show2FA, setShow2FA] = useState(false);
  const [loginToken, setLoginToken] = useState<string | null>(null);
  const [totpCode, setTotpCode] = useState("");
  const [useBackupCode, setUseBackupCode] = useState(false);
  const totpInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (shouldShowSessionExpiredAlert()) {
      alert.warning("Vaše relace vypršela. Přihlaste se prosím znovu.");
    } else if (shouldShowLogoutAlert()) {
      alert.success("Byli jste úspěšně odhlášeni.");
    }
  }, [alert]);

  // Auto-focus TOTP input
  useEffect(() => {
    if (show2FA && totpInputRef.current) {
      totpInputRef.current.focus();
    }
  }, [show2FA, useBackupCode]);

  if (authLoading) {
    return (
      <div className="admin-login">
        <div className="admin-loading">
          <div className="admin-spinner" />
        </div>
      </div>
    );
  }

  if (isAuthenticated && !animatingOut) {
    return <Navigate to="/" replace />;
  }

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setLoading(true);

    const result = await login(username, password, remember);

    if (result.requires2FA) {
      setLoginToken(result.loginToken ?? null);
      setShow2FA(true);
      setTotpCode("");
      setLoading(false);
    } else if (!result.success) {
      alert.error(result.error ?? "Chyba přihlášení");
      setShake(true);
      setTimeout(() => setShake(false), 500);
      setLoading(false);
    } else {
      alert.success("Úspěšně přihlášeno");
      setAnimatingOut(true);
      setTimeout(() => setAnimatingOut(false), 400);
    }
  };

  const handle2FASubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!totpCode.trim()) return;

    setLoading(true);

    const result = await verify2FA(
      loginToken!,
      totpCode.trim(),
      remember,
      useBackupCode,
    );

    if (!result.success) {
      alert.error(result.error ?? "Chyba ověření");
      setShake(true);
      setTimeout(() => setShake(false), 500);
      setTotpCode("");
      if (totpInputRef.current) totpInputRef.current.focus();
      setLoading(false);
    } else {
      alert.success("Úspěšně přihlášeno");
      setAnimatingOut(true);
      setTimeout(() => setAnimatingOut(false), 400);
    }
  };

  const handleBack = () => {
    setShow2FA(false);
    setLoginToken(null);
    setTotpCode("");
    setUseBackupCode(false);
  };

  return (
    <motion.div
      className="admin-login"
      initial={{ opacity: 0, scale: 0.98 }}
      animate={
        animatingOut
          ? { scale: 1.5, opacity: 0, filter: "blur(12px)" }
          : { scale: 1, opacity: 1, filter: "none" }
      }
      transition={
        animatingOut
          ? { duration: 0.25, ease: [0.4, 0, 0.2, 1] }
          : { duration: 0.25, ease: [0.4, 0, 0.2, 1] }
      }
    >
      <div className="bg-orb bg-orb-1" />
      <div className="bg-orb bg-orb-2" />

      <button
        onClick={toggleTheme}
        className="admin-login-theme-btn"
        title={theme === "dark" ? "Světlý režim" : "Tmavý režim"}
      >
        <span
          className={`admin-theme-icon ${theme === "light" ? "visible" : ""}`}
        >
          <svg
            width="20"
            height="20"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
          >
            <circle cx="12" cy="12" r="5" />
            <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
          </svg>
        </span>
        <span
          className={`admin-theme-icon ${theme === "dark" ? "visible" : ""}`}
        >
          <svg
            width="20"
            height="20"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
          >
            <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
          </svg>
        </span>
      </button>

      <AnimatePresence mode="wait">
        {!show2FA ? (
          <motion.div
            key="login"
            className="admin-login-card"
            initial={{ opacity: 0, y: 30 }}
            animate={
              shake
                ? { opacity: 1, y: 0, x: [0, -12, 12, -8, 8, -4, 4, 0] }
                : { opacity: 1, y: 0 }
            }
            exit={{ opacity: 0, y: -20 }}
            transition={
              shake
                ? { x: { duration: 0.5, ease: "easeOut" } }
                : { duration: 0.3 }
            }
          >
            <div className="admin-login-header">
              <img
                src={
                  theme === "dark"
                    ? "/api/admin/company-settings/logo?variant=dark"
                    : "/api/admin/company-settings/logo?variant=light"
                }
                alt="Logo"
                className="admin-login-logo"
                onError={(e) => {
                  (e.target as HTMLImageElement).src =
                    theme === "dark"
                      ? "/images/logo-dark.png"
                      : "/images/logo-light.png";
                }}
              />
              <h1 className="admin-login-title">Interní systém</h1>
              <p className="admin-login-subtitle">Přihlaste se ke svému účtu</p>
            </div>

            <form onSubmit={handleSubmit} className="admin-form">
              <FormField label="Uživatelské jméno nebo e-mail">
                <input
                  id="username"
                  type="text"
                  value={username}
                  onChange={(e) => setUsername(e.target.value)}
                  required
                  autoComplete="username"
                  className="admin-form-input"
                  placeholder="Zadejte uživatelské jméno"
                />
              </FormField>

              <FormField label="Heslo">
                <input
                  id="password"
                  type="password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  required
                  autoComplete="current-password"
                  className="admin-form-input"
                  placeholder="Zadejte heslo"
                />
              </FormField>

              <label className="admin-form-checkbox">
                <input
                  type="checkbox"
                  checked={remember}
                  onChange={(e) => setRemember(e.target.checked)}
                />
                <span>Zapamatovat si mě</span>
              </label>

              <button
                type="submit"
                disabled={loading}
                className="admin-btn admin-btn-primary"
                style={{ width: "100%" }}
              >
                {loading ? (
                  <>
                    <div
                      className="admin-spinner"
                      style={{ width: 20, height: 20, borderWidth: 2 }}
                    />
                    Přihlašování...
                  </>
                ) : (
                  "Přihlásit se"
                )}
              </button>
            </form>
          </motion.div>
        ) : (
          <motion.div
            key="2fa"
            className="admin-login-card"
            initial={{ opacity: 0, y: 30 }}
            animate={
              shake
                ? { opacity: 1, y: 0, x: [0, -12, 12, -8, 8, -4, 4, 0] }
                : { opacity: 1, y: 0 }
            }
            exit={{ opacity: 0, y: -20 }}
            transition={
              shake
                ? { x: { duration: 0.5, ease: "easeOut" } }
                : { duration: 0.3 }
            }
          >
            <div className="admin-login-header">
              <div className="admin-login-2fa-icon">
                <svg
                  width="32"
                  height="32"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="1.5"
                >
                  <rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
                  <path d="M7 11V7a5 5 0 0 1 10 0v4" />
                </svg>
              </div>
              <h1 className="admin-login-title">Dvoufaktorové ověření</h1>
              <p className="admin-login-subtitle">
                {useBackupCode
                  ? "Zadejte jeden ze záložních kódů"
                  : "Zadejte 6místný kód z autentizační aplikace"}
              </p>
            </div>

            <form onSubmit={handle2FASubmit} className="admin-form">
              <FormField
                label={useBackupCode ? "Záložní kód" : "Ověřovací kód"}
              >
                <input
                  ref={totpInputRef}
                  id="totp-code"
                  type="text"
                  inputMode={useBackupCode ? "text" : "numeric"}
                  pattern={useBackupCode ? undefined : "[0-9]*"}
                  maxLength={useBackupCode ? 8 : 6}
                  value={totpCode}
                  onChange={(e) => {
                    const val = useBackupCode
                      ? e.target.value
                      : e.target.value.replace(/\D/g, "");
                    setTotpCode(val);
                  }}
                  required
                  autoComplete="one-time-code"
                  className="admin-form-input"
                  placeholder={useBackupCode ? "XXXXXXXX" : "000000"}
                  style={
                    useBackupCode
                      ? {}
                      : {
                          textAlign: "center",
                          fontSize: "1.5rem",
                          letterSpacing: "0.5rem",
                          fontFamily: "monospace",
                        }
                  }
                />
              </FormField>

              <button
                type="submit"
                disabled={loading}
                className="admin-btn admin-btn-primary"
                style={{ width: "100%" }}
              >
                {loading ? (
                  <>
                    <div
                      className="admin-spinner"
                      style={{ width: 20, height: 20, borderWidth: 2 }}
                    />
                    Ověřování...
                  </>
                ) : (
                  "Ověřit"
                )}
              </button>
            </form>

            <div
              style={{
                display: "flex",
                flexDirection: "column",
                gap: "0.5rem",
                marginTop: "0.5rem",
              }}
            >
              <button
                onClick={() => {
                  setUseBackupCode(!useBackupCode);
                  setTotpCode("");
                }}
                className="admin-back-link"
                style={{
                  border: "none",
                  background: "none",
                  cursor: "pointer",
                }}
              >
                {useBackupCode
                  ? "Použít autentizační aplikaci"
                  : "Použít záložní kód"}
              </button>
              <button
                onClick={handleBack}
                className="admin-back-link"
                style={{
                  border: "none",
                  background: "none",
                  cursor: "pointer",
                }}
              >
                &larr; Zpět na přihlášení
              </button>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </motion.div>
  );
}
