"use client";

import { AnimatePresence, motion } from "framer-motion";
import { Eye, EyeOff, Lock, User, X } from "lucide-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import React, { useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { useForm } from "react-hook-form";
import { toast } from "react-hot-toast";

import { useSigninMutation } from "@/api/auth.api";
import { ISigninRequest } from "@/api/types/auth";
import { parseApiError } from "@/api/utils/error-handler";
import { setAuthTokens } from "@/lib/auth-cookies";
import { useAppDispatch } from "@/redux/hooks";
import { setCredentials } from "@/redux/slices/authSlice";

interface LoginModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess?: () => void;
}

const LoginModal: React.FC<LoginModalProps> = ({
  isOpen,
  onClose,
  onSuccess,
}) => {
  const [showPassword, setShowPassword] = useState(false);
  const dispatch = useAppDispatch();
  const [signin, { isLoading }] = useSigninMutation();
  // Where to return after registering — the page the modal was opened from.
  const pathname = usePathname();
  const signupHref = `/signup?redirect=${encodeURIComponent(pathname)}`;

  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm<ISigninRequest & { rememberMe?: boolean }>({
    defaultValues: { email: "", password: "" },
  });

  useEffect(() => {
    if (!isOpen) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };

    const originalOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    document.addEventListener("keydown", handleKeyDown);

    return () => {
      document.body.style.overflow = originalOverflow;
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [isOpen, onClose]);

  const onSubmit = async ({
    rememberMe,
    ...signinData
  }: ISigninRequest & { rememberMe?: boolean }) => {
    try {
      const response = await signin(signinData).unwrap();
      if (response?.id) {
        setAuthTokens(
          response.token,
          response.refreshToken,
          rememberMe ?? false,
        );
        dispatch(
          setCredentials({
            user: {
              id: response.id.toString(),
              email: response.email,
              name: response.userProfile.name,
              profileImage: response.userProfile.profileImage?.filePath || null,
              rankName: response.userProfile.rank.name,
              isPremium: response.userSetting.isPremium,
              billingRegion: response.userSetting.billingRegion ?? null,
            },
          }),
        );
        toast.success("Login successful!");
        reset();
        onClose();
        onSuccess?.();
        window.location.reload();
      }
    } catch (error: unknown) {
      toast.error(parseApiError(error));
    }
  };

  if (typeof document === "undefined") return null;

  return createPortal(
    <AnimatePresence>
      {isOpen && (
        <motion.div
          role="dialog"
          aria-modal="true"
          aria-labelledby="login-modal-title"
          onClick={onClose}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
          className="fixed inset-0 z-[100] flex items-center justify-center bg-black/50 px-4 backdrop-blur-sm"
        >
          <motion.div
            onClick={(e) => e.stopPropagation()}
            initial={{ opacity: 0, scale: 0.95 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.95 }}
            transition={{ duration: 0.2 }}
            className="relative w-full max-w-[420px] bg-white rounded-[19px] shadow-xl"
          >
            {/* Close button */}
            <button
              onClick={onClose}
              aria-label="Close"
              className="absolute top-[11px] right-[12px] w-[29px] h-[29px] bg-white rounded-full border border-[#DBDBDB] flex items-center justify-center hover:bg-neutral-50 transition-colors cursor-pointer z-10"
            >
              <X size={16} className="text-[#737373]" strokeWidth={1.5} />
            </button>

            {/* Content */}
            <div className="flex flex-col gap-5 px-6 pt-8 pb-7">
              {/* Title */}
              <h2
                id="login-modal-title"
                className="font-sans text-[22px] font-bold leading-[1.3] tracking-[-0.02em] text-black"
              >
                Login to Your Account
              </h2>

              {/* Form */}
              <form
                onSubmit={handleSubmit(onSubmit)}
                className="flex flex-col gap-4"
              >
                {/* Email field */}
                <div className="flex flex-col gap-1">
                  <div
                    className={`flex items-center gap-3 px-4 py-3 bg-[#EEF3FA] rounded-[10px] border transition-colors ${
                      errors.email
                        ? "border-red-400"
                        : "border-transparent focus-within:border-[#08A1EE]"
                    }`}
                  >
                    <User
                      size={18}
                      className="text-[#8FA4BE] shrink-0"
                      strokeWidth={1.8}
                    />
                    <input
                      type="email"
                      placeholder="Email"
                      autoComplete="email"
                      className="flex-1 bg-transparent outline-none font-sans text-[15px] font-medium text-[#1A2B3C] placeholder:text-[#8FA4BE]"
                      {...register("email", {
                        required: "Email is required",
                        pattern: {
                          value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
                          message: "Invalid email format",
                        },
                      })}
                    />
                  </div>
                  {errors.email && (
                    <p className="text-red-500 text-xs pl-1 font-sans">
                      {errors.email.message}
                    </p>
                  )}
                </div>

                {/* Password field */}
                <div className="flex flex-col gap-1">
                  <div
                    className={`flex items-center gap-3 px-4 py-3 bg-[#EEF3FA] rounded-[10px] border transition-colors ${
                      errors.password
                        ? "border-red-400"
                        : "border-transparent focus-within:border-[#08A1EE]"
                    }`}
                  >
                    <Lock
                      size={18}
                      className="text-[#8FA4BE] shrink-0"
                      strokeWidth={1.8}
                    />
                    <input
                      type={showPassword ? "text" : "password"}
                      placeholder="Password"
                      autoComplete="current-password"
                      className="flex-1 min-w-0 bg-transparent outline-none font-sans text-[15px] font-medium text-[#1A2B3C] placeholder:text-[#8FA4BE]"
                      {...register("password", {
                        required: "Password is required",
                      })}
                    />
                    <button
                      type="button"
                      onClick={() => setShowPassword((p) => !p)}
                      className="shrink-0 text-[#8FA4BE] hover:text-[#1A2B3C] transition-colors cursor-pointer"
                      aria-label={
                        showPassword ? "Hide password" : "Show password"
                      }
                    >
                      {showPassword ? (
                        <EyeOff size={18} strokeWidth={1.8} />
                      ) : (
                        <Eye size={18} strokeWidth={1.8} />
                      )}
                    </button>
                  </div>
                  {errors.password && (
                    <p className="text-red-500 text-xs pl-1 font-sans">
                      {errors.password.message}
                    </p>
                  )}
                </div>

                {/* Remember me + Forgot password */}
                <div className="flex items-center justify-between">
                  <label className="flex items-center gap-2 cursor-pointer select-none">
                    <input
                      type="checkbox"
                      className="w-4 h-4 rounded border-[#DBDBDB] accent-[#08A1EE] cursor-pointer"
                      {...register("rememberMe")}
                    />
                    <span className="font-sans text-[13px] font-medium text-[#484848]">
                      Remember Me
                    </span>
                  </label>
                  <Link
                    href="/forgot-password"
                    onClick={onClose}
                    className="font-sans text-[13px] font-semibold text-[#08A1EE] hover:underline"
                  >
                    Lost your password?
                  </Link>
                </div>

                {/* Submit */}
                <button
                  type="submit"
                  disabled={isLoading}
                  className="w-full h-[46px] bg-[#08A1EE] rounded-[34px] font-sans text-[16px] font-bold text-white hover:bg-[#0791d4] transition-colors cursor-pointer disabled:opacity-60 disabled:cursor-not-allowed mt-1 shadow-[0px_1px_2px_0px_rgba(0,0,0,0.08)]"
                >
                  {isLoading ? "Logging in..." : "Log In"}
                </button>
              </form>

              {/* Register link */}
              <p className="text-center font-sans text-[14px] font-medium text-[#484848]">
                Don&apos;t have an account?{" "}
                <Link
                  href={signupHref}
                  onClick={onClose}
                  className="text-[#08A1EE] font-semibold hover:underline"
                >
                  Register
                </Link>
              </p>
            </div>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>,
    document.body,
  );
};

export default LoginModal;
