import React, { useState } from 'react';
import { Input, Button, Select, FormItem, FormContainer, InputGroup, Upload } from '@/components/ui';
import { Field, Form, Formik } from 'formik';
import NumberFormat from 'react-number-format';
import { getDocumentTypeOptions } from '../constants';
import { getCountryList } from '@/constants/countries.constant';
import * as Yup from 'yup';
import { components } from 'react-select';
import { ActionLink, DoubleSidedImage } from '@/components/shared';
import useAuth from '@/utils/hooks/useAuth';
import { useSelector, useDispatch } from 'react-redux';
import { setFormData } from '../store/dataSlice';
import store from '../../../../store';
import NalertToast from '@/nafith/alertToast';
import { t } from 'i18next';
import { useTranslation } from 'react-i18next';
import { HiOutlineChevronLeft, HiOutlineChevronRight } from 'react-icons/hi';

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 DocumentUploadField = (props) => {
  const { name, children, label } = props;
  const onSetFormFile = (form, field, file) => {
    form.setFieldValue(field.name, file[0]);
  };
  const beforeUpload = (file, fileList) => {
    let valid = true;
    const maxUpload = 2;
    const allowedFileType = [
      'application/pdf',
      'application/msword',
      'image/jpeg',
      'image/png',
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    ];
    const maxFileSize = 3000000; // 3MB

    if (fileList.length >= maxUpload) {
      return t('UPLOAD_FILE_MUST_BE_LESS_THAN_2_FILES');
    }

    for (let f of file) {
      if (!allowedFileType.includes(f.type)) {
        valid = t('UPLOAD_FILE_MUST_BE_PDF_DOC_JPEG_OR_PNG');
      }

      if (f.size >= maxFileSize) {
        valid = t('UPLOAD_FILE_MUST_BE_LESS_THAN_3MB');
      }
    }

    return valid;
  };
  return (
    <FormItem label={label}>
      <Field name={name}>
        {({ field, form }) => {
          const { errors } = form;
          const showError = errors[field.name];
          return (
            <div>
              <Upload
                draggable
                className="cursor-pointer h-[180px]"
                onChange={(files) => onSetFormFile(form, field, files)}
                onFileRemove={(files) => onSetFormFile(form, field, files)}
                showList={true}
                uploadLimit={1}
                beforeUpload={beforeUpload}
              >
                {field.value ? (
                  <div className="flex flex-col items-center justify-center h-full">
                    <img
                      className="p-3 max-h-[100px]"
                      src={'/img/thumbs/file.png'}
                      alt="Company Registration Certificate"
                    />
                    <p className="font-semibold">
                      <span className="text-gray-800 dark:text-white">{field.value.name}</span>
                    </p>
                  </div>
                ) : (
                  <div className="text-center">
                    {children}
                    <p className="font-semibold">
                      <span className="text-gray-800 dark:text-white">{t('DROP_YOUR_FILE_HERE_OR')} </span>
                      <span className="text-blue-500">{t('BROWSE')}</span>
                    </p>
                    <p className="mt-1 opacity-60 dark:text-white">{t('SUPPORT')}: .pdf, .doc, .jpeg, .png</p>
                  </div>
                )}
              </Upload>
              {showError && <div className="text-red-500 text-sm">{errors[field.name]}</div>}
            </div>
          );
        }}
      </Field>
    </FormItem>
  );
};

const UserInformation = ({
  data = {
    idDocumentType: '',
    idDocumentNo: '',
    fullName: '',
    authorizedManagerNationality: '',
    email: '',
    authorizedManagerMobileNo: '',
    dialCode: '',
    frontsideIDCard: '',
    backsideIDCard: '',
  },
  onNextChange,
  onBackChange,
}) => {
  const documentTypeOptions = getDocumentTypeOptions(t);
  const countryList = getCountryList(t);
  const { i18n } = useTranslation();
  const isRTL = i18n.dir() === 'rtl';
  const validationSchema = Yup.object().shape({
    idDocumentType: Yup.string().required(t('THIS_FIELD_IS_REQUIRED')),
    idDocumentNo: Yup.string()
      .matches(/^\d{1,25}$/, t('ONLY_NUMBERS_ARE_ALLOWED_UP_TO_25_DIGITS'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    fullName: Yup.string()
      .matches(/^[\u0621-\u064Aa-zA-Z ]+$/, t('Full name can only contain Arabic or English letters'))
      .max(50, t('FULL_NAME_MUST_BE_AT_MOST_50_CHARACTERS_LONG'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    authorizedManagerNationality: Yup.string().required(t('THIS_FIELD_IS_REQUIRED')),
    email: Yup.string()
      .email(t('INVALID_EMAIL'))
      .max(40, t('EMAIL_MUST_BE_AT_MOST_40_CHARACTERS_LONG'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    dialCode: Yup.string().required(t('THIS_FIELD_IS_REQUIRED')),
    authorizedManagerMobileNo: Yup.string()
      .min(8, t('PLEASE_ENTER_VALID_MOBILE_NUMBER'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    frontsideIDCard: Yup.mixed().required(t('THIS_FIELD_IS_REQUIRED')),
    backsideIDCard: Yup.mixed().required(t('THIS_FIELD_IS_REQUIRED')),
  });
  const onNext = (values, setSubmitting) => {
    onNextChange?.(values, 'UserInformation', setSubmitting);
  };

  const onBack = () => {
    onBackChange?.();
  };

  //const [setMessage] = useTimeOutMessage();
  const { signUp } = useAuth();
  const formData = useSelector((state) => state.accountDetailForm.data.formData);
  const locale = useSelector((state) => state.locale.currentLang);
  const dispatch = useDispatch();
  const [disabledButton, setDisabledButton] = useState(false);
  const [submitButton, setSubmitButton] = useState(false);

  const onSignUp = async (data, setSubmitting) => {
    setSubmitButton(true);
    dispatch(setFormData({ ...formData, UserInformation: data }));
    const newFormData = store.getState().accountDetailForm.data.formData;
    const result = await signUp(newFormData, locale);

    if (result.status === 'failed') {
      setDisabledButton(true);
      NalertToast(result.message, 'danger');
      setSubmitButton(false);
      setTimeout(() => {
        setDisabledButton(false);
      }, 3000);
    } else {
      onNext(data, setSubmitting);
    }

    // setSubmitting(false);
    return result.status;
  };

  return (
    <>
      <div className="mb-8">
        <h3 className="mb-2">{t('USER_INFORMATION')}</h3>
      </div>
      <Formik
        initialValues={data}
        enableReinitialize
        validationSchema={validationSchema}
        onSubmit={(values, { setSubmitting }) => {
          setSubmitting(true);
          onSignUp(values, setSubmitting);
          // onNext(values, setSubmitting);
        }}
      >
        {({ values, touched, errors, isSubmitting }) => {
          const validatedProps = { touched, errors };
          return (
            <Form>
              <FormContainer>
                <div className="md:grid grid-cols-2 gap-4">
                  <FormItem
                    label={t('FULL_NAME') + ' *'}
                    invalid={errors.fullName && touched.fullName}
                    errorMessage={errors.fullName}
                  >
                    <Field
                      type="text"
                      autoComplete="off"
                      name="fullName"
                      placeholder={t('FULL_NAME')}
                      component={Input}
                    />
                  </FormItem>
                  <FormItem
                    label={t('USER_NATIONALITY') + ' *'}
                    invalid={errors.authorizedManagerNationality && touched.authorizedManagerNationality}
                    errorMessage={errors.authorizedManagerNationality}
                  >
                    <Field name="authorizedManagerNationality">
                      {({ field, form }) => (
                        <Select
                          placeholder={t('USER_NATIONALITY')}
                          aria-label={t('USER_NATIONALITY')}
                          field={field}
                          form={form}
                          options={countryList}
                          value={countryList.filter((country) => country.value === values.authorizedManagerNationality)}
                          onChange={(country) => form.setFieldValue(field.name, country.value)}
                        />
                      )}
                    </Field>
                  </FormItem>
                </div>
                <div className="md:grid grid-cols-2 gap-4">
                  <FormItem
                    label={t('ID_DOCUMENT_TYPE') + ' *'}
                    invalid={errors.idDocumentType && touched.idDocumentType}
                    errorMessage={errors.idDocumentType}
                  >
                    <Field name="idDocumentType">
                      {({ field, form }) => (
                        <Select
                          placeholder={t('ID_DOCUMENT_TYPE')}
                          aria-label={t('ID_DOCUMENT_TYPE')}
                          field={field}
                          form={form}
                          options={documentTypeOptions}
                          value={documentTypeOptions.filter((status) => status.value === values.idDocumentType)}
                          onChange={(status) => form.setFieldValue(field.name, status.value)}
                        />
                      )}
                    </Field>
                  </FormItem>
                  <FormItem
                    label={t('ID_DOCUMENT_NO') + ' *'}
                    invalid={errors.idDocumentNo && touched.idDocumentNo}
                    errorMessage={errors.idDocumentNo}
                  >
                    <Field
                      name="idDocumentNo"
                      maxLength={25}
                      type="text"
                      autoComplete="off"
                      placeholder={t('ID_DOCUMENT_NO')}
                      component={Input}
                    />
                  </FormItem>
                </div>

                <div className="md:grid grid-cols-2 gap-4">
                  <FormItem
                    label={t('MOBILE_NUMBER') + ' *'}
                    invalid={
                      (errors.dialCode && touched.dialCode) ||
                      (errors.authorizedManagerMobileNo && touched.authorizedManagerMobileNo)
                    }
                    errorMessage={
                      errors.dialCode && touched.dialCode ? errors.dialCode : errors.authorizedManagerMobileNo
                    }
                  >
                    <InputGroup className={i18n.dir() === 'rtl' && 'ltr-direction'}>
                      <Field name="dialCode">
                        {({ field, form }) => (
                          <Select
                            className="min-w-[130px]"
                            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="authorizedManagerMobileNo">
                        {({ 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>
                  <FormItem
                    label={t('EMAIL') + ' *'}
                    invalid={errors.email && touched.email}
                    errorMessage={errors.email}
                  >
                    <Field type="email" autoComplete="off" name="email" placeholder={t('EMAIL')} component={Input} />
                  </FormItem>
                </div>
                <div className="md:grid grid-cols-2 gap-4">
                  <DocumentUploadField
                    name="frontsideIDCard"
                    label={t('FRONTSIDE_OF_AUTHORIZED_MANAGER_ID_CARD') + ' *'}
                    {...validatedProps}
                  >
                    <DoubleSidedImage
                      className="mx-auto mb-3"
                      src="/img/thumbs/id-card-front.png"
                      darkModeSrc="/img/thumbs/id-card-front-dark.png"
                      alt="SidedImage"
                    />
                  </DocumentUploadField>
                  <DocumentUploadField
                    name="backsideIDCard"
                    label={t('BACKSIDE_OF_AUTHORIZED_MANAGER_ID_CARD') + ' *'}
                    {...validatedProps}
                  >
                    <DoubleSidedImage
                      className="mx-auto mb-3"
                      src="/img/thumbs/id-card-back.png"
                      darkModeSrc="/img/thumbs/id-card-back-dark.png"
                      alt="SidedImage"
                    />
                  </DocumentUploadField>
                </div>

                <div className="flex justify-between gap-2">
                  <div className="mt-4 text-end">
                    <span>{t('DO_YOU_HAVE_AN_ACCOUNT')} </span>
                    <ActionLink to="/sign-in">{t('SIGN_IN')}</ActionLink>
                  </div>
                  <div className="flex gap-2">
                    <Button
                      type="button"
                      aria-label={t('BACK')}
                      icon={isRTL ? <HiOutlineChevronRight /> : <HiOutlineChevronLeft />}
                      onClick={onBack}
                    />
                    <Button
                      loading={submitButton}
                      variant="solid"
                      type="submit"
                      color="green-600"
                      disabled={disabledButton}
                    >
                      {t('REGISTER')}
                    </Button>
                  </div>
                </div>
              </FormContainer>
            </Form>
          );
        }}
      </Formik>
    </>
  );
};

export default UserInformation;
