import { useTranslation } from 'react-i18next';
import { Box, Button, Stack, Typography } from '@mui/material';
import { ArrowLeft, ArrowRight, Edit2 } from 'iconsax-react';
import DigitInput from '@/components/DigitsInput';
import type { AuthFactory, AuthMode, AuthType } from '../../types/authTypes';
import { useEffect, useState } from 'react';
import { AuthenticationCard } from '../AuthenticationCard';
import type { LoginRequest, LoginResult } from '../../types/userTypes';
import {
  loginOrSignUpWithOtp,
  sendEmailOtp,
  sendSmsOtp,
} from '../../api/authorizationAPI';
import type { CountryCode } from '@/types/commonTypes';
import { Icon, useToast } from '@rkheftan/harmony-ui';
import { useApi } from '@/hooks/useApi';
import {
  generateTokenWithOtp,
  type GenerateTokenResponse,
} from '../../api/identityAPI';
import { LTRBox } from '@/components/common/LTRBox';

interface OtpVerifyFormProps {
  value: string;
  countryCode: CountryCode;
  authType: AuthType;
  authMode: AuthMode;
  onEditValue: () => void;
  onOTPVerified: (
    loginResult: LoginResult,
    tokenResponse: GenerateTokenResponse,
  ) => void;
  authFactory: AuthFactory;
  hasPassword: boolean;
  onLoginWithPassword: () => void;
}

export function OtpVerifyForm({
  value,
  countryCode,
  authType,
  authMode,
  onEditValue,
  onOTPVerified,
  authFactory,
  hasPassword,
  onLoginWithPassword,
}: OtpVerifyFormProps) {
  const [otpCode, setOtpCode] = useState<string>('');
  const [otpDigitInvalid, setOtpDigitInvalid] = useState<boolean>(false);
  const [isStatusSuccess, setIsStatusSuccess] = useState<boolean>();
  const { t, i18n } = useTranslation('authentication');
  const [resendTimer, setResendTimer] = useState<number>(120);
  const [canResend, setCanResend] = useState(false);
  const toast = useToast();
  const { loading: smsResendLoading, execute: smsResendCall } =
    useApi(sendSmsOtp);
  const { loading: emailResendLoading, execute: emailResendCall } =
    useApi(sendEmailOtp);
  const { loading: loginSignUpLoading, execute: loginSignUpCall } =
    useApi(loginOrSignUpWithOtp);

  useEffect(() => {
    if (otpCode.length === 4) {
      handleVerifyOTP();
    }
  }, [otpCode]);

  useEffect(() => {
    let interval: NodeJS.Timeout;
    if (resendTimer > 0) {
      interval = setInterval(() => {
        setResendTimer((prev) => prev - 1);
      }, 1000);
    } else {
      setCanResend(true);
    }

    return () => clearInterval(interval);
  }, [resendTimer]);

  const handleResendOTPCode = async () => {
    if (authType === 'phone') {
      await smsResendCall({ phoneNumber: countryCode + value });
    } else {
      await emailResendCall({ email: value });
    }

    setResendTimer(120);
    setCanResend(false);
  };

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

  const handleVerifyOTP = () => {
    if (!otpCode || otpCode.length < 4) {
      setOtpDigitInvalid(true);
    } else {
      handleLoginOrSignUp();
    }
  };

  const handleLoginOrSignUp = async () => {
    setOtpDigitInvalid(false);

    const loginRequest: LoginRequest = {
      otpCode: otpCode,
      phoneNumber: authType === 'phone' ? countryCode + value : undefined,
      email: authType === 'email' ? value : undefined,
      returnUrl: authFactory.redirectUrl,
    };
    const res = await loginSignUpCall(loginRequest);

    if (!res) {
      return;
    }

    if (res.success) {
      setIsStatusSuccess(true);

      const tokenRes = await generateTokenWithOtp({
        email: loginRequest.email,
        phonenumber: loginRequest.phoneNumber,
        otp: loginRequest.otpCode,
        client_id: authFactory.clientId,
      });

      onOTPVerified(res, tokenRes.data);

      toast({
        message:
          authMode === 'login'
            ? t('verify.youHaveSuccessfullyLoggedIn')
            : t('verify.youHaveSuccessfullySignedIn'),
        severity: 'success',
      });
    } else {
      setIsStatusSuccess(false);

      toast({
        message: res.message,
        severity: 'error',
      });
    }
  };

  const otpMessageFn = (): string => {
    if (authType === 'phone' && authMode === 'login') {
      return t(
        'verify.a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt',
      );
    } else if (authType === 'phone' && authMode === 'register') {
      return t(
        'verify.thereIsNoAccountWithThisNumberA4DigitVerificationCodeHasBeenSentToThisNumberToCreateANewAccount',
      );
    } else if (authType === 'email' && authMode === 'login') {
      return t(
        'verify.a4digitVerificationCodeHasBeenSentToYourEmailAddressPleaseEnterIt',
      );
    } else if (authType === 'email' && authMode === 'register') {
      return t(
        'verify.thereIsNoAccountWithThisEmailAddressA4DigitVerificationCodeHasBeenSentToThisEmailAddressToCreateANewAccount',
      );
    }

    return '';
  };

  const otpMessage = otpMessageFn();

  return (
    <Stack alignItems="center">
      <AuthenticationCard>
        <Box
          component="form"
          onSubmit={(e) => {
            e.preventDefault();
            e.stopPropagation();
            if (!loginSignUpLoading) {
              void handleVerifyOTP();
            }
          }}
        >
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'row',
              alignItems: 'center',
              justifyContent: 'space-between',
              mb: 0.5,
            }}
          >
            <Typography variant="h5">{t('verify.verify')}</Typography>

            <Button
              variant="outlined"
              size="large"
              sx={{
                textTransform: 'lowercase',
                width: 'auto',
              }}
              endIcon={<Icon Component={Edit2} />}
              onClick={onEditValue}
            >
              <LTRBox>
                {authType === 'phone' ? countryCode + value : value}
              </LTRBox>
            </Button>
          </Box>

          <Typography variant="body2" color="textSecondary" sx={{ mt: 1 }}>
            {otpMessage}
          </Typography>

          <DigitInput
            error={otpDigitInvalid || isStatusSuccess === false}
            success={isStatusSuccess === true}
            onChange={(value) => setOtpCode(value)}
          />

          {hasPassword && (
            <Button
              onClick={onLoginWithPassword}
              sx={{ width: 'auto', mb: 2 }}
              variant="text"
              endIcon={
                <Icon
                  Component={i18n.dir() === 'rtl' ? ArrowLeft : ArrowRight}
                />
              }
            >
              {t('verify.loginWithPassword')}
            </Button>
          )}

          <Button type="submit" loading={loginSignUpLoading}>
            {authMode === 'register'
              ? t('verify.confirmAndContinue')
              : t('verify.confirmAndLogin')}
          </Button>
        </Box>
      </AuthenticationCard>

      <Stack
        direction="row"
        sx={{
          justifyContent: 'center',
          alignItems: 'center',
          mt: 2.5,
        }}
      >
        <Typography variant="body1">{t('verify.resendCodeIn')}</Typography>

        <Typography
          variant="body1"
          sx={{ color: 'primary.main', marginInlineStart: 1 }}
        >
          {!canResend && `${formatTime(resendTimer)} ${t('verify.moreMinute')}`}
        </Typography>

        {canResend && (
          <Button
            variant="text"
            loading={smsResendLoading || emailResendLoading}
            sx={{ width: 'auto', p: 0 }}
            onClick={canResend ? handleResendOTPCode : undefined}
          >
            {t('verify.resendCode')}
          </Button>
        )}
      </Stack>
    </Stack>
  );
}
