import { DIVIDER, SUPPORTED_FORMATS } from './consts';
import { newDate } from './date-utils';

const patterns = {
  MM: '(0?[1-9]|1[0-2])',
  DD: '(0?[1-9]|[12][0-9]|3[01])',
  YYYY: '([0-9]{4})',
};

const createPattern = (format) => {
  const pattern = format
    .split(DIVIDER)
    .map((part) => patterns[part])
    .join('\\D');

  return `^${pattern}$`;
};

const createToValuesFn = (format) => {
  const order = format.split(DIVIDER);
  return (match) => {
    const values = {};
    order.forEach((part, index) => {
      values[part] = match[index + 1];
    });
    return [values.YYYY, values.MM, values.DD];
  };
};

const createDate = (val, regexp, toValuesFn) => {
  const match = regexp.exec(val);
  if (!match) return null;
  const [year, month, day] = toValuesFn(match);
  return newDate([year, month, day].join(DIVIDER));
};

const createFormat = (format) => {
  const pattern = createPattern(format);
  const toValuesFn = createToValuesFn(format);
  const regexp = new RegExp(pattern);

  return {
    pattern,
    validate: (val) => regexp.test(val),
    getDate: (val) => createDate(val, regexp, toValuesFn),
  };
};

export const formats = Object.fromEntries(SUPPORTED_FORMATS.map((f) => [f, createFormat(f)]));
