import { useOtpInput } from "react-otp-input-hook";
import { useEffect, useState } from "react";
import { FaCommentSms } from "react-icons/fa6";

import FormHelperText from "@/components/common/form-helper-text";
import Button from "@/components/common/button";
import RenderCountdown from "@/components/common/countdown-render";

type OTPDigitsProps = {
  parsedPhoneNumber?: string;
  sendNewCodeBtnEnabled?: boolean;
  showDefaultIntroText?: boolean;
  label?: string;
  allowSendNewCode?: boolean;
  onChange: (value: string) => void;
  onSendNewCode?: () => void;
};

function OTPDigits({
  parsedPhoneNumber,
  sendNewCodeBtnEnabled,
  showDefaultIntroText,
  label,
  allowSendNewCode = true,
  onChange,
  onSendNewCode,
}: OTPDigitsProps) {
  const { register } = useOtpInput({
    onInputValueChange: onChange,
    focusOnLoad: true,
    blankAllowed: false,
    placeholder: "0",
    type: "numeric",
  });

  const [countdown, setCountdown] = useState(5 * 60); // 5 minutes.
  const [canRequest, setCanRequest] = useState(false);

  const inputStyles =
    "font-inter size-10 sm:w-14 sm:h-14 lg:w-16 lg:h-16 flex flex-col items-center justify-center text-center px-2 outline-none rounded-xl focus:ring-0 focus:shadow-focusInput focus:border-transparent focus:outline-none focus:outline-dotted focus:outline-2 focus:outline-offset-0 focus:outline-light-seafoamGreen disabled:bg-gray-100 border-gray-300 border-2 text-base text-semibold placeholder-gray-300";

  const defaultOptions = { required: true };

  const introText = parsedPhoneNumber
    ? `A verification code was sent to ${parsedPhoneNumber}. Please input the code below.`
    : "Please enter the verification code sent to the mobile number you provided when signing up.";

  const styles = `${
    showDefaultIntroText ? "" : "mt-4"
  } mx-4 xl:mx-0 flex flex-col items-center justify-center p-3 text-black`;

  const numeric = "numeric";

  useEffect(() => {
    let timer: NodeJS.Timeout | undefined;

    if (countdown > 0 && !canRequest && sendNewCodeBtnEnabled) {
      timer = setTimeout(() => setCountdown(countdown - 1), 1000);
    } else if (countdown === 0 || !sendNewCodeBtnEnabled) {
      clearTimeout(timer);
      setCanRequest(true);
      setCountdown(5 * 60);
    }

    return () => clearTimeout(timer);
  }, [countdown, canRequest, sendNewCodeBtnEnabled]);

  const handleSendNewCode = () => {
    setCanRequest(false);
    setCountdown(5 * 60);
    onSendNewCode && onSendNewCode();
  };

  return (
    <div className={styles}>
      {showDefaultIntroText && (
        <h3 className="text-sm font-noto text-center my-8">{introText}</h3>
      )}
      {label && (
        <label
          className="block text-base font-semibold tracking-tight font-noto mb-2"
          htmlFor="verificationCode"
        >
          {label}
        </label>
      )}
      <div className="flex flex-row space-x-2 lg:space-x-6">
        <input
          className={inputStyles}
          inputMode={numeric}
          {...register("digit-1", defaultOptions)}
        />
        <input
          className={inputStyles}
          inputMode={numeric}
          {...register("digit-2", defaultOptions)}
        />
        <input
          className={inputStyles}
          inputMode={numeric}
          {...register("digit-3", defaultOptions)}
        />
        <input
          className={inputStyles}
          inputMode={numeric}
          {...register("digit-4", defaultOptions)}
        />
        <input
          className={inputStyles}
          inputMode={numeric}
          {...register("digit-5", defaultOptions)}
        />
        <input
          className={inputStyles}
          inputMode={numeric}
          {...register("digit-6", defaultOptions)}
        />
      </div>
      <FormHelperText
        helperText="Enter the 6 digits you received via text message. The code might take up a few minutes to arrive."
        styleClasses="mt-6 text-center"
      />
      {allowSendNewCode && (
        <div className="mt-16 text-sm flex flex-col">
          <p className="font-medium font-noto text-center">
            Didn&apos;t receive a verification code?{" "}
          </p>
          <div className="my-2">
            <Button
              btnLabel={
                <div className="flex items-center justify-center space-x-1 flex-col sm:flex-row">
                  <span className="font-noto">Request a new code in</span>
                  <RenderCountdown
                    completed={canRequest}
                    minutes={Math.floor(countdown / 60)}
                    seconds={countdown % 60}
                  />
                </div>
              }
              color="default"
              isDisabled={!sendNewCodeBtnEnabled || !canRequest}
              radius="full"
              startContent={<FaCommentSms className="size-4" />}
              onClick={handleSendNewCode}
            />
          </div>
        </div>
      )}
    </div>
  );
}

export default OTPDigits;
