import { useState, useEffect, useRef, useCallback } from "react";
import { Navigate } from "react-router-dom";
import { motion, AnimatePresence } from "framer-motion";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import CircularProgress from "@mui/material/CircularProgress";
import { keyframes } from "@mui/system";
import type { Theme } from "@mui/material/styles";
import { useAuth } from "../context/AuthContext";
import { useAlert } from "../context/AlertContext";
import { useTheme } from "../../context/ThemeContext";
import {
  shouldShowSessionExpiredAlert,
  shouldShowLogoutAlert,
} from "../utils/api";
import { TextField, Button, CheckboxField, Field } from "../ui";

// Drift animation for the decorative background orbs (was @keyframes float).
const float = keyframes({
  "0%, 100%": { transform: "translate(0, 0)" },
  "50%": { transform: "translate(30px, -30px)" },
});

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.");
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

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

  const handleSubmit = useCallback(
    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);
      }
    },
    [
      username,
      password,
      remember,
      login,
      alert,
      setLoading,
      setShake,
      setAnimatingOut,
      setLoginToken,
      setShow2FA,
      setTotpCode,
    ],
  );

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

      // Defensive: the 2FA form only renders after a loginToken is issued, but
      // guard against a null token (e.g. server returns requires2FA without one)
      // rather than passing `null!` through to verify2FA.
      if (!loginToken) {
        alert.error("Relace vypršela, přihlaste se prosím znovu");
        setShow2FA(false);
        setTotpCode("");
        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);
      }
    },
    [
      totpCode,
      loginToken,
      remember,
      useBackupCode,
      verify2FA,
      alert,
      setLoading,
      setShake,
      setTotpCode,
      setShow2FA,
      setAnimatingOut,
    ],
  );

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

  if (authLoading) {
    return (
      <Box
        sx={{
          minHeight: ["100vh", "100dvh"],
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          bgcolor: "background.default",
        }}
      >
        <CircularProgress />
      </Box>
    );
  }

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

  // Shared glass card sx (replaces .admin-login-card)
  const cardSx = (theme: Theme) => ({
    width: "100%",
    maxWidth: 420,
    maxHeight: "calc(100dvh - 2rem)",
    p: { xs: 4, sm: 5 },
    bgcolor: "background.paper",
    backdropFilter: "blur(20px)",
    border: "1px solid",
    borderColor: "divider",
    borderRadius: "16px",
    boxShadow: "0 1px 3px rgba(0,0,0,0.06), 0 4px 16px rgba(0,0,0,0.04)",
    ...theme.applyStyles("dark", {
      boxShadow: "0 1px 3px rgba(0,0,0,0.2), 0 4px 16px rgba(0,0,0,0.15)",
    }),
    position: "relative" as const,
    zIndex: 1,
    overflowY: "auto" as const,
  });

  // Framer entrance + shake choreography for the card panels (unchanged)
  const cardMotion = {
    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" as const } }
      : { duration: 0.3 },
  };

  return (
    <Box
      component={motion.div}
      initial={{ opacity: 0, scale: 0.98 }}
      animate={
        animatingOut
          ? { scale: 1.5, opacity: 0, filter: "blur(12px)" }
          : { scale: 1, opacity: 1, filter: "none" }
      }
      transition={{ duration: 0.25, ease: [0.4, 0, 0.2, 1] }}
      sx={{
        minHeight: ["100vh", "100dvh"],
        maxHeight: ["100vh", "100dvh"],
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        p: 2,
        bgcolor: "background.default",
        position: "relative",
        overflow: "hidden",
        boxSizing: "border-box",
      }}
    >
      {/* Animated background orbs (replaces .bg-orb) */}
      <Box
        aria-hidden
        sx={{
          position: "absolute",
          borderRadius: "50%",
          filter: "blur(80px)",
          pointerEvents: "none",
          width: 400,
          height: 400,
          background: "rgba(var(--mui-palette-primary-mainChannel) / 0.16)",
          top: "10%",
          left: "20%",
          animation: `${float} 20s ease-in-out infinite`,
        }}
      />
      <Box
        aria-hidden
        sx={{
          position: "absolute",
          borderRadius: "50%",
          filter: "blur(80px)",
          pointerEvents: "none",
          width: 320,
          height: 320,
          background: "rgba(120, 119, 198, 0.13)",
          bottom: "20%",
          right: "15%",
          animation: `${float} 25s ease-in-out infinite reverse`,
        }}
      />

      {/* Theme toggle (replaces .admin-login-theme-btn) */}
      <IconButton
        onClick={toggleTheme}
        title={theme === "dark" ? "Světlý režim" : "Tmavý režim"}
        sx={{
          position: "absolute",
          top: "1rem",
          right: "1rem",
          width: 44,
          height: 44,
          bgcolor: "background.paper",
          backdropFilter: "blur(10px)",
          border: "1px solid",
          borderColor: "divider",
          color: "text.secondary",
          overflow: "hidden",
          zIndex: 10,
          transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
          "&:hover": {
            bgcolor: "background.paper",
            color: "text.primary",
            borderColor: "rgba(var(--mui-palette-text-primaryChannel) / 0.15)",
            transform: "scale(1.05)",
          },
        }}
      >
        {theme === "light" ? (
          <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>
        ) : (
          <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>
        )}
      </IconButton>

      <AnimatePresence mode="wait">
        {!show2FA ? (
          <Box key="login" component={motion.div} {...cardMotion} sx={cardSx}>
            <Box sx={{ textAlign: "center", mb: 4 }}>
              <Box
                component="img"
                src={
                  theme === "dark"
                    ? "/api/admin/company-settings/logo?variant=dark"
                    : "/api/admin/company-settings/logo?variant=light"
                }
                alt="Logo"
                onError={(e) => {
                  (e.target as HTMLImageElement).src =
                    theme === "dark"
                      ? "/images/logo-dark.png"
                      : "/images/logo-light.png";
                }}
                sx={{ height: 48, width: "auto", mb: 2 }}
              />
              <Typography
                variant="h1"
                sx={{
                  fontSize: "1.5rem",
                  fontWeight: 700,
                  color: "text.primary",
                  mb: 1,
                }}
              >
                Interní systém
              </Typography>
              <Typography sx={{ color: "text.secondary", fontSize: "0.95rem" }}>
                Přihlaste se ke svému účtu
              </Typography>
            </Box>

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

              <Field label="Heslo">
                <TextField
                  id="password"
                  type="password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  required
                  autoComplete="current-password"
                  placeholder="Zadejte heslo"
                />
              </Field>

              <Box sx={{ mb: 2 }}>
                <CheckboxField
                  label="Zapamatovat si mě"
                  checked={remember}
                  onChange={setRemember}
                />
              </Box>

              <Button type="submit" disabled={loading} fullWidth>
                {loading ? (
                  <>
                    <CircularProgress
                      size={20}
                      thickness={5}
                      color="inherit"
                      sx={{ mr: 1 }}
                    />
                    Přihlašování...
                  </>
                ) : (
                  "Přihlásit se"
                )}
              </Button>
            </Box>
          </Box>
        ) : (
          <Box key="2fa" component={motion.div} {...cardMotion} sx={cardSx}>
            <Box sx={{ textAlign: "center", mb: 4 }}>
              <Box
                sx={{
                  display: "inline-flex",
                  alignItems: "center",
                  justifyContent: "center",
                  width: 56,
                  height: 56,
                  borderRadius: "50%",
                  background:
                    "rgba(var(--mui-palette-primary-mainChannel) / 0.1)",
                  color: "primary.main",
                  mb: 2,
                }}
              >
                <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>
              </Box>
              <Typography
                variant="h1"
                sx={{
                  fontSize: "1.5rem",
                  fontWeight: 700,
                  color: "text.primary",
                  mb: 1,
                }}
              >
                Dvoufaktorové ověření
              </Typography>
              <Typography sx={{ color: "text.secondary", fontSize: "0.95rem" }}>
                {useBackupCode
                  ? "Zadejte jeden ze záložních kódů"
                  : "Zadejte 6místný kód z autentizační aplikace"}
              </Typography>
            </Box>

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

              <Button type="submit" disabled={loading} fullWidth>
                {loading ? (
                  <>
                    <CircularProgress
                      size={20}
                      thickness={5}
                      color="inherit"
                      sx={{ mr: 1 }}
                    />
                    Ověřování...
                  </>
                ) : (
                  "Ověřit"
                )}
              </Button>
            </Box>

            <Box
              sx={{
                display: "flex",
                flexDirection: "column",
                gap: 1,
                mt: 1,
              }}
            >
              <Button
                variant="text"
                onClick={() => {
                  setUseBackupCode(!useBackupCode);
                  setTotpCode("");
                }}
                sx={{
                  color: "text.secondary",
                  fontSize: "0.875rem",
                  fontWeight: 400,
                  textTransform: "none",
                  "&:hover": {
                    color: "text.primary",
                    textDecoration: "underline",
                    background: "transparent",
                  },
                }}
              >
                {useBackupCode
                  ? "Použít autentizační aplikaci"
                  : "Použít záložní kód"}
              </Button>
              <Button
                variant="text"
                onClick={handleBack}
                sx={{
                  color: "text.secondary",
                  fontSize: "0.875rem",
                  fontWeight: 400,
                  textTransform: "none",
                  "&:hover": {
                    color: "text.primary",
                    textDecoration: "underline",
                    background: "transparent",
                  },
                }}
              >
                &larr; Zpět na přihlášení
              </Button>
            </Box>
          </Box>
        )}
      </AnimatePresence>
    </Box>
  );
}
