import { AnimatePresence, motion } from "motion/react";
import { useState, useEffect, useRef } from "react";
import { useNavigate, useLocation, Navigate } from "react-router-dom";
import { ChevronDown, ChevronRight, ShieldCheck } from "lucide-react";
import logoImage from "figma:asset/0a77244cc5b7dea0bea10275d45df2915d5170ca.png";
import phoneIconImage from "../../assets/phone-purple-icon.svg";
import { API_BASE_URL } from "../../config/api";
import { isTokenValid } from "../../utils/auth";
import { useProfile } from "../context/ProfileContext";
import { usePageTracking } from "../../hooks/usePageTracking";
import { useInbox } from "../context/InboxContext";
import { backgroundImages } from "../../config/backgroundConfig";

const PERSIAN_NUMBERS = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"] as const;
const ARABIC_NUMBERS = ["٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"] as const;
const CODE_LENGTH = 5;

const loadingDotTransition = {
  duration: 0.6,
  repeat: Infinity,
  repeatType: "mirror" as const,
  ease: "easeInOut" as const,
};

export function LoginPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const { refreshProfile } = useProfile();
  const { refreshInbox } = useInbox();

  usePageTracking("ورود");

  const [phoneNumber, setPhoneNumber] = useState("");
  const [code, setCode] = useState("");
  const [step, setStep] = useState<"phone" | "code">("phone");
  const [isLoading, setIsLoading] = useState(false);
  const [countdown, setCountdown] = useState(0);
  const [error, setError] = useState("");
  const [isNavigatingHome, setIsNavigatingHome] = useState(false);

  const firstInputRef = useRef<HTMLInputElement>(null);
  const phoneInputRef = useRef<HTMLInputElement>(null);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const hasAutoSubmittedRef = useRef(false);

  useEffect(() => {
    if (location.state?.error) {
      setError(location.state.error);
      window.history.replaceState({}, document.title);
    }
  }, [location]);

  useEffect(() => {
    if (step === "code" && firstInputRef.current) {
      const timeout = setTimeout(() => {
        firstInputRef.current?.focus();
      }, 100);

      return () => clearTimeout(timeout);
    }
  }, [step]);

  useEffect(() => {
    if (step === "phone" && phoneInputRef.current) {
      const timeout = setTimeout(() => {
        phoneInputRef.current?.focus();
      }, 100);

      return () => clearTimeout(timeout);
    }
  }, [step]);

  useEffect(() => {
    if (step === "code" && code.length === 5 && !isLoading && !hasAutoSubmittedRef.current) {
      hasAutoSubmittedRef.current = true;
      handleVerifyCode();
    }

    if (code.length < 5) {
      hasAutoSubmittedRef.current = false;
    }
  }, [code, step, isLoading]);

  useEffect(() => {
    return () => {
      if (timerRef.current) {
        clearInterval(timerRef.current);
        timerRef.current = null;
      }
    };
  }, []);

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

  const normalizeNumber = (input: string) => {
    let normalized = input;
    PERSIAN_NUMBERS.forEach((num, index) => {
      normalized = normalized.replace(new RegExp(num, "g"), index.toString());
    });
    ARABIC_NUMBERS.forEach((num, index) => {
      normalized = normalized.replace(new RegExp(num, "g"), index.toString());
    });

    return normalized;
  };

  const toPersianNumber = (input: string) => {
    return input.replace(/\d/g, (digit) => PERSIAN_NUMBERS[parseInt(digit, 10)]);
  };

  const clearTimer = () => {
    if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
  };

  const startCountdown = () => {
    clearTimer();

    setCountdown(120);

    timerRef.current = setInterval(() => {
      setCountdown((prev) => {
        if (prev <= 1) {
          clearTimer();
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
  };

  const requestSmsCode = async (normalizedPhone: string) => {
    const response = await fetch(`${API_BASE_URL}/api/SignUpLoginBySMS`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json;charset=UTF-8",
      },
      body: JSON.stringify(normalizedPhone),
    });

    const result = await response.json();
    return { response, result };
  };

  const handleSendCode = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsLoading(true);
    setError("");

    try {
      const normalizedPhone = normalizeNumber(phoneNumber);
      const { response, result } = await requestSmsCode(normalizedPhone);

      if (response.ok && result.state === 0) {
        setStep("code");
        setCode("");
        hasAutoSubmittedRef.current = false;
        startCountdown();
      } else {
        setError(result.message || "خطا در ارسال کد تایید");
      }
    } catch (err) {
      console.error("Error sending code:", err);
      setError("خطا در برقراری ارتباط با سرور");
    } finally {
      setIsLoading(false);
    }
  };

  const handleVerifyCode = async (e?: React.FormEvent) => {
    e?.preventDefault();
    setIsLoading(true);
    setError("");

    try {
      const normalizedPhone = normalizeNumber(phoneNumber);
      const normalizedCode = normalizeNumber(code);

      const response = await fetch(`${API_BASE_URL}/api/verifyloginbysms`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          mobile: normalizedPhone,
          code: normalizedCode,
        }),
      });

      const result = await response.json();

      if (response.ok && result.state === 0) {
        setIsNavigatingHome(true);
        const data = JSON.parse(result.data);

        localStorage.setItem("accessToken", data.Token.AccessToken);
        localStorage.setItem("refreshToken", data.Token.RefreshToken);
        localStorage.setItem("userId", data.Person.ID.toString());
        localStorage.setItem("username", data.Person.ID.toString());
        localStorage.setItem("userInfo", JSON.stringify(data.Person));

        await refreshProfile();
        await refreshInbox();
        setTimeout(() => {
          sessionStorage.setItem("homeEntranceFromLogin", "1");
          navigate("/", { replace: true });
        }, 1250);
      } else {
        hasAutoSubmittedRef.current = false;
        setError(result.message || "کد تایید اشتباه است");
      }
    } catch (err) {
      console.error("Error verifying code:", err);
      hasAutoSubmittedRef.current = false;
      setError("خطا در برقراری ارتباط با سرور");
    } finally {
      setIsLoading(false);
    }
  };

  const handleResendCode = async () => {
    setIsLoading(true);
    setError("");

    try {
      const normalizedPhone = normalizeNumber(phoneNumber);
      const { response, result } = await requestSmsCode(normalizedPhone);

      if (response.ok && result.state === 0) {
        setCode("");
        hasAutoSubmittedRef.current = false;
        startCountdown();
      } else {
        setError(result.message || "خطا در ارسال مجدد کد");
      }
    } catch (err) {
      console.error("Error resending code:", err);
      setError("خطا در برقراری ارتباط با سرور");
    } finally {
      setIsLoading(false);
    }
  };

  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, "0")}`;
  };

  const handleBackToPhone = () => {
    setStep("phone");
    setCode("");
    setCountdown(0);
    setError("");
    hasAutoSubmittedRef.current = false;

    clearTimer();
  };

  const updateCodeAtIndex = (source: string, index: number, value: string) => {
    const mutableCode = source.split("");
    while (mutableCode.length < CODE_LENGTH) mutableCode.push("");
    mutableCode[index] = value;
    return mutableCode.join("").slice(0, CODE_LENGTH);
  };

  return (
    <div
      className="relative h-[100dvh] overflow-hidden"
      style={{
        backgroundImage: `url(${backgroundImages.login})`,
        backgroundSize: "cover",
        backgroundPosition: "center -90px",
        backgroundRepeat: "no-repeat",
        backgroundColor: "#10053a",
      }}
    >
      <div
        className="absolute inset-0"
        style={{
          background:
            "linear-gradient(180deg, rgba(22, 10, 62, 0.38) 0%, rgba(24, 10, 64, 0.32) 38%, rgba(22, 8, 58, 0.74) 100%)",
        }}
      />

      <AnimatePresence>
        {isNavigatingHome && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.5, ease: "easeInOut" }}
            className="absolute inset-0 z-50 flex items-center justify-center px-8"
            style={{
              background:
                "radial-gradient(circle at 50% 35%, rgba(195, 114, 255, 0.32) 0%, rgba(53, 22, 102, 0.9) 42%, rgba(19, 8, 54, 0.98) 100%)",
              backdropFilter: "blur(8px)",
              WebkitBackdropFilter: "blur(8px)",
            }}
          >
            <motion.div
              initial={{ opacity: 0, y: 14, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              transition={{ duration: 0.62, ease: [0.25, 0.1, 0.25, 1] }}
              className="w-full max-w-[280px] rounded-3xl border border-white/20 bg-white/10 p-5 text-center shadow-[0_12px_32px_rgba(0,0,0,0.35)]"
            >
              <motion.div
                className="mx-auto mb-3 h-10 w-10 rounded-full border-2 border-white/25 border-t-white"
                animate={{ rotate: 360 }}
                transition={{ duration: 0.9, repeat: Infinity, ease: "linear" }}
              />
              <p className="text-base font-semibold text-white">در حال ورود به همدست...</p>
              <motion.div
                className="mx-auto mt-4 h-1.5 w-full overflow-hidden rounded-full bg-white/15"
                initial={false}
              >
                <motion.div
                  className="h-full rounded-full"
                  style={{
                    background:
                      "linear-gradient(90deg, rgba(255,139,91,1) 0%, rgba(238,91,166,1) 45%, rgba(147,78,255,1) 100%)",
                  }}
                  initial={{ x: "-100%" }}
                  animate={{ x: "100%" }}
                  transition={{ duration: 1.4, repeat: Infinity, ease: "easeInOut" }}
                />
              </motion.div>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>

      <div className="relative z-10 mx-auto flex h-full w-full max-w-[430px] flex-col px-6 pb-8 pt-8 sm:px-7" dir="rtl">
        <div className="text-center">
          <img src={logoImage} alt="همدست" className="mx-auto h-16 w-auto object-contain" />
          <p className="mt-1 text-xl font-medium text-white">خوش آمدی قهرمان!</p>
        </div>

        <section className="mt-auto">
          <AnimatePresence mode="wait" initial={false}>
            <motion.div
              key={`login-copy-${step}`}
              initial={{ opacity: 0, y: 8, scale: 0.985, filter: "blur(5px)" }}
              animate={{ opacity: 1, y: 0, scale: 1, filter: "blur(0px)" }}
              exit={{ opacity: 0, y: -8, scale: 1.015, filter: "blur(5px)" }}
              transition={{ duration: 0.42, ease: [0.25, 0.1, 0.25, 1] }}
              className="origin-center"
            >
              <h2 className="text-center text-[24px] font-bold leading-tight text-white">ورود به حساب کاربری</h2>
              <p className="mt-1 text-center text-base text-[#eadfff]">
                {step === "phone" ? "شماره تلفن خود را وارد کنید" : "کد تایید ارسال شده را وارد کنید"}
              </p>
            </motion.div>
          </AnimatePresence>

          <form onSubmit={step === "phone" ? handleSendCode : handleVerifyCode} className="mt-4 space-y-4">
            {error && (
              <div className="rounded-2xl border border-red-400/40 bg-red-500/20 p-3 text-center text-sm text-red-100">{error}</div>
            )}

            <AnimatePresence mode="wait" initial={false}>
              {step === "phone" ? (
                <motion.div
                  key="phone-step"
                  initial={{ opacity: 0, y: 8, filter: "blur(4px)" }}
                  animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
                  exit={{ opacity: 0, y: -8, filter: "blur(4px)" }}
                  transition={{ duration: 0.38, ease: "easeInOut" }}
                >
                  <div
                    className="flex h-14 items-center rounded-full border border-[#d680ff66] px-4"
                    style={{
                      backgroundImage:
                        "linear-gradient(180deg, #2E1B3D 0%, #23183E 100%), linear-gradient(120deg, #7c3aed 0%, #f97316 58%, #facc15 100%)",
                      backgroundOrigin: "border-box",
                      backgroundClip: "padding-box, border-box",
                      boxShadow:
                        "0 -7px 20px rgba(7, 0, 18, 0.5), 0 6px 14px rgba(5, 2, 12, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 2px 5px rgba(255, 222, 255, 0.09), inset 0 -2px 0 rgba(12, 7, 27, 0.72), inset 0 -8px 14px rgba(8, 4, 18, 0.34), inset 0 0 0 1px rgba(255, 255, 255, 0.045), inset 0 0 0 2px rgba(17, 10, 35, 0.32)",
                    }}
                    dir="ltr"
                  >
                    <button type="button" className="flex items-center gap-1 text-lg text-white/90">
                      <span>+۹۸</span>
                      <ChevronDown size={16} />
                    </button>
                    <div className="mx-3 h-7 w-px bg-white/30" />
                    <input
                      id="phone"
                      type="tel"
                      inputMode="numeric"
                      autoFocus={step === "phone"}
                      value={toPersianNumber(phoneNumber)}
                      onChange={(e) => setPhoneNumber(normalizeNumber(e.target.value))}
                      className="w-full bg-transparent text-left text-lg text-white outline-none placeholder:text-lg placeholder:text-white/45"
                      placeholder="۹۱۲ ۱۲۳ ۴۵۶۷"
                      required
                      ref={phoneInputRef}
                    />
                    <img src={phoneIconImage} alt="تلفن" className="ml-2 h-5 w-5 object-contain opacity-100" />
                  </div>
                </motion.div>
              ) : (
                <motion.div
                  key="code-step"
                  initial={{ opacity: 0, y: 8, filter: "blur(4px)" }}
                  animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
                  exit={{ opacity: 0, y: -8, filter: "blur(4px)" }}
                  transition={{ duration: 0.38, ease: "easeInOut" }}
                >
                  <div className="mx-auto mb-2 flex w-[16.5rem] items-center justify-between text-sm text-white/80">
                    <button type="button" onClick={handleBackToPhone} className="flex items-center gap-1 text-[#ffcf7e]">
                      <ChevronRight size={14} />
                      <span>ویرایش شماره تلفن</span>
                    </button>
                    <span>{toPersianNumber(phoneNumber)}</span>
                  </div>
                  <div className="flex justify-center gap-1.5" dir="ltr">
                    {Array.from({ length: CODE_LENGTH }, (_, index) => (
                      <input
                        key={index}
                        type="tel"
                        inputMode="numeric"
                        pattern="[0-9]*"
                        maxLength={1}
                        value={toPersianNumber(code[index] || "")}
                        onChange={(e) => {
                          const value = normalizeNumber(e.target.value);

                          if (value.match(/^[0-9]$/)) {
                            setCode(updateCodeAtIndex(code, index, value));

                            if (index < CODE_LENGTH - 1) {
                              const nextInput = e.target.parentElement?.children[index + 1] as HTMLInputElement;
                              nextInput?.focus();
                            }
                          } else if (e.target.value === "") {
                            setCode(updateCodeAtIndex(code, index, ""));
                          }
                        }}
                        onKeyDown={(e) => {
                          if (e.key === "Backspace") {
                            if (code[index]) {
                              setCode(updateCodeAtIndex(code, index, ""));
                            } else if (index > 0) {
                              setCode(updateCodeAtIndex(code, index - 1, ""));

                              const prevInput = e.currentTarget.parentElement?.children[index - 1] as HTMLInputElement;
                              prevInput?.focus();
                            }
                          }
                        }}
                        className="h-13 w-13 rounded-xl border border-[#d680ff66] bg-[#2f1b59]/85 text-center text-2xl text-white outline-none"
                        ref={index === 0 ? firstInputRef : undefined}
                        autoFocus={step === "code" && index === 0}
                      />
                    ))}
                  </div>
                  <div className="mx-auto w-[16.5rem]">
                    <button
                      type="button"
                      onClick={handleResendCode}
                      className="mt-3 text-sm text-[#f7dcff] disabled:opacity-55"
                      disabled={countdown > 0 || isLoading}
                    >
                      {countdown > 0 ? `ارسال دوباره کد (${formatTime(countdown)})` : "ارسال دوباره کد"}
                    </button>
                  </div>
                </motion.div>
              )}
            </AnimatePresence>

            <motion.button
              whileTap={{ scale: 0.985 }}
              whileHover={{ scale: 1.01 }}
              type="submit"
              disabled={isLoading}
              className="h-14 w-full rounded-full border border-transparent text-lg font-bold text-white"
              style={{
                backgroundImage:
                  "linear-gradient(90deg, rgba(255,139,91,1) 0%, rgba(238,91,166,1) 45%, rgba(147,78,255,1) 100%), linear-gradient(120deg, #7c3aed 0%, #f97316 58%, #facc15 100%)",
                backgroundOrigin: "border-box",
                backgroundClip: "padding-box, border-box",
                boxShadow: "0 10px 26px rgba(196, 87, 255, 0.35), inset 0 1px 0 rgba(255,255,255,0.35)",
              }}
            >
              {isLoading ? (
                <span className="inline-flex items-center gap-1">
                  <span>در حال پردازش</span>
                  <span className="inline-flex items-center" dir="ltr" aria-hidden="true">
                    <motion.span
                      className="inline-block"
                      animate={{ opacity: [0.25, 1], y: [0, -2] }}
                      transition={{ ...loadingDotTransition, delay: 0 }}
                    >
                      .
                    </motion.span>
                    <motion.span
                      className="inline-block"
                      animate={{ opacity: [0.25, 1], y: [0, -2] }}
                      transition={{ ...loadingDotTransition, delay: 0.15 }}
                    >
                      .
                    </motion.span>
                    <motion.span
                      className="inline-block"
                      animate={{ opacity: [0.25, 1], y: [0, -2] }}
                      transition={{ ...loadingDotTransition, delay: 0.3 }}
                    >
                      .
                    </motion.span>
                  </span>
                </span>
              ) : step === "phone" ? (
                "دریافت کد تایید"
              ) : (
                "تایید و ورود"
              )}
            </motion.button>
          </form>

          <div className="mt-8 rounded-2xl border border-[#db8bff44] bg-[#3a1f67]/48 p-4">
            <div className="flex items-center gap-3">
              <ShieldCheck className="h-6 w-6 text-[#f1c0ff]" />
              <p className="text-sm text-white sm:text-base">
                اطلاعات شما با استانداردهای ایمنی نرم‌افزار محافظت می‌شود.
              </p>
            </div>
          </div>
        </section>
      </div>
    </div>
  );
}
