import React, { useState } from 'react';
import { Input, Button, FormItem, FormContainer, Alert, InputGroup, Select, Tooltip, Card } from '@/components/ui';
import { ActionLink, PasswordInput } from '@/components/shared';
import { apiSendOTP, apiVerifyOTP, apiNewPassword } from '@/services/AuthService'; // Update with appropriate API endpoints
import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage';
import { Field, Form, Formik } from 'formik';
import * as Yup from 'yup';
import { t } from 'i18next';
import { getCountryList } from '@/constants/countries.constant';
import NumberFormat from 'react-number-format';
import { components } from 'react-select';
import PasswordStrengthBar from 'react-password-strength-bar';
import { Link } from 'react-router-dom';
import { HiOutlineQuestionMarkCircle } from 'react-icons/hi';
import LanguageSelector from '@/components/template/LanguageSelector';
import { useTranslation } from 'react-i18next';
import { ResendOtpButton } from '@/nafith/shared';

const { SingleValue } = components;

const NumberInput = (props) => {
  return <Input {...props} value={props.field.value} />;
};

const NumberFormatInput = ({ onValueChange, ...rest }) => {
  return (
    <NumberFormat
      customInput={Input}
      type="text"
      onValueChange={onValueChange}
      autoComplete="off"
      {...rest}
      allowNegative={false}
      decimalScale={0}
    />
  );
};

const PhoneSelectOption = ({ innerProps, data, isSelected }) => {
  return (
    <div
      className={`cursor-pointer flex items-center justify-between p-2 ${
        isSelected ? 'bg-gray-100 dark:bg-gray-500' : 'hover:bg-gray-50 dark:hover:bg-gray-600'
      }`}
      {...innerProps}
    >
      <div className="flex items-center gap-2">
        <span>
          ({data.value}) {data.dialCode}
        </span>
      </div>
    </div>
  );
};

const PhoneControl = ({ children, ...props }) => {
  const selected = props.getValue()[0];
  return <SingleValue {...props}>{selected && <span>{selected.dialCode}</span>}</SingleValue>;
};

const tip = (
  <Tooltip
    title={t(
      'PASSWORD_MUST_CONTAIN_AT_LEAST_ONE_LOWERCASE_LETTER_ONE_UPPERCASE_LETTER_ONE_DIGIT_AND_ONE_SPECIAL_SYMBOL_IN_THE_LIST',
    )}
    placement="top"
  >
    <HiOutlineQuestionMarkCircle className="text-lg cursor-pointer ml-1" />
  </Tooltip>
);
const ForgotPasswordForm = (props) => {
  const { disableSubmit = false, className } = props;
  const countryList = getCountryList(t);
  const [mobileNumberSent, setMobileNumberSent] = useState(false);
  const [verificationCodeSent, setVerificationCodeSent] = useState(false);
  const [newPasswordSet, setNewPasswordSet] = useState(false);
  const [forgetPassword, setForgetPassword] = useState(true);
  const { i18n } = useTranslation();
  const [message, setMessage] = useTimeOutMessage();
  const [resendOTP, setResendOTP] = useState(false);
  const [blockedResendOTP, setBlockedResendOTP] = useState(false);

  const validationSchema = Yup.object().shape({
    mobileNumber: Yup.string()
      .min(8, t('PLEASE_ENTER_VALID_MOBILE_NUMBER'))
      .required(t('PLEASE_ENTER_YOUR_MOBILE_NUMBER')),
    dialCode: Yup.string().required(t('PLEASE_SELECT_DIAL_CODE')),

    verificationCode: Yup.lazy(() => {
      if (mobileNumberSent) {
        return Yup.string()
          .matches(/^[0-9]{6}$/, t('PLEASE_ENTER_VALID_OTP'))
          .required(t('THIS_FIELD_IS_REQUIRED'));
      }
      return Yup.string();
    }),
    newPassword: Yup.lazy(() => {
      if (verificationCodeSent) {
        return Yup.string()
          .min(8, t('PASSWORD_MUST_BE_AT_LEAST_8_CHARACTERS'))
          .max(25, t('PASSWORD_MUST_BE_LESS_THAN_25_CHARACTERS'))
          .matches(
            // eslint-disable-next-line no-useless-escape
            /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_\-+=\[\]{}|;:,.<>?])[A-Za-z\d!@#$%^&*()_\-+=\[\]{}|;:,.<>?]+$/,
            t(
              'PASSWORD_MUST_CONTAIN_AT_LEAST_ONE_LOWERCASE_LETTER_ONE_UPPERCASE_LETTER_ONE_DIGIT_AND_ONE_SPECIAL_SYMBOL_IN_THE_LIST',
            ) + ' (!@#$%^&*()_-+=[]{}|;:,.<>?)',
          );
      }
      return Yup.string();
    }),
    confirmPassword: Yup.lazy(() => {
      if (verificationCodeSent) {
        return Yup.string()
          .oneOf([Yup.ref('newPassword'), null], t('PASSWORDS_MUST_MATCH'))
          .required(t('CONFIRM_PASSWORD_IS_REQUIRED'));
      }
      return Yup.string();
    }),
  });

  const onSendMobileNumber = async (values, setSubmitting, otp = false) => {
    if (otp) {
      setResendOTP(true);
    } else {
      setSubmitting(true);
    }
    try {
      const resp = await apiSendOTP(values);
      if (resp.data) {
        setSubmitting(false);
        setMobileNumberSent(true);
        setForgetPassword(false);
        setResendOTP(false);
      }
    } catch (errors) {
      // NalertToast(t(errors?.response?.data?.errorCodes[0].errorMessages), 'danger');
      setMessage(errors?.response?.data?.errorCodes[0].errorMessages || errors.toString());
      if (errors?.response?.data?.responseCode === '429') {
        setBlockedResendOTP(true);
      }
      setSubmitting(false);
    }
  };

  const onVerifyOTP = async (values, setSubmitting) => {
    setSubmitting(true);
    try {
      const resp = await apiVerifyOTP(values);
      if (resp.data) {
        setSubmitting(false);
        setVerificationCodeSent(true);
        setMobileNumberSent(false);
      }
    } catch (errors) {
      setMessage(errors?.response?.data?.errorCodes[0].errorMessages || errors.toString());
      setSubmitting(false);
    }
  };

  const onResetPassword = async (values, setSubmitting) => {
    setSubmitting(true);
    try {
      const resp = await apiNewPassword(values);
      if (resp.data) {
        setSubmitting(false);
        setNewPasswordSet(true);
        setVerificationCodeSent(false);
      }
    } catch (errors) {
      setMessage(t(errors?.response?.data?.errorCodes[0].errorMessages) || errors.toString());
      setSubmitting(false);
    }
  };

  return (
    <div className={className}>
      <Card className="max-w-[500px] mx-auto lg:min-w-[500px] p-4">
        <div className="mb-6 ">
          {mobileNumberSent ? (
            <>
              <h3 className="mb-1">{t('VERIFICATION_CODE_SENT')}</h3>
              <p>{t('WE_HAVE_SENT_A_VERIFICATION_CODE_TO_YOUR_MOBILE_NUMBER')}</p>
            </>
          ) : verificationCodeSent ? (
            <>
              <h3 className="mb-1">{t('RESET_PASSWORD')}</h3>
              <p>{t('PLEASE_ENTER_NEW_PASSWORD')}</p>
            </>
          ) : newPasswordSet ? (
            <>
              <h3 className="mb-1">{t('PASSWORD_RESET_SUCCESSFULLY')}</h3>
              <p>{t('YOUR_PASSWORD_HAS_BEEN_RESET_SUCCESSFULLY._PLEASE_CLICK_ON_THE_BUTTON_BELOW_TO_SIGN_IN')}</p>
            </>
          ) : forgetPassword ? (
            <>
              <h3 className="mb-1">{t('FORGOT_PASSWORD')}</h3>
              <p>{t('PLEASE_ENTER_YOUR_MOBILE_NUMBER_TO_RESET_YOUR_PASSWORD')}</p>
            </>
          ) : (
            <>
              <h3 className="mb-1">{t('RESET_PASSWORD')}</h3>
              <p>{t('PLEASE_ENTER_THE_VERIFICATION_CODE_AND_NEW_PASSWORD')}</p>
            </>
          )}
        </div>
        <Formik
          initialValues={{
            mobileNumber: '',
            verificationCode: '',
            newPassword: '',
            confirmPassword: '',
            dialCode: '+968',
          }}
          validationSchema={validationSchema}
          onSubmit={(values, { setSubmitting }) => {
            if (mobileNumberSent) {
              onVerifyOTP(values, setSubmitting);
            } else if (verificationCodeSent) {
              onResetPassword(values, setSubmitting);
            } else {
              onSendMobileNumber(values, setSubmitting);
            }
          }}
        >
          {({ touched, errors, isSubmitting, values, setSubmitting }) => (
            <Form>
              <FormContainer>
                {message && (
                  <Alert type="danger" showIcon>
                    {t(message)}
                  </Alert>
                )}
                {forgetPassword && (
                  <>
                    <FormItem
                      label={t('MOBILE_NUMBER')}
                      invalid={(errors.dialCode && touched.dialCode) || (errors.mobileNumber && touched.mobileNumber)}
                      errorMessage={errors.dialCode && touched.dialCode ? errors.dialCode : errors.mobileNumber}
                    >
                      <InputGroup className={i18n.dir() === 'rtl' && 'ltr-direction'}>
                        <Field name="dialCode">
                          {({ field, form }) => (
                            <Select
                              className="min-w-[120px] max-w-[120px]"
                              placeholder={t('DIAL_CODE')}
                              aria-label={t('DIAL_CODE')}
                              components={{
                                Option: PhoneSelectOption,
                                SingleValue: PhoneControl,
                              }}
                              field={field}
                              form={form}
                              options={countryList}
                              value={countryList.filter((country) => country.dialCode === values.dialCode)}
                              onChange={(country) => form.setFieldValue(field.name, country.dialCode)}
                            />
                          )}
                        </Field>
                        <Field name="mobileNumber">
                          {({ field, form }) => {
                            return (
                              <NumberFormatInput
                                form={form}
                                field={field}
                                maxLength={12}
                                customInput={NumberInput}
                                placeholder={t('MOBILE_NUMBER')}
                                onValueChange={(e) => {
                                  form.setFieldValue(field.name, e.value);
                                }}
                              />
                            );
                          }}
                        </Field>
                      </InputGroup>
                    </FormItem>
                    <div className="flex justify-between mb-6">
                      <ActionLink className="mt-2" to={'/sign-in'}>
                        {t('RETURN_TO_SIGN_IN')}
                      </ActionLink>
                      <div className="flex flex-row   h-full text-center  ">
                        <div className="flex-auto"></div>
                        <div className="flex-2  border-white">
                          <LanguageSelector />
                        </div>
                        <div className="flex-auto"></div>
                      </div>
                      {/*<Field className="mb-0" name="rememberMe" component={Checkbox} children={t('Remember Me')} />*/}
                    </div>
                    <Button
                      type="submit"
                      disabled={isSubmitting || disableSubmit}
                      className="w-full"
                      loading={isSubmitting}
                      variant="solid"
                    >
                      {t('SEND_VERIFICATION_CODE')}
                    </Button>
                  </>
                )}
                {mobileNumberSent && (
                  <>
                    <FormItem
                      label={t('VERIFICATION_CODE')}
                      invalid={errors.verificationCode && touched.verificationCode}
                      errorMessage={errors.verificationCode}
                    >
                      <Field name="verificationCode">
                        {({ field, form }) => {
                          return (
                            <NumberFormatInput
                              form={form}
                              maxLength={12}
                              field={field}
                              customInput={Input}
                              format="######"
                              placeholder={t('VERIFICATION_CODE')}
                              onValueChange={(e) => {
                                form.setFieldValue(field.name, e.value);
                              }}
                            />
                          );
                        }}
                      </Field>
                      {/* resend otp */}
                      <ResendOtpButton
                        onResendClick={() => {
                          onSendMobileNumber(values, setSubmitting, true);
                        }}
                        resendOTP={resendOTP} // Pass the resendOTP status here
                        blockedResendOTP={blockedResendOTP}
                        disableSubmit={disableSubmit}
                      />
                    </FormItem>
                    <Button
                      type="submit"
                      disabled={isSubmitting || disableSubmit}
                      className="w-full"
                      loading={isSubmitting}
                      variant="solid"
                    >
                      {t('VERIFY')}
                    </Button>
                  </>
                )}
                {verificationCodeSent && (
                  <>
                    <FormItem
                      label={t('NEW_PASSWORD')}
                      invalid={errors.newPassword && touched.newPassword}
                      errorMessage={errors.newPassword}
                      extra={tip}
                    >
                      <Field name="newPassword" placeholder={t('PASSWORD')} component={PasswordInput} />
                    </FormItem>
                    {/* Add the PasswordStrengthBar component to show password strength */}
                    <PasswordStrengthBar
                      password={values.newPassword}
                      scoreWords={[t('WEAK'), t('FAIR'), t('GOOD'), t('STRONG'), t('STRONGER')]}
                      shortScoreWord={false}
                    />
                    <FormItem
                      label={t('CONFIRM_PASSWORD')}
                      invalid={touched.confirmPassword && errors.confirmPassword}
                      errorMessage={errors.confirmPassword}
                    >
                      <Field
                        name="confirmPassword"
                        placeholder={t('CONFIRM_PASSWORD')}
                        component={PasswordInput}
                        autoComplete="off"
                      />
                    </FormItem>
                    <div className="flex justify-end gap-2">
                      <Button
                        loading={isSubmitting}
                        variant="solid"
                        type="submit"
                        disabled={!values.newPassword || errors.newPassword || errors.confirmPassword}
                        className={
                          values.newPassword && !errors.newPassword && !errors.confirmPassword
                            ? 'bg-blue-500 hover:bg-blue-600'
                            : 'bg-gray-300 cursor-not-allowed'
                        }
                      >
                        {t('RESET_PASSWORD')}
                      </Button>
                    </div>
                  </>
                )}
                {newPasswordSet && (
                  <FormItem>
                    <Link to="/sign-in">
                      <Button type="button" variant="solid" className="w-full">
                        {t('SIGN_IN')}
                      </Button>
                    </Link>
                  </FormItem>
                )}
              </FormContainer>
            </Form>
          )}
        </Formik>
      </Card>
    </div>
  );
};

export default ForgotPasswordForm;
