import { useRef, useState } from 'react';
import { AuthenticationCard } from '../AuthenticationCard';
import { ArrowLeft, ArrowRight, Edit2, Eye, EyeSlash } from 'iconsax-react';
import {
  Box,
  Button,
  IconButton,
  Stack,
  TextField,
  Typography,
} from '@mui/material';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import type { AuthFactory, AuthType } from '../../types/authTypes';
import type { CountryCode } from '@/types/commonTypes';
import {
  loginWithPassword,
  sendEmailOtp,
  sendSmsOtp,
} from '../../api/authorizationAPI';
import type { LoginResult, PasswordLoginRequest } from '../../types/userTypes';
import { Icon, useToast } from '@rkheftan/harmony-ui';
import { useApi } from '@/hooks/useApi';
import {
  generateTokenWithPassword,
  type GenerateTokenResponse,
} from '../../api/identityAPI';
import { LTRBox } from '@/components/common/LTRBox';

export interface EnterPasswordFormProps {
  onEditValue: () => void;
  onLoginWithOTP: () => void;
  onLoggedIn: (
    loginResult: LoginResult,
    tokenResponse: GenerateTokenResponse,
  ) => void;
  emailOrPhone: string;
  authType: AuthType;
  loginRegisterValue: string;
  countryCode: CountryCode;
  authFactory: AuthFactory;
}

export const EnterPasswordForm = ({
  onEditValue,
  onLoginWithOTP,
  onLoggedIn,
  emailOrPhone,
  authType,
  loginRegisterValue,
  countryCode,
  authFactory,
}: EnterPasswordFormProps) => {
  const { t, i18n } = useTranslation('authentication');
  const [passValue, setPassValue] = useState<string>('');
  const [inputTouched, setInputTouched] = useState<boolean>(false);
  const [showPassword, setShowPassword] = useState<boolean>(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const toast = useToast();
  const { loading: smsResendLoading, execute: smsResendCall } =
    useApi(sendSmsOtp);
  const { loading: emailResendLoading, execute: emailResendCall } =
    useApi(sendEmailOtp);
  const { loading: loginWithPassLoading, execute: loginWithPassCall } =
    useApi(loginWithPassword);

  const handleBlur = () => {
    setInputTouched(true);
  };

  const handleSubmit = async () => {
    if (!passValue) {
      inputRef.current?.focus();
    } else {
      const apiRequest: PasswordLoginRequest = {
        phoneNumber:
          authType === 'phone' ? countryCode + loginRegisterValue : undefined,
        email: authType === 'email' ? loginRegisterValue : undefined,
        password: passValue,
        returnUrl: authFactory.redirectUrl,
      };
      const res = await loginWithPassCall(apiRequest);

      if (!res) return;

      if (res.success) {
        const tokenRes = await generateTokenWithPassword({
          username: apiRequest.email ?? (apiRequest.phoneNumber as string),
          password: apiRequest.password,
          client_id: authFactory.clientId,
        });

        onLoggedIn(res, tokenRes.data);
        toast({
          message: t('verify.youHaveSuccessfullyLoggedIn'),
          severity: 'success',
        });
      } else {
        toast({
          message: res.message,
          severity: 'error',
        });
      }
    }
  };

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

    onLoginWithOTP();
  };

  return (
    <AuthenticationCard>
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'row',
          alignItems: 'center',
          justifyContent: 'space-between',
          gap: 4,
          mb: 0.5,
        }}
      >
        <Typography variant="h5">
          {t('enterPassword.loginWithPassword')}
        </Typography>

        <Button
          variant="outlined"
          size="large"
          sx={{ width: 'auto' }}
          endIcon={<Icon Component={Edit2} />}
          onClick={onEditValue}
        >
          <LTRBox>
            {authType === 'phone' ? countryCode + emailOrPhone : emailOrPhone}
          </LTRBox>
        </Button>
      </Box>
      <Box
        component="form"
        onSubmit={(e) => {
          e.preventDefault();
          e.stopPropagation();
          if (!loginWithPassLoading) {
            void handleSubmit();
          }
        }}
      >
        <Typography variant="body2" color="textSecondary" sx={{ mt: 1, mb: 2 }}>
          {t('enterPassword.enterThePasswordYouSetForYourAccount')}
        </Typography>

        <TextField
          label={t('enterPassword.loginPassword')}
          type={showPassword ? 'text' : 'password'}
          value={passValue}
          inputRef={inputRef}
          onChange={(e) => setPassValue(e.target.value)}
          onBlur={handleBlur}
          error={!passValue && inputTouched}
          helperText={
            !passValue && inputTouched ? t('loginForm.thisFieldIsRequired') : ''
          }
          autoFocus
          slotProps={{
            htmlInput: { sx: { lineHeight: 1.5 } },
            input: {
              endAdornment: (
                <IconButton
                  color="primary"
                  onClick={() => setShowPassword(!showPassword)}
                >
                  {showPassword ? (
                    <Icon Component={Eye} />
                  ) : (
                    <Icon Component={EyeSlash} />
                  )}
                </IconButton>
              ),
            },
          }}
          sx={{ my: 4 }}
        />

        <Button
          onClick={handleLoginWithOtp}
          sx={{ width: 'auto', mb: 2 }}
          variant="text"
          loading={emailResendLoading || smsResendLoading}
          endIcon={
            <Icon Component={i18n.dir() === 'rtl' ? ArrowLeft : ArrowRight} />
          }
        >
          {t('enterPassword.loginWithOneTimeCode')}
        </Button>

        <Stack spacing={1}>
          <Button loading={loginWithPassLoading}>
            {t('verify.confirmAndLogin')}
          </Button>
          <Link to="/forget-password">
            <Button variant="text">
              {t('enterPassword.iForgotMyPassword')}
            </Button>
          </Link>
        </Stack>
      </Box>
    </AuthenticationCard>
  );
};
