import { Input, FormItem, FormContainer, Upload, Select, Button, InputGroup } from '@/components/ui';
import { Field, Form, Formik } from 'formik';
import * as Yup from 'yup';
import { useTranslation } from 'react-i18next';
import { getBusinessActivityTypeOptions } from '../constants';
import { ActionLink } from '@/components/shared';
import { HiOutlineChevronLeft, HiOutlineChevronRight } from 'react-icons/hi';
import { getCountryList } from '@/constants/activeCountries.constant';
import { getCityList } from '@/constants/city.constant';
import { components } from 'react-select';
import NumberFormat from 'react-number-format';
import { useRef } from 'react';

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, errors, label } = props;
  const { t } = useTranslation();
  const onSetFormFile = (form, field, file) => {
    if (!file) {
      form.setFieldValue(field.name, '');
      return;
    }
    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;

    if (fileList.length >= maxUpload) {
      return t('YOU_CAN_ONLY_UPLOAD_MAXUPLOAD_FILE(S)', { maxUpload });
    }

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

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

    return valid;
  };

  return (
    <FormItem label={label} className="mb-0">
      <Field name={name}>
        {({ field, form }) => {
          const showError = errors[field.name];
          return (
            <div>
              <Upload
                draggable
                className="cursor-pointer h-[70px]"
                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-[70px]"
                      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 && errors[field.name] && <div className="text-red-500 text-sm">{errors[field.name]}</div>}
            </div>
          );
        }}
      </Field>
    </FormItem>
  );
};

const CompanyRegistrationInfo = ({
  data = {
    //company info
    businessActivityType: '',
    commercialNameArabic: '',
    commercialNameEnglish: '',
    companyRegistrationNo: '',
    companyRegistrationCertificate: '',
    //address info
    countryCode: '',
    address: '',
    governorate: '',
    companyTelephoneNo: '',
    dialCode: '',
  },
  onNextChange,
}) => {
  const { t, i18n } = useTranslation();
  const businessActivityTypeOptions = getBusinessActivityTypeOptions(t);
  const isRTL = i18n.dir() === 'rtl';
  const countryList = getCountryList(t);
  const formRef = useRef();

  const onNext = (values, setSubmitting) => {
    onNextChange?.(values, 'CompanyRegistrationInfo', setSubmitting);
  };

  const validationSchema = Yup.object().shape({
    //company info
    businessActivityType: Yup.string().required(t('THIS_FIELD_IS_REQUIRED')),
    commercialNameArabic: Yup.string()
      .matches(/^[\u0600-\u06FF\s]{1,100}$/, t('ONLY_ARABIC_LETTERS_ARE_ALLOWED_UP_TO_100_CHARACTERS'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    commercialNameEnglish: Yup.string()
      .matches(/^[a-zA-Z\s]{1,100}$/, t('ONLY_ENGLISH_LETTERS_ARE_ALLOWED_UP_TO_100_CHARACTERS'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    companyRegistrationNo: Yup.lazy(() => {
      if (formRef.current?.values?.businessActivityType !== 'OWNER') {
        return Yup.string()
          .matches(/^\d{1,25}$/, t('ONLY_NUMBERS_ARE_ALLOWED_UP_TO_25_DIGITS'))
          .required(t('THIS_FIELD_IS_REQUIRED'));
      } else {
        return Yup.string().nullable();
      }
    }),
    companyRegistrationCertificate: Yup.lazy(() => {
      if (formRef.current?.values?.businessActivityType !== 'OWNER') {
        return Yup.mixed().required(t('THIS_FIELD_IS_REQUIRED'));
      } else {
        return Yup.mixed().nullable();
      }
    }),
    //address info
    countryCode: Yup.string().required(t('THIS_FIELD_IS_REQUIRED')),
    address: Yup.string()
      .matches(/^[\u0621-\u064Aa-zA-Z0-9 ]+$/, t('INVALID_ADDRESS_FORMAT'))
      .max(100, t('ADDRESS_LINE_IS_TOO_LONG'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    governorate: Yup.string()
      .matches(/^[\u0621-\u064Aa-zA-Z _]{1,100}$/, t('LIMIT_NAME_TO_100_LETTERS_AND_LETTERS_ONLY'))
      .required(t('THIS_FIELD_IS_REQUIRED')),
    companyTelephoneNo: Yup.lazy(() => {
      if (formRef.current?.values?.businessActivityType !== 'OWNER') {
        return Yup.string()
          .matches(/^\d{8,12}$/, t('PLEASE_ENTER_VALID_PHONE_NUMBER'))
          .required(t('THIS_FIELD_IS_REQUIRED'));
      } else {
        return Yup.string().nullable();
      }
    }),
    dialCode: Yup.lazy(() => {
      if (formRef.current?.values?.businessActivityType !== 'OWNER') {
        return Yup.string().required(t('THIS_FIELD_IS_REQUIRED'));
      } else {
        return Yup.string().nullable();
      }
    }),
  });
  return (
    <>
      <div className="mb-3">
        <h3 className="mb-2">{t('REGISTRATION_INFO')}</h3>
      </div>
      <Formik
        innerRef={formRef}
        initialValues={data}
        enableReinitialize={true}
        validationSchema={validationSchema}
        onSubmit={(values, { setSubmitting }) => {
          setSubmitting(true);
          setTimeout(() => {
            onNext(values, setSubmitting);
          }, 100);
        }}
      >
        {({ values, touched, errors, isSubmitting }) => {
          const validatedProps = { touched, errors };
          return (
            <Form>
              <FormContainer>
                <FormItem
                  label={t('BUSINESS_ACTIVITY_TYPE') + ' *'}
                  invalid={errors.businessActivityType && touched.businessActivityType}
                  errorMessage={errors.businessActivityType}
                >
                  <Field name="businessActivityType">
                    {({ field, form }) => (
                      <Select
                        placeholder={t('BUSINESS_ACTIVITY_TYPE')}
                        aria-label={t('BUSINESS_ACTIVITY_TYPE')}
                        field={field}
                        form={form}
                        options={businessActivityTypeOptions}
                        value={businessActivityTypeOptions.filter(
                          (activityType) => activityType.value === values.businessActivityType,
                        )}
                        onChange={(activityType) => form.setFieldValue(field.name, activityType.value)}
                      />
                    )}
                  </Field>
                </FormItem>
                <div className="md:grid grid-cols-2 gap-4">
                  <FormItem
                    label={
                      values.businessActivityType === 'OWNER'
                        ? t('FULL_NAME_IN_ARABIC') + ' *'
                        : t('COMMERCIAL_NAME_IN_ARABIC') + ' *'
                    }
                    invalid={errors.commercialNameArabic && touched.commercialNameArabic}
                    errorMessage={errors.commercialNameArabic}
                  >
                    <Field
                      type="text"
                      autoComplete="off"
                      name="commercialNameArabic"
                      placeholder={
                        values.businessActivityType === 'OWNER'
                          ? t('FULL_NAME_IN_ARABIC')
                          : t('COMMERCIAL_NAME_IN_ARABIC')
                      }
                      component={Input}
                    />
                  </FormItem>
                  <FormItem
                    label={
                      values.businessActivityType === 'OWNER'
                        ? t('FULL_NAME_IN_ENGLISH') + ' *'
                        : t('COMMERCIAL_NAME_IN_ENGLISH') + ' *'
                    }
                    invalid={errors.commercialNameEnglish && touched.commercialNameEnglish}
                    errorMessage={errors.commercialNameEnglish}
                  >
                    <Field
                      type="text"
                      autoComplete="off"
                      name="commercialNameEnglish"
                      placeholder={
                        values.businessActivityType === 'OWNER'
                          ? t('FULL_NAME_IN_ENGLISH')
                          : t('COMMERCIAL_NAME_IN_ENGLISH')
                      }
                      component={Input}
                    />
                  </FormItem>
                </div>
                {values.businessActivityType !== 'OWNER' && (
                  <div className="md:grid grid-cols-2 gap-4">
                    <FormItem
                      label={t('COMPANY_REGISTRATION_NO') + ' *'}
                      invalid={errors.companyRegistrationNo && touched.companyRegistrationNo}
                      errorMessage={errors.companyRegistrationNo}
                    >
                      <Field
                        name="companyRegistrationNo"
                        maxLength={25}
                        type="text"
                        autoComplete="off"
                        placeholder={t('COMPANY_REGISTRATION_NO')}
                        component={Input}
                      />
                    </FormItem>
                    <FormItem
                      label={t('COMPANY_PHONE_NUMBER') + ' *'}
                      invalid={
                        (errors.companyTelephoneNo && touched.companyTelephoneNo) ||
                        (errors.dialCode && touched.dialCode)
                      }
                      errorMessage={errors.companyTelephoneNo || errors.dialCode}
                    >
                      <InputGroup className={i18n.dir() === 'rtl' && 'ltr-direction'}>
                        <Field name="dialCode">
                          {({ field, form }) => (
                            <Select
                              className="min-w-[130px]"
                              placeholder={t('COUNTRY_CODE')}
                              aria-label={t('COUNTRY_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="companyTelephoneNo">
                          {({ field, form }) => {
                            return (
                              <NumberFormatInput
                                form={form}
                                maxLength={12}
                                field={field}
                                customInput={NumberInput}
                                placeholder={t('PHONE_NUMBER')}
                                onValueChange={(e) => {
                                  form.setFieldValue(field.name, e.value);
                                }}
                              />
                            );
                          }}
                        </Field>
                      </InputGroup>
                    </FormItem>
                  </div>
                )}

                <div className="md:grid grid-cols-2 gap-4">
                  <div className="md:grid grid-cols-2 gap-4">
                    <FormItem
                      label={t('COUNTRY') + ' *'}
                      invalid={errors.countryCode && touched.countryCode}
                      errorMessage={errors.countryCode}
                    >
                      <Field name="countryCode">
                        {({ field, form }) => (
                          <Select
                            placeholder={t('COUNTRY')}
                            aria-label={t('COUNTRY')}
                            field={field}
                            form={form}
                            options={countryList}
                            value={countryList.filter((country) => country.value === values.countryCode)}
                            onChange={(country) => form.setFieldValue(field.name, country.value)}
                          />
                        )}
                      </Field>
                    </FormItem>
                    <FormItem
                      label={t('GOVERNORATE') + ' *'}
                      invalid={errors.governorate && touched.governorate}
                      errorMessage={errors.governorate}
                    >
                      <Field name="governorate">
                        {({ field, form }) =>
                          getCityList(t, form.values.countryCode).length > 0 ? (
                            <Select
                              placeholder={t('GOVERNORATE')}
                              aria-label={t('GOVERNORATE')}
                              field={field}
                              form={form}
                              options={getCityList(t, form.values.countryCode)}
                              value={getCityList(t, form.values.countryCode).filter((city) => {
                                return city.value === values.governorate;
                              })}
                              onChange={(value) => {
                                return form.setFieldValue(field.name, value.value);
                              }}
                              isDisabled={!form.values.countryCode}
                            />
                          ) : (
                            <Input
                              placeholder={t('GOVERNORATE')}
                              field={field}
                              form={form}
                              isDisabled={!form.values.countryCode}
                            />
                          )
                        }
                      </Field>
                    </FormItem>
                  </div>
                  <FormItem
                    label={t('ADDRESS_LINE') + ' *'}
                    invalid={errors.address && touched.address}
                    errorMessage={errors.address}
                  >
                    <Field
                      type="text"
                      autoComplete="off"
                      name="address"
                      placeholder={t('ADDRESS_LINE')}
                      component={Input}
                    />
                  </FormItem>
                </div>
                {values.businessActivityType !== 'OWNER' && (
                  <DocumentUploadField
                    name="companyRegistrationCertificate"
                    label={t('COMPANY_REGISTRATION_CERTIFICATE') + ' *'}
                    {...validatedProps}
                  />
                )}
                <div className="flex justify-between gap-2">
                  <div className="mt-2 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 />}
                      disabled={true}
                    />
                    <Button
                      loading={isSubmitting}
                      aria-label={t('NEXT')}
                      variant="solid"
                      type="submit"
                      icon={isRTL ? <HiOutlineChevronLeft /> : <HiOutlineChevronRight />}
                    />
                  </div>
                </div>
              </FormContainer>
            </Form>
          );
        }}
      </Formik>
    </>
  );
};

export default CompanyRegistrationInfo;
