import { Field, useFormikContext } from 'formik';
import React, { useEffect } from 'react';
import { Data } from '../../../../types';
import { Button, ButtonContext } from '../../../Buttons';
import { IconName } from '../../../Icons';
import { BulkEditFieldConfig } from '../BulkEdit.model';
import classes from './FieldWrapper.scss';

interface FieldWrapperProps {
  name: string;
  label: string;
  config: BulkEditFieldConfig;
  component: React.ElementType;
}

export const FieldWrapper: React.FC<FieldWrapperProps> = ({
  name,
  label,
  config,
  component: Component,
}) => {
  const { setFieldValue, values } = useFormikContext<Data>();
  const shouldValidate = React.useRef<boolean>(true);
  const [clearField, setClearField] = React.useState<boolean>(false);

  useEffect(() => {
    if (!Object.keys(values).includes(name) && clearField) {
      setClearField(false);
      shouldValidate.current = true;
    }
  }, [clearField, name, values]);

  const handleClearFieldChange = (): void => {
    const value = !clearField;

    setClearField(value);
    shouldValidate.current = !value;
    if (value && config.clearable) {
      setFieldValue(name, config.clearValue);
    } else if (!value) {
      setFieldValue(name, undefined);
    }
  };

  const handleValidate = (value: unknown): string | void => {
    if (!shouldValidate.current) {
      return;
    }

    if (config.customValidation) {
      try {
        config.customValidation.validateSync(value);
      } catch (error) {
        if (error instanceof Error) {
          return error.message;
        }
        return 'Invalid value';
      }
    }

    if (
      value === null ||
      value === undefined ||
      value === '' ||
      (Array.isArray(value) && value.length === 0)
    ) {
      return 'Please provide a value';
    }
  };

  return (
    <div className={classes.container}>
      <Field
        name={name}
        label={label}
        validate={handleValidate}
        autoFocus={true}
        as={Component}
        disabled={clearField}
      />
      {config.clearable && (
        <Button
          className={classes.button}
          icon={IconName.ClearAll}
          buttonContext={clearField ? ButtonContext.Active : ButtonContext.Icon}
          onButtonClicked={handleClearFieldChange}
          title="Clear"
        />
      )}
    </div>
  );
};
