import moment from 'moment';

const toMoment = (dateString?: string) => {
  return moment(
    dateString || null,
    [
      'DD.MM.YY',
      'D/MM/YY',
      'DD/MM/YY',
      'DD.MM.YYYY',
      'D/MM/YYYY',
      'DD/MM/YYYY',
      'YYYY-MM-DD',
    ],
    true
  );
}

export const VALIDATION_RULES = {
  required: (val: string): true | string => !!val || 'Обязательное поле',
  strings: (val: string): true | string =>
    !val ||
    !/[!?:;@*_=+|<>[\]{}&^']/.test(`${val}`) ||
    "Поле не должно содержать символы !?:;@*_=+|<>[]{}&^'",

  rusStrings: (val: string): true | string =>
    !val ||
    !/[!?:;@*_=+|<>[\]{}&^'A-Za-z]/.test(`${val}`) ||
    "Поле не должно содержать латиницу и символы !?:;@*_=+|<>[]{}&^'",

  rusStringDashSpace: (val: string): true | string =>
    VALIDATION_CHECKS.rusStringDashSpace(val) ||
    'Поле должно содержать только русские буквы и символы " ", "-"',

  date: (val: string): true | string => {
    if (!val) return true;
    const invalidDateMsg = 'Некорректная дата';
    if (val?.length < 10) return invalidDateMsg;
    const dateVal = toMoment(val);
    const isDateValid = dateVal.isValid();
    return isDateValid || invalidDateMsg;
  },

  words: (val: string): true | string => {
    return (
      /[a-zA-Zа-яА-Я0-9]/.test(`${val}`) || 'Поле должно содержать цифры/буквы"'
    );
  },

  dateRange: ({
    from,
    to,
  }: {
    from?: string;
    to?: string;
  }): ((val: string) => true | string) => {
    return (val: string) => {
      if (!val) return true;
      const dateVal = toMoment(val);
      const isDateValid = dateVal.isValid();
      if (!isDateValid) return 'Некорректная дата';
      const fromDate = toMoment(from);
      const toDate = toMoment(to);
      let isDateInRange = true;

      if (from && isDateValid) {
        isDateInRange = !dateVal.isBefore(fromDate);
      }

      if (to && isDateValid) {
        isDateInRange = isDateInRange && !dateVal.isAfter(toDate);
      }

      if (from && to)
        return (
          isDateInRange ||
          `Дата должна быть не ранее ${fromDate.format(
            'DD.MM.YYYY'
          )}г и не после ${toDate.format('DD.MM.YYYY')}г`
        );

      if (from)
        return (
          isDateInRange ||
          `Дата не должна быть ранее ${fromDate.format('DD.MM.YYYY')}г `
        );

      if (to)
        return (
          isDateInRange ||
          `Дата не должна быть после ${toDate.format('DD.MM.YYYY')}г`
        );

      return isDateValid;
    };
  },

  datestring: (val: string): true | string => {
    return (
      VALIDATION_CHECKS.datestring(val) || 'Дата и время введены некорректно'
    );
  },
};

export const VALIDATION_CHECKS = {
  // функция проверки корректности ввода даты в строке
  datestring: (datestring: string): boolean => {
    const regexCurrentTime = /^([0-1][0-9]|2[0-3]):([0-5][0-9])$/;
    const [date, time] = datestring.split(' ');
    if (!date || !time || !regexCurrentTime.test(time)) return false;

    const momentDate = toMoment(date);

    if (!momentDate.isValid()) return false;

    return moment(`${momentDate.format('YYYY-MM-DD')}T${time}:00Z`).isValid();
  },

  // функция проверки корректности ввода русских символов, '-', ' ' (для имен, фамилий и т.д.)
  // запрет на ввод конструкций " -", "- ", "  ", "--"
  // и соответственно нельзя в начале и в уонце оставлять знаки '-' и ' '
  rusStringDashSpace: (val: string): boolean =>
    !/\s-|-\s|^\s|^-|\s$|-$|-{2,}|\s{2,}/.test(val) &&
    !/[!?:;@*_=#№$%*+|/\\.,()<>[\]{}&^'"A-Za-z0-9]/.test(val),
};
