import { authenticator } from "~/auth.server";
import {
  ActionFunctionArgs,
  json,
  redirect,
  LoaderFunctionArgs,
  MetaFunction,
} from "@remix-run/node";
import { sessionStorage } from "~/sessions.server";
import { useServiceSendOtp, useServiceVerifyOtp } from "~/utils/RequestHandler";
import { useEffect, useState } from "react";
import verifyBanner from "app/assets/icons/login/verify-banner.svg";
import { Button } from "~/components/ui/button";
import { ArrowLeft, Loader2, Phone, RotateCcw } from "lucide-react";
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSlot,
} from "~/components/ui/input-otp";
import AppInput from "~/components/AppInput";
import { useToast } from "~/hooks/use-toast";
import { useSubmit, useLoaderData } from "@remix-run/react";
import { User } from "~/utils/token-manager.server";

export async function loader({ request }: LoaderFunctionArgs) {
  const url = new URL(request.url);
  const redirectTo = url.searchParams.get("redirectTo") || "/";
  return json({ redirectTo });
}

// Helper function to convert Persian numbers to English
const convertPersianToEnglish = (str: string): string => {
  const persianNumbers = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"];
  const englishNumbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];

  let result = str;
  for (let i = 0; i < 10; i++) {
    result = result.replace(
      new RegExp(persianNumbers[i], "g"),
      englishNumbers[i]
    );
  }
  return result;
};

export default function LoginPage() {
  const { redirectTo } = useLoaderData<typeof loader>();
  const { toast } = useToast();
  const [phoneNumber, setPhoneNumber] = useState("");
  const [otpValue, setOtpValue] = useState("");
  const [enableVerifySection, setEnableVerifySection] = useState(false);

  const sendOtpMutation = useServiceSendOtp(
    phoneNumber,
    setEnableVerifySection
  );

  const verifyOtpMutation = useServiceVerifyOtp(phoneNumber, otpValue, toast);

  const submit = useSubmit();
  useEffect(() => {
    if (
      verifyOtpMutation.data &&
      verifyOtpMutation.data.accessToken &&
      verifyOtpMutation.data.refreshToken
    ) {
      console.log("redirectTo", redirectTo);
      submit(
        {
          phoneNumber: phoneNumber,
          access_token: JSON.stringify(verifyOtpMutation.data.accessToken),
          refresh_token: JSON.stringify(verifyOtpMutation.data.refreshToken),
          redirectTo: redirectTo,
        },
        {
          action: "/login",
          method: "post",
          encType: "application/x-www-form-urlencoded",
        }
      );
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [verifyOtpMutation.data]);

  const [canResend, setCanResend] = useState(false);
  useEffect(() => {
    if (enableVerifySection) setCanResend(false);
  }, [enableVerifySection]);

  const handleTimerEnd = () => {
    setCanResend(true);
  };

  return (
    <div className="flex flex-col gap-6 px-[20px] py-12 items-center w-full">
      {enableVerifySection ? (
        <>
          <div className="flex flex-col gap-4 w-full items-center">
            <img alt="" src={verifyBanner} className="w-[85px] h-[70px]" />
            <p className={"text-R18"}>کد تایید شماره موبایل</p>
            <p className="text-BLACK2 text-R12">
              کد ارسال شده به {phoneNumber} را وارد کنید:
            </p>
            <Button
              variant="ghost"
              className="text-BLUE"
              size={"lg"}
              onClick={() => setEnableVerifySection(false)}
            >
              ویرایش شماره موبایل
              <ArrowLeft />
            </Button>
          </div>
          <div className="w-full mt-2 flex justify-center">
            <InputOTP
              maxLength={4}
              onComplete={(finalValue) => {
                const convertedValue = convertPersianToEnglish(finalValue);
                setOtpValue(convertedValue);
              }}
              value={otpValue}
              onChange={(value) => {
                const convertedValue = convertPersianToEnglish(value);
                setOtpValue(convertedValue);
              }}
            >
              <InputOTPGroup dir="ltr" className="gap-4">
                <InputOTPSlot index={0} />
                <InputOTPSlot index={1} />
                <InputOTPSlot index={2} />
                <InputOTPSlot index={3} />
              </InputOTPGroup>
            </InputOTP>
          </div>
          <div className="gap-4 w-full flex flex-col items-center">
            <Button
              disabled={verifyOtpMutation.isPending || !(otpValue.length === 4)}
              className="w-[90%]"
              size={"xl"}
              variant="dark"
              onClick={() => verifyOtpMutation.mutate()}
            >
              {verifyOtpMutation.isPending ? (
                <>
                  <Loader2 className="animate-spin" />
                  درحال تایید...
                </>
              ) : (
                "تایید شماره موبایل"
              )}
            </Button>
            <div>
              {!canResend ? (
                <ResendTimer initialTime={120} onTimerEnd={handleTimerEnd} />
              ) : (
                <Button
                  variant="link"
                  size="lg"
                  className="text-BLUE font-bold p-0 h-auto gap-1"
                  onClick={() => {
                    setCanResend(false);
                    setOtpValue("");
                    sendOtpMutation.mutate();
                    toast({
                      description: "کد مجددا ارسال گردید",
                    });
                  }}
                >
                  <span className="text-B12">ارسال مجدد کد</span>
                  <RotateCcw className="size-5" />
                </Button>
              )}
            </div>
          </div>
        </>
      ) : (
        <>
          <div className="flex flex-col gap-4 w-full items-center">
            <p className="text-R18">به ویترون خوش آمدید!</p>
            <p className="text-GRAY text-R14">
              برای ادامه اطلاعات زیر را وارد کنید
            </p>
          </div>
          <div className="w-full mt-8">
            <AppInput
              inputTitle={"شماره موبایل خود را وارد کنید:"}
              inputIcon={Phone}
              inputValue={phoneNumber}
              inputPlaceholder={"مثل ۰۹۳۹۱۲۳۴۵۶۷"}
              inputOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                const value = e.target.value;
                // Convert Persian numbers to English
                const convertedValue = convertPersianToEnglish(value);
                // Only allow English digits
                if (/^\d*$/.test(convertedValue)) {
                  setPhoneNumber(convertedValue);
                }
              }}
            />
          </div>
          <Button
            disabled={
              sendOtpMutation.isPending ||
              !(phoneNumber.length === 11 && phoneNumber.startsWith("0"))
            }
            size={"xl"}
            variant={"dark"}
            className="w-full"
            onClick={() => {
              sendOtpMutation.mutate();
            }}
          >
            {sendOtpMutation.isPending ? (
              <>
                <Loader2 className="animate-spin" />
                درحال ارسال کد
              </>
            ) : (
              "تایید و ادامه"
            )}
          </Button>
        </>
      )}
    </div>
  );
}

const ResendTimer = ({
  initialTime = 120,
  onTimerEnd,
}: {
  initialTime?: number;
  onTimerEnd?: () => void;
}) => {
  const [timeLeft, setTimeLeft] = useState(initialTime);

  useEffect(() => {
    if (timeLeft <= 0) {
      if (onTimerEnd) onTimerEnd();
      return;
    }

    const timer = setInterval(() => {
      setTimeLeft((prev) => prev - 1);
    }, 1000);

    return () => clearInterval(timer); // پاک کردن تایمر هنگام خروج از کامپوننت
  }, [timeLeft, onTimerEnd]);

  const formatTime = (seconds: number) => {
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${minutes}:${remainingSeconds < 10 ? `0${remainingSeconds}` : remainingSeconds}`;
  };

  return (
    <p className="text-GRAY text-R12">
      {formatTime(timeLeft)} &nbsp;تا ارسال مجدد کد
    </p>
  );
};
export const meta: MetaFunction = () => {
  const title = "ورود و ثبت نام | ویترون";
  const description =
    "ورود یا ثبت نام در ویترون - پلتفرم خرید آنلاین. دسترسی آسان و سریع به حساب کاربری خود برای تجربه خرید بهتر.";
  const imageUrl =
    "https://vitrownstatics.s3.ir-thr-at1.arvanstorage.ir/SVG-06.svg?versionId=";

  return [
    { title },
    { name: "description", content: description },
    { name: "keywords", content: "ورود ویترون، ثبت نام، حساب کاربری، لاگین" },
    { name: "robots", content: "noindex, follow" },

    // Open Graph
    { property: "og:type", content: "website" },
    { property: "og:title", content: title },
    { property: "og:description", content: description },
    { property: "og:image", content: imageUrl },
    { property: "og:site_name", content: "ویترون" },
    { property: "og:locale", content: "fa_IR" },

    // Twitter Card
    { name: "twitter:card", content: "summary" },
    { name: "twitter:title", content: title },
    { name: "twitter:description", content: description },
  ];
};

export async function action({ request }: ActionFunctionArgs) {
  const clonedRequest = request.clone();
  const formData = await clonedRequest.formData();
  const redirectTo = (formData.get("redirectTo") as string) || "/";

  try {
    const user = (await authenticator.authenticate(
      "vitrown-login",
      request
    )) as User;
    if (!user.access_token) {
      return redirect("/login");
    }

    const session = await sessionStorage.getSession(
      request.headers.get("cookie")
    );

    const currentTime = Date.now();

    // Store both tokens with their timestamps
    session.set("user", {
      access_token: user.access_token,
      refresh_token: user.refresh_token,
      access_token_timestamp: currentTime,
      refresh_token_timestamp: currentTime,
    });

    return redirect(redirectTo || "/", {
      headers: {
        "Set-Cookie": await sessionStorage.commitSession(session, {
          expires: new Date(new Date().setMonth(new Date().getMonth() + 1)),
        }),
      },
    });
  } catch (error) {
    console.log("error", error);
    return json({ error: "Authentication failed" }, { status: 401 });
  }
}
