"use client";

import { getOrganization } from "@/actions/organization/get-organization";
import { trackEvent } from "@/app/utils/analytics";
import { NODE_ENV } from "@cap/env";
import { Button, Input, LogoBadge } from "@cap/ui";
import {
  faArrowLeft,
  faEnvelope,
  faExclamationCircle,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { AnimatePresence, motion } from "framer-motion";
import Cookies from "js-cookie";
import { LucideArrowUpRight } from "lucide-react";
import { signIn } from "next-auth/react";
import Image from "next/image";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react";
import { toast } from "sonner";

const MotionInput = motion(Input);
const MotionLogoBadge = motion(LogoBadge);
const MotionLink = motion(Link);
const MotionButton = motion(Button);

export function LoginForm() {
  const searchParams = useSearchParams();
  const next = searchParams?.get("next");
  const [email, setEmail] = useState("");
  const [loading, setLoading] = useState(false);
  const [emailSent, setEmailSent] = useState(false);
  const [oauthError, setOauthError] = useState(false);
  const [showOrgInput, setShowOrgInput] = useState(false);
  const [organizationId, setOrganizationId] = useState("");
  const [organizationName, setOrganizationName] = useState<string | null>(null);
  const theme = Cookies.get("theme") || "light";

  useEffect(() => {
    theme === "dark"
      ? (document.body.className = "dark")
      : (document.body.className = "light");
    //remove the dark mode when we leave the dashboard
    return () => {
      document.body.className = "light";
    };
  }, [theme]);

  useEffect(() => {
    const error = searchParams?.get("error");
    const errorDesc = searchParams?.get("error_description");

    const handleErrors = () => {
      if (error === "OAuthAccountNotLinked" && !errorDesc) {
        setOauthError(true);
        return toast.error(
          "This email is already associated with a different sign-in method"
        );
      } else if (
        error === "profile_not_allowed_outside_organization" &&
        !errorDesc
      ) {
        return toast.error(
          "Your email domain is not authorized for SSO access. Please use your work email or contact your administrator."
        );
      } else if (error && errorDesc) {
        return toast.error(errorDesc);
      }
    };
    handleErrors();
  }, [searchParams]);

  useEffect(() => {
    const pendingPriceId = localStorage.getItem("pendingPriceId");
    const pendingQuantity = localStorage.getItem("pendingQuantity") ?? "1";
    if (emailSent && pendingPriceId) {
      localStorage.removeItem("pendingPriceId");
      localStorage.removeItem("pendingQuantity");

      // Wait a bit to ensure the user is created
      setTimeout(async () => {
        const response = await fetch(`/api/settings/billing/subscribe`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            priceId: pendingPriceId,
            quantity: parseInt(pendingQuantity),
          }),
        });
        const data = await response.json();

        console.log(data);

        if (data.url) {
          window.location.href = data.url;
        }
      }, 2000);
    }
  }, [emailSent]);

  const handleGoogleSignIn = () => {
    trackEvent("auth_started", { method: "google", is_signup: true });
    signIn("google", {
      ...(next && next.length > 0 ? { callbackUrl: next } : {}),
    });
  };

  const handleOrganizationLookup = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!organizationId) {
      toast.error("Please enter an organization ID");
      return;
    }

    try {
      const data = await getOrganization(organizationId);
      setOrganizationName(data.name);

      signIn("workos", undefined, {
        organization: data.organizationId,
        connection: data.connectionId,
      });
    } catch (error) {
      console.error("Lookup Error:", error);
      toast.error("Organization not found or SSO not configured");
    }
  };

  return (
    <motion.div
      layout
      transition={{
        layout: { duration: 0.3, ease: "easeInOut" },
        height: { duration: 0.3, ease: "easeInOut" }
      }}
      className="overflow-hidden relative w-[calc(100%-5%)] p-[28px] max-w-[432px] bg-gray-3 border border-gray-5 rounded-2xl"
    >
      <motion.div
        layout="position"
        key="back-button"
        initial={{ opacity: 0, display: "none" }}
        animate={{
          opacity: showOrgInput ? 1 : 0,
          display: showOrgInput ? "flex" : "none",
          transition: { duration: 0.1, delay: 0.2 },
        }}
        onClick={() => setShowOrgInput(false)}
        className="absolute overflow-hidden top-5 rounded-full left-5 z-20 hover:bg-gray-1 gap-2 items-center py-1.5 px-3 text-gray-12 bg-transparent border border-gray-4 transition-colors duration-300 cursor-pointer"
      >
        <FontAwesomeIcon className="w-2" icon={faArrowLeft} />
        <motion.p layout="position" className="text-xs text-inherit">Back</motion.p>
      </motion.div>
      <MotionLink layout="position" className="flex mx-auto size-fit" href="/">
        <MotionLogoBadge
          layout="position"
          className="w-[72px] h-[72px]"
        />
      </MotionLink>
      <motion.div layout="position" className="flex flex-col justify-center items-center my-7 text-left">
        <motion.h1 key="title" layout="position" className="text-2xl font-semibold text-gray-12">Sign in to Cap</motion.h1>
        <motion.p key="subtitle" layout="position" className="text-[16px] text-gray-10">
          Beautiful screen recordings, owned by you.
        </motion.p>
      </motion.div>
      <motion.div layout="position" className="flex flex-col space-y-3">
        <Suspense
          fallback={
            <>
              <Button disabled={true} variant="primary" />
              <Button disabled={true} variant="destructive" />
              <div className="mx-auto w-3/4 h-5 rounded-lg bg-gray-1" />
            </>
          }
        >
          <motion.div
            layout
            className="flex flex-col space-y-3"
          >
            <AnimatePresence mode="wait" initial={false}>
              <motion.div
                key={showOrgInput ? "sso-wrapper" : "email-wrapper"}
                layout
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.25, ease: "easeInOut", opacity: { delay: 0.05 } }}
                className="px-1"
              >
                {showOrgInput ? (
                  <motion.div
                    key="sso"
                    layout
                    className="min-w-fit"
                    initial={{ opacity: 0, y: 10 }}
                    animate={{ opacity: 1, y: 0, transition: { delay: 0.1 } }}
                    exit={{ opacity: 0, y: -10, transition: { duration: 0.1 } }}
                    transition={{ duration: 0.2, ease: "easeInOut" }}
                  >
                    <LoginWithSSO
                      handleOrganizationLookup={handleOrganizationLookup}
                      organizationId={organizationId}
                      setOrganizationId={setOrganizationId}
                      organizationName={organizationName}
                    />
                  </motion.div>
                ) : (
                  <motion.form
                    key="email"
                    layout
                    initial={{ opacity: 0, y: 10 }}
                    animate={{ opacity: 1, y: 0, transition: { duration: 0.1 } }}
                    exit={{ opacity: 0, y: -10, transition: { duration: 0.15 } }}
                    transition={{ duration: 0.2, ease: "easeInOut", opacity: { delay: 0.05 } }}
                    onSubmit={async (e) => {
                      e.preventDefault();
                      if (!email) return;

                      setLoading(true);
                      trackEvent("auth_started", {
                        method: "email",
                        is_signup: !oauthError,
                      });
                      signIn("email", {
                        email,
                        redirect: false,
                        ...(next && next.length > 0 ? { callbackUrl: next } : {}),
                      })
                        .then((res) => {
                          setLoading(false);
                          if (res?.ok && !res?.error) {
                            setEmailSent(true);
                            trackEvent("auth_email_sent", {
                              email_domain: email.split("@")[1],
                            });
                            toast.success("Email sent - check your inbox!");
                          } else {
                            toast.error("Error sending email - try again?");
                          }
                        })
                        .catch(() => {
                          setEmailSent(false);
                          setLoading(false);
                          toast.error("Error sending email - try again?");
                        });
                    }}
                    className="flex flex-col space-y-3"
                  >
                    <NormalLogin
                      setShowOrgInput={setShowOrgInput}
                      email={email}
                      emailSent={emailSent}
                      setEmail={setEmail}
                      loading={loading}
                      oauthError={oauthError}
                      handleGoogleSignIn={handleGoogleSignIn}
                    />
                  </motion.form>
                )}
              </motion.div>
            </AnimatePresence>
            <motion.p
              layout="position" className="pt-3 text-xs text-center text-gray-9">
              By typing your email and clicking continue, you acknowledge that
              you have both read and agree to Cap's{" "}
              <Link
                href="/terms"
                target="_blank"
                className="text-xs font-semibold text-gray-12 hover:text-blue-300"
              >
                Terms of Service
              </Link>{" "}
              and{" "}
              <Link
                href="/privacy"
                target="_blank"
                className="text-xs font-semibold text-gray-12 hover:text-blue-300"
              >
                Privacy Policy
              </Link>
              .
            </motion.p>
          </motion.div>
          {emailSent && (
            <motion.button
              layout
              className="pt-3 mx-auto text-sm underline text-gray-10 hover:text-gray-8"
              onClick={() => {
                setEmailSent(false);
                setEmail("");
                setLoading(false);
              }}
            >
              Click to restart sign in process
            </motion.button>
          )}
        </Suspense>
      </motion.div>
    </motion.div>
  );
}

const LoginWithSSO = ({
  handleOrganizationLookup,
  organizationId,
  setOrganizationId,
  organizationName,
}: {
  handleOrganizationLookup: (e: React.FormEvent) => void;
  organizationId: string;
  setOrganizationId: (organizationId: string) => void;
  organizationName: string | null;
}) => {
  return (
    <motion.form layout onSubmit={handleOrganizationLookup} className="relative space-y-2">
      <MotionInput
        id="organizationId"
        placeholder="Enter your Organization ID..."
        value={organizationId}
        onChange={(e) => setOrganizationId(e.target.value)}
        className="w-full max-w-full"
      />
      {organizationName && (
        <p className="text-sm text-gray-1">
          Signing in to: {organizationName}
        </p>
      )}
      <div>
        <Button type="submit" variant="dark" className="w-full max-w-full">
          Continue with SSO
        </Button>
      </div>
    </motion.form>
  );
};

const NormalLogin = ({
  setShowOrgInput,
  email,
  emailSent,
  setEmail,
  loading,
  oauthError,
  handleGoogleSignIn,
}: {
  setShowOrgInput: (show: boolean) => void;
  email: string;
  emailSent: boolean;
  setEmail: (email: string) => void;
  loading: boolean;
  oauthError: boolean;
  handleGoogleSignIn: () => void;
}) => {
  return (
    <motion.div>
      <motion.div layout className="flex flex-col space-y-3">
        <MotionInput
          id="email"
          name="email"
          autoFocus
          type="email"
          placeholder={emailSent ? "" : "tim@apple.com"}
          autoComplete="email"
          required
          value={email}
          disabled={emailSent || loading}
          onChange={(e) => {
            setEmail(e.target.value);
          }}
        />
        <MotionButton
          variant="primary"
          type="submit"
          disabled={loading || emailSent}
          icon={<FontAwesomeIcon className="mr-1 size-4" icon={faEnvelope} />}
        >
          {emailSent
            ? NODE_ENV === "development"
              ? "Email sent to your terminal"
              : "Email sent to your inbox"
            : "Login with email"}
        </MotionButton>
        {/* {NODE_ENV === "development" && (
                  <div className="flex justify-center items-center px-6 py-3 mt-3 bg-red-600 rounded-xl">
                    <p className="text-lg text-white">
                      <span className="font-medium text-white">
                        Development mode:
                      </span>{" "}
                      Auth URL will be logged to your dev console.
                    </p>
                  </div>
                )} */}
      </motion.div>
      <div className="flex gap-4 items-center my-4">
        <span className="flex-1 h-px bg-gray-5" />
        <p className="text-sm text-center text-gray-10">OR</p>
        <span className="flex-1 h-px bg-gray-5" />
      </div>
      <motion.div layout className="flex flex-col gap-3 justify-center items-center">
        {!oauthError && (
          <>
            <MotionButton
              variant="gray"
              type="button"
              className="flex gap-2 justify-center items-center w-full text-sm"
              onClick={handleGoogleSignIn}
              disabled={loading}
            >
              <Image src="/google.svg" alt="Google" width={16} height={16} />
              Login with Google
            </MotionButton>
          </>
        )}

        {oauthError && (
          <div className="flex gap-3 items-center p-3 bg-red-400 rounded-xl border border-red-600">
            <FontAwesomeIcon
              className="text-gray-50 size-8"
              icon={faExclamationCircle}
            />
            <p className="text-xs leading-5 text-gray-50">
              It looks like you've previously used this email to sign up via
              email login. Please enter your email below to receive a sign in
              link.
            </p>
          </div>
        )}
        <MotionButton
          variant="gray"
          type="button"
          className="w-full"
          layout
          onClick={() => setShowOrgInput(true)}
          disabled={loading}
        >
          <LucideArrowUpRight size={20} />
          Login with SAML SSO
        </MotionButton>
      </motion.div>
    </motion.div>
  );
};
