import { useEffect, useState } from 'react';
import { Box, Typography } from '@mui/material';
import { useTranslation } from 'react-i18next';
import Logo from '@/components/Logo';
import { PersonalInfoFields } from '../components/UserCompletionForm/PersonalInfoFields';
import { PasswordSection } from '../components/UserCompletionForm/PasswordSection';
import { EmailSection } from '../components/UserCompletionForm/EmailSection';
import { SubmitSection } from '../components/UserCompletionForm/SubmitSection';
import { useToast } from '@rkheftan/harmony-ui';
import { Gender } from '../types/settingForm';
import { useApi } from '@/hooks/useApi';
import {
  sendEmailOtpApi,
  confirmEmailOtpApi,
  completeUserInformationApi,
} from '../api/userCompletion';
import { containsSymbol } from '@/utils/regexes/containsSymbol';
import { least8Chars } from '@/utils/regexes/least8Chars';
import { containsNumber } from '@/utils/regexes/containsNumber';
import { hasUpperAndLowerLetter } from '@/utils/regexes/hasUpperAndLowerLetter';
import { isEmail } from '@/utils/regexes/isEmail';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { FlexBox } from '@/components/common/FlexBox';
import { AuthenticationCard } from '../components/AuthenticationCard';
import { nationalIdRegex } from '@/utils/regexes/nationalId';

export function UserCompletionPage() {
  const [params] = useSearchParams();
  const { t } = useTranslation('completionForm');
  const showToast = useToast();
  const navigate = useNavigate();

  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [nationalId, setNationalId] = useState('');
  const [birthDate, setBirthDate] = useState<Date | null>(null);
  const [sex, setSex] = useState<Gender | null>(null);
  const [country, setCountry] = useState('');
  const [showPasswordSection, setShowPasswordSection] = useState(false);
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [showEmail, setShowEmail] = useState(false);
  const [email, setEmail] = useState('');
  const [verificationCode, setVerificationCode] = useState('');

  const [codeSent, setCodeSent] = useState(false);
  const [buttonState, setButtonState] = useState<'default' | 'counting'>(
    'default',
  );
  const [countdown, setCountdown] = useState(0);
  const [emailVerified, setEmailVerified] = useState(false);

  const [errors, setErrors] = useState<{ [key: string]: string }>({});
  const [touched, setTouched] = useState<{ [key: string]: boolean }>({});

  const hasNumber = containsNumber(password);
  const hasMinLength = least8Chars(password);
  const hasUpperAndLower = hasUpperAndLowerLetter(password);
  const hasSpecialChar = containsSymbol(password);
  const validPassword =
    hasNumber && hasMinLength && hasUpperAndLower && hasSpecialChar;

  const matchPassword = password === confirmPassword;
  const correctEmail = isEmail(email);

  const { execute: sendCode, loading: isSendingCode } = useApi(sendEmailOtpApi);
  const { execute: verifyCode, loading: isVerifyingCode } =
    useApi(confirmEmailOtpApi);
  const { execute: submitForm, loading: isSubmitting } = useApi(
    completeUserInformationApi,
  );

  useEffect(() => {
    let timer: NodeJS.Timeout;
    if (buttonState === 'counting' && countdown > 0) {
      timer = setInterval(() => {
        setCountdown((prev) => {
          if (prev <= 1) {
            setButtonState('default');
            clearInterval(timer);
            return 0;
          }
          return prev - 1;
        });
      }, 1000);
    }
    return () => clearInterval(timer);
  }, [buttonState, countdown]);

  useEffect(() => {
    if (buttonState === 'default') {
      setCodeSent(false);
      setVerificationCode('');
      // setEmailVerified(false);
      setTouched((prev) => {
        const n = { ...prev };
        delete n.verificationCode;
        return n;
      });
      setErrors((prev) => {
        const n = { ...prev };
        delete n.verificationCode;
        return n;
      });
    }
  }, [buttonState]);

  const handleSendCode = async () => {
    if (!isEmail(email)) {
      setTouched((prev) => ({ ...prev, email: true }));
      setErrors((prev) => ({ ...prev, email: t('validation.emailInvalid') }));
      return;
    }
    setTouched((prev) => {
      const newTouched = { ...prev };
      delete newTouched.verificationCode;
      return newTouched;
    });
    setErrors((prev) => {
      const newErrors = { ...prev };
      delete newErrors.verificationCode;
      return newErrors;
    });
    const res = await sendCode({ email });
    if (res) {
      if (res.success) {
        showToast({
          message: t('completion.successfulCodeSent'),
          severity: 'success',
        });
        setCodeSent(true);
        setButtonState('counting');
        setCountdown(120);
      } else {
        showToast({
          message: res.message || t('completion.problem'),
          severity: 'error',
        });
      }
    }
  };

  const handleVerifyCode = async () => {
    const trimmedCode = verificationCode.trim();
    if (!trimmedCode) {
      setTouched((prev) => ({ ...prev, verificationCode: true }));
      setErrors((prev) => ({
        ...prev,
        verificationCode: t('validation.verificationCodeRequired'),
      }));
      return;
    } else if (trimmedCode.length < 4) {
      setTouched((prev) => ({ ...prev, verificationCode: true }));
      setErrors((prev) => ({
        ...prev,
        verificationCode: t('validation.verificationCodeInvalid'),
      }));
      return;
    }
    const res = await verifyCode({ email, otpCode: verificationCode });
    if (res) {
      if (res.success) {
        setEmailVerified(true);
        showToast({
          message: res.message || t('completion.codeVerified'),
          severity: 'success',
        });
      } else {
        showToast({
          message: res.message || t('completion.invalidCode'),
          severity: 'error',
        });
        setEmailVerified(false);
      }
    }
  };

  const handleSubmit = async () => {
    setTouched({
      firstName: true,
      lastName: true,
      country: true,
      email: showEmail,
      nationalId: true,
      verificationCode: showEmail,
      password: showPasswordSection,
      confirmPassword: showPasswordSection,
      sex: true,
    });
    const isValid = validateForm();
    if (!isValid) {
      return;
    }
    const res = await submitForm({
      firstName,
      lastName,
      gender: sex || 0,
      nationalCode: nationalId,
      savePassword: showPasswordSection,
      password: showPasswordSection ? password : undefined,
      saveEmail: showEmail,
      email: showEmail ? email : undefined,
      birthDate,
      countryCode: country,
    });
    if (res) {
      if (res.success) {
        showToast({
          message: res.message || t('completion.submitSuccess'),
          severity: 'success',
        });
        const returnUrl = params.get('returnUrl');
        navigate(
          returnUrl ? `/account-created?returnUrl=${returnUrl}` : '/setting',
        );
      } else {
        showToast({
          message: res.message || t('completion.submitError'),
          severity: 'error',
        });
      }
    }
  };

  const handleEditEmail = () => {
    setButtonState('default');
    setCodeSent(false);
    setEmailVerified(false);
    setVerificationCode('');
    setTouched((prev) => {
      const newTouched = { ...prev };
      delete newTouched.email;
      delete newTouched.verificationCode;
      return newTouched;
    });
    setErrors((prev) => {
      const newErrors = { ...prev };
      delete newErrors.email;
      delete newErrors.verificationCode;
      return newErrors;
    });
  };

  const validateForm = () => {
    const newErrors: { [key: string]: string } = {};
    if (!firstName.trim())
      newErrors.firstName = t('validation.firstNameRequired');
    if (!lastName.trim()) newErrors.lastName = t('validation.lastNameRequired');
    if (!country) newErrors.country = t('validation.countryRequired');
    if (showEmail && !isEmail(email)) {
      newErrors.email = t('validation.emailInvalid');
    }
    if (nationalId && !nationalIdRegex.test(nationalId)) {
      newErrors.nationalId = t('validation.nationalIdInvalid');
    }
    if (showEmail && codeSent && !emailVerified) {
      const trimmedCode = verificationCode.trim();
      if (!trimmedCode) {
        newErrors.verificationCode = t('validation.verificationCodeRequired');
      } else if (trimmedCode.length < 4) {
        newErrors.verificationCode = t('validation.verificationCodeInvalid');
      } else {
        newErrors.verificationCode = t('validation.mustVerifyCode');
      }
    }
    if (showPasswordSection) {
      if (!password.trim()) {
        newErrors.password = t('validation.passwordRequired');
      } else if (!validPassword) {
        newErrors.password = t('validation.passwordInvalid');
      }
      if (!confirmPassword.trim()) {
        newErrors.confirmPassword = t('validation.confirmPasswordRequired');
      } else if (!matchPassword) {
        newErrors.confirmPassword = t('validation.passwordsDoNotMatch');
      }
    }
    if (sex === null) {
      newErrors.sex = t('validation.genderRequired');
    }
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleBlur = (_field: string) => {};

  useEffect(() => {
    if (!showPasswordSection) {
      setTouched((prev) => {
        const newTouched = { ...prev };
        delete newTouched.password;
        delete newTouched.confirmPassword;
        return newTouched;
      });
      setErrors((prev) => {
        const newErrors = { ...prev };
        delete newErrors.password;
        delete newErrors.confirmPassword;
        return newErrors;
      });
    }
  }, [showPasswordSection]);

  useEffect(() => {
    if (!showEmail) {
      setTouched((prev) => {
        const newTouched = { ...prev };
        delete newTouched.email;
        delete newTouched.verificationCode;
        return newTouched;
      });
      setErrors((prev) => {
        const newErrors = { ...prev };
        delete newErrors.email;
        delete newErrors.verificationCode;
        return newErrors;
      });
    }
  }, [showEmail]);

  useEffect(() => {
    if (Object.keys(touched).length > 0) {
      validateForm();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    firstName,
    lastName,
    country,
    email,
    nationalId,
    verificationCode,
    codeSent,
    emailVerified,
    password,
    confirmPassword,
    showPasswordSection,
    sex,
    touched,
  ]);

  return (
    <FlexBox
      direction="column"
      align="center"
      justify="center"
      sx={{
        minHeight: '100vh',
        gap: 3,
        py: { md: 0, xs: 4 },
      }}
    >
      <Logo />
      <AuthenticationCard
        sx={{
          maxHeight: { sm: '80vh', xs: 'unset' },
          flex: { sm: 'unset', xs: 1 },
          overflowY: 'auto',
          scrollbarGutter: 'stable both-edges',
        }}
        maxWidth="730px"
      >
        <Box
          component="form"
          id="completionForm"
          onSubmit={(e) => {
            e.preventDefault();
            e.stopPropagation();
            void handleSubmit();
          }}
        >
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: 2,
            }}
          >
            <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
              <Typography variant="h5" color="text.primary">
                {t('completion.title')}
              </Typography>
              <Typography variant="body2" color="text.secondary">
                {t('completion.description')}
              </Typography>
            </Box>

            <PersonalInfoFields
              firstName={firstName}
              setFirstName={setFirstName}
              lastName={lastName}
              setLastName={setLastName}
              nationalId={nationalId}
              setNationalId={setNationalId}
              birthDate={birthDate}
              setBirthDate={setBirthDate}
              sex={sex}
              setSex={setSex}
              country={country}
              setCountry={setCountry}
              errors={errors}
              touched={touched}
              handleBlur={handleBlur}
            />

            <PasswordSection
              showPasswordSection={showPasswordSection}
              setShowPasswordSection={setShowPasswordSection}
              password={password}
              setPassword={setPassword}
              confirmPassword={confirmPassword}
              setConfirmPassword={setConfirmPassword}
              matchPassword={matchPassword}
              hasNumber={hasNumber}
              hasMinLength={hasMinLength}
              hasUpperAndLower={hasUpperAndLower}
              hasSpecialChar={hasSpecialChar}
              validPassword={validPassword}
              errors={errors}
              touched={touched}
              handleBlur={handleBlur}
            />

            <EmailSection
              showEmail={showEmail}
              setShowEmail={setShowEmail}
              email={email}
              setEmail={setEmail}
              correctEmail={correctEmail}
              codeSent={codeSent}
              verificationCode={verificationCode}
              setVerificationCode={setVerificationCode}
              buttonState={buttonState}
              countdown={countdown}
              handleSendCode={handleSendCode}
              handleVerifyCode={handleVerifyCode}
              emailVerified={emailVerified}
              isVerifyingCode={isVerifyingCode}
              isSendingCode={isSendingCode}
              handleEditEmail={handleEditEmail}
              errors={errors}
              touched={touched}
              handleBlur={handleBlur}
            />

            <SubmitSection loading={isSubmitting} />
          </Box>
        </Box>
      </AuthenticationCard>
    </FlexBox>
  );
}
