import { useRef, useState } from 'react';
import { AuthenticationCard } from '../AuthenticationCard';
import { Edit2, Eye, EyeSlash, TickCircle } from 'iconsax-react';
import {
  Box,
  Button,
  IconButton,
  Stack,
  TextField,
  Typography,
} from '@mui/material';
import { useTranslation } from 'react-i18next';
import { containsNumber } from '@/utils/regexes/containsNumber';
import { containsSymbol } from '@/utils/regexes/containsSymbol';
import { least8Chars } from '@/utils/regexes/least8Chars';
import { hasUpperAndLowerLetter } from '@/utils/regexes/hasUpperAndLowerLetter';
import type { ResetPasswordRequest } from '../../types/userTypes';
import type { AuthType } from '../../types/authTypes';
import type { CountryCode } from '@/types/commonTypes';
import { resetPassword } from '../../api/authorizationAPI';
import { Icon, useToast } from '@rkheftan/harmony-ui';
import { useApi } from '@/hooks/useApi';

export interface ChangePasswordProps {
  onEditInfo: () => void;
  onPasswordChanged: () => void;
  forgetPasswordInfo: string;
  infoType: AuthType;
  countryCode: CountryCode;
}

export const ChangePassword = ({
  onEditInfo,
  onPasswordChanged,
  forgetPasswordInfo,
  infoType,
  countryCode,
}: ChangePasswordProps) => {
  const { t } = useTranslation('authentication');
  const [passValue, setPassValue] = useState<string>('');
  const [confirmPassValue, setConfirmPassValue] = useState<string>('');
  const [inputTouched, setInputTouched] = useState<boolean>(false);
  const [confirmInputTouched, setConfirmInputTouched] =
    useState<boolean>(false);
  const [showPassword, setShowPassword] = useState<boolean>(false);
  const [showConfirmPassword, setShowConfirmPassword] =
    useState<boolean>(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const confirmInputRef = useRef<HTMLInputElement>(null);
  const toast = useToast();
  const { loading: resetPasswordLoading, execute: resetPasswordCall } =
    useApi(resetPassword);

  const passwordValidationRules = [
    { title: t('forgetPassword.includingANumber'), validator: containsNumber },
    { title: t('forgetPassword.atLeast8Characters'), validator: least8Chars },
    {
      title: t('forgetPassword.containsAnUppercaseAndLowercaseLetter'),
      validator: hasUpperAndLowerLetter,
    },
    { title: t('forgetPassword.ContainsASymbol'), validator: containsSymbol },
  ];

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

  const handleConfirmPassBlur = () => {
    setConfirmInputTouched(true);
  };

  const handleSubmit = async () => {
    if (!passValue || !isValidPassword(passValue)) {
      setInputTouched(true);
      inputRef.current?.focus();
    } else if (passValue !== confirmPassValue) {
      setConfirmInputTouched(true);
      confirmInputRef.current?.focus();
    } else {
      const apiRequest: ResetPasswordRequest = {
        email: infoType === 'email' ? forgetPasswordInfo : undefined,
        phoneNumber:
          infoType === 'phone' ? countryCode + forgetPasswordInfo : undefined,
        newPassword: passValue,
        confirmNewPassword: confirmPassValue,
      };

      const res = await resetPasswordCall(apiRequest);

      if (!res) return;

      if (res.success) {
        onPasswordChanged();
        toast({
          message: t('forgetPassword.passwordChangedSuccessfully'),
          severity: 'success',
        });
      } else {
        toast({
          message: res.message,
          severity: 'error',
        });
      }
    }
  };

  const isValidPassword = (value: string) => {
    return (
      containsNumber(value) &&
      containsSymbol(value) &&
      least8Chars(value) &&
      hasUpperAndLowerLetter(value)
    );
  };

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

        <Button
          variant="outlined"
          size="large"
          sx={{ textTransform: 'lowercase', width: 'auto' }}
          endIcon={<Icon Component={Edit2} />}
          onClick={onEditInfo}
        >
          {forgetPasswordInfo}
        </Button>
      </Box>

      <Typography variant="body2" color="textSecondary" sx={{ mt: 1, mb: 2 }}>
        {t('forgetPassword.createANewPassword')}
      </Typography>

      <TextField
        label={t('forgetPassword.newPassword')}
        type={showPassword ? 'text' : 'password'}
        value={passValue}
        inputRef={inputRef}
        onChange={(e) => setPassValue(e.target.value)}
        onBlur={handleBlur}
        error={inputTouched && !isValidPassword(passValue)}
        autoFocus
        slotProps={{
          htmlInput: { sx: { lineHeight: 1.5, paddingInlineStart: 1 } },
          input: {
            startAdornment: confirmPassValue &&
              isValidPassword(passValue) &&
              passValue === confirmPassValue && (
                <Icon
                  Component={TickCircle}
                  variant="Bold"
                  color="success.main"
                />
              ),
            endAdornment: passValue ? (
              <IconButton
                color="primary"
                onClick={() => setShowPassword(!showPassword)}
              >
                {showPassword ? (
                  <Icon Component={Eye} />
                ) : (
                  <Icon Component={EyeSlash} />
                )}
              </IconButton>
            ) : (
              ''
            ),
          },
        }}
        sx={{ mt: 4 }}
      />

      {!isValidPassword(passValue) && (
        <Stack spacing={1} sx={{ mt: 2 }}>
          {passwordValidationRules.map((rule) => (
            <Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
              <Icon
                Component={TickCircle}
                variant={rule.validator(passValue) ? 'Bold' : 'Linear'}
                color={
                  rule.validator(passValue) ? 'success.main' : 'primary.light'
                }
              />

              <Typography variant="body2">{rule.title}</Typography>
            </Stack>
          ))}
        </Stack>
      )}

      <TextField
        label={t('forgetPassword.confirmPassword')}
        type={showConfirmPassword ? 'text' : 'password'}
        value={confirmPassValue}
        inputRef={confirmInputRef}
        onChange={(e) => setConfirmPassValue(e.target.value)}
        onBlur={handleConfirmPassBlur}
        error={confirmInputTouched && confirmPassValue !== passValue}
        slotProps={{
          htmlInput: { sx: { lineHeight: 1.5, paddingInlineStart: 1 } },
          input: {
            startAdornment: confirmPassValue &&
              isValidPassword(passValue) &&
              passValue === confirmPassValue && (
                <Icon
                  Component={TickCircle}
                  variant="Bold"
                  color="success.main"
                />
              ),
            endAdornment: confirmPassValue ? (
              <IconButton
                color="primary"
                onClick={() => setShowConfirmPassword(!showConfirmPassword)}
              >
                {showConfirmPassword ? (
                  <Icon Component={Eye} />
                ) : (
                  <Icon Component={EyeSlash} />
                )}
              </IconButton>
            ) : (
              ''
            ),
          },
        }}
        sx={{ my: 4 }}
      />

      <Stack spacing={1}>
        <Button loading={resetPasswordLoading} onClick={handleSubmit}>
          {t('forgetPassword.confirm')}
        </Button>
      </Stack>
    </AuthenticationCard>
  );
};
