import { FieldInputProps, FormikProps } from 'formik'
import _debounce from 'lodash/debounce'
import _get from 'lodash/get'
import MuiPhoneNumber from 'material-ui-phone-number'
import React, { useCallback, useEffect } from 'react'

import { validatePhoneNumber } from '../../api'

export interface IPhoneNumberField {
  label: string;
  field: FieldInputProps<any>;
  form: FormikProps<any>;
  type: string;
  disableDropdown: boolean;
  fill: boolean;
  setPhoneValidationIsLoading: (isLoading: boolean) => void;

  // optional
  defaultCountry?: string;
  isCountryCodeEditable?: boolean;
}

export const PhoneNumberField = ({
  label,
  field,
  form: {
    errors,
    touched,
    setFieldError,
    values,
    initialValues,
    setFieldValue,
    setFieldTouched,
    setErrors,
    submitCount,
  },
  disableDropdown = true,
  defaultCountry = 'us',
  fill = false,
  setPhoneValidationIsLoading,
  isCountryCodeEditable,
}: IPhoneNumberField) => {
  const error = _get(errors, field.name)
  const isTouched = Boolean(_get(touched, field.name))
  const isSubmitAttempted = Boolean(submitCount && submitCount > 0)

  // eslint-disable-next-line react-hooks/exhaustive-deps
  const debounceCb = useCallback(
    _debounce((cb: () => void) => void cb(), 1000),
    []
  )

  useEffect(() => {
    if (field.value) {
      setPhoneValidationIsLoading(true)
    }

    debounceCb(async () => {
      try {
        if (!values[field.name]) {
          const newErrors = { ...errors }
          delete newErrors[field.name]
          setErrors(newErrors)
          return
        }
        if (values[field.name]) {
          await validatePhoneNumber(values[field.name])
        }
        if (errors[field.name]) {
          const newErrors = { ...errors }
          delete newErrors[field.name]
          setErrors(newErrors)
        }
      } catch (error) {
        const message = _get(
          error,
          'response.data.message',
          'Invalid phone number'
        )
        if (values[field.name] && errors[field.name] !== message) {
          setFieldError(field.name, message)
        }
      } finally {
        setPhoneValidationIsLoading(false)
      }
    })
    // eslint-disable-next-line
  }, [field.value])

  return (
    <>
      <MuiPhoneNumber
        name={field.name}
        value={fill ? values[field.name] : initialValues[field.name]}
        onChange={(value: any, country?: any) => {
          if (`+${country?.dialCode}` === value || value === '+') {
            setFieldValue(field.name, '')
            setFieldError(field.name, '')
          } else {
            setFieldTouched(field.name, true)
            setFieldValue(field.name, value)
          }
        }}
        variant="outlined"
        defaultCountry={defaultCountry}
        disableDropdown={disableDropdown}
        label={label}
        error={!!error && (isTouched || fill || isSubmitAttempted)}
        helperText={(isTouched || fill || isSubmitAttempted) && error}
        fullWidth
        autoFormat={false}
        disableAreaCodes={true}
        countryCodeEditable={isCountryCodeEditable}
      />
    </>
  )
}
