import { logActionRequired } from '../logActionRequired';

type DeprecatedMessageType = {
  component: string;
  propName: string;
  message: string;
  expiryDate?: Date;
};

type ValidatorType = (props: Record<string, any>, propName: string, ...rest: any[]) => Error | null;

type DeprecatedOptionsType = {
  component: string;
  message?: string;
  newProp?: string;
  expiryDate?: Date;
};

const deprecatedMessage = ({ component, propName, message, expiryDate }: DeprecatedMessageType) => {
  const messages = [`${component} has deprecated the use of ${propName}.`];

  if (message) {
    messages.push(message);
  }

  if (expiryDate) {
    messages.push(
      `${propName} will be removed on or after ${expiryDate.toLocaleString('en-GB', {
        year: 'numeric',
        month: 'numeric',
        day: 'numeric',
      })}`,
    );
  }

  return messages.join(' ');
};

const deprecated =
  (
    validator: ValidatorType,
    { component, message = '', newProp: newProperty, expiryDate }: DeprecatedOptionsType,
  ) =>
  (props: Record<string, any>, propertyName: string, ...rest: any[]) => {
    const newPropertyMessage = newProperty ? `Please use ${newProperty} instead.` : message;

    if (props[propertyName] !== null && props[propertyName] !== undefined) {
      logActionRequired(
        deprecatedMessage({
          component,
          propName: propertyName,
          message: newPropertyMessage,
          expiryDate,
        }),
      );
    }
    return validator(props, propertyName, ...rest);
  };

export default deprecated;
