/* eslint-disable no-useless-escape */
import dayjs from 'dayjs';
import durationPlugin from 'dayjs/plugin/duration';

import { DAY, MONTH, WEEK } from '../constants';

dayjs.extend(durationPlugin);

const validateUrl = (url) => /^(https:\/\/)[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/.test(url);

const validateField = ({ fieldName, fieldValue }, setErrorAction, optional) => {
  if (!fieldValue) {
    return setErrorAction({
      [fieldName]: {
        isValid: false,
        message: 'This field cannot be empty',
      },
    });
  }

  if (fieldName === 'url' && !validateUrl(fieldValue)) {
    return setErrorAction({
      [fieldName]: {
        isValid: false,
        message: "Field must be in the format of 'https://' URL'",
      },
    });
  }

  if (fieldName === 'recurrentPeriod') {
    if (fieldValue === DAY && optional?.duration > 1) {
      return setErrorAction({
        [fieldName]: {
          isValid: false,
          message: "A daily event can't be longer than a day",
        },
      });
    }

    if (fieldValue === WEEK && optional?.duration > 7) {
      return setErrorAction({
        [fieldName]: {
          isValid: false,
          message: "A weekly event can't be longer than a week",
        },
      });
    }
  }

  if (fieldName === 'recurrentEndDate') {
    if (optional?.recurrentPeriod === DAY && optional.timeDifference < 1) {
      return setErrorAction({
        [fieldName]: {
          isValid: false,
          message: 'The end date must be a day after the last event date',
        },
      });
    }
    if (optional?.recurrentPeriod === WEEK && optional.timeDifference < 7) {
      return setErrorAction({
        [fieldName]: {
          isValid: false,
          message: 'The end date must be a week after the last event date',
        },
      });
    }

    if (optional.recurrentPeriod === MONTH && optional.timeDifference < optional.daysInMonth) {
      return setErrorAction({
        [fieldName]: {
          isValid: false,
          message: 'The end date must be a month after the last event date',
        },
      });
    }
  }

  return setErrorAction({
    [fieldName]: {
      isValid: true,
      message: '',
    },
  });
};

export const getTimeWithoutS = (time) => time - (time % 60000);

export const getMinStartDate = () => getTimeWithoutS(Date.now());

export const validateSchedules = (schedules) => {
  const startTime = dayjs(schedules[0]?.startTime);
  const endTime = dayjs(schedules[schedules.length - 1]?.endTime);

  const validatedSchedules = schedules.map((schedule, index) => {
    if (schedule.isEditDisabled) {
      return schedule;
    }
    const errors = {};

    if (Math.ceil(dayjs.duration(endTime.diff(startTime)).asDays()) > 7) {
      errors.duration = 'The maximum duration of the whole schedule can be up to 7 days';
    }

    if (!schedule.title.length) {
      errors.title = 'Please, enter the title';
    }

    if (schedule.title.length > 100) {
      errors.title = 'Title size is limited by 100 characters';
    }

    if (schedule.startTime < getMinStartDate()) {
      errors.startTime = 'The schedule line couldn’t be set in the past';
    }

    schedules.forEach((item, itemIndex) => {
      if (itemIndex === index) {
        return;
      }

      if (schedule.startTime >= item.startTime && schedule.startTime <= item.endTime) {
        errors.startTime = 'The schedule line’s start/end time couldn’t be overlapped with another schedule line';
      }

      if (
        (schedule.endTime > item.startTime && schedule.endTime < item.endTime) ||
        (schedule.startTime <= item.startTime && schedule.endTime > item.startTime)
      ) {
        errors.endTime = 'The schedule line’s start/end time couldn’t be overlapped with another schedule line';
      }
    });

    if (!schedule.duration) {
      errors.duration = 'The duration cannot be empty';
    }

    if (schedule.durationIn === 'MINUTES' && schedule.duration < 10) {
      errors.duration = 'The minimum duration can be 10 minutes';
    }

    if (schedule.durationIn === 'MINUTES' && schedule.duration > 1440) {
      errors.duration = 'The maximum duration can be 1440 minutes';
    }

    if (schedule.durationIn === 'HOURS' && schedule.duration < 1) {
      errors.duration = 'The minimum duration can be 1 hour';
    }

    if (schedule.durationIn === 'HOURS' && schedule.duration > 24) {
      errors.duration = 'The maximum duration can be 24 hours';
    }

    const validatedSchedule = {
      ...schedule,
      isValid: !Object.keys(errors).length,
      errors,
    };

    return validatedSchedule;
  });

  return validatedSchedules;
};

export default validateField;
