export const VALIDATION_MESSAGES = {
  eventStartsInPast: 'Your event is set to start in the past.',
  eventStartsSoon: 'Your event will start in less than an hour.',
  eventTooShort: 'An event must last at least 30 minutes.',
  startTimeMissing: 'A start time is required',
  endTimeMissing: 'An end time is required',
  gameInvalid: 'Please choose a supported game',
  wrongFileType: 'Your image must be a .png or a .jpg file.',
  imageTooBig: 'Your image must be smaller than 3 MB.'
};

export const FILE_SIZE_LIMIT = 3 * Math.pow(1024, 2); // 3 MB
export const MIME_TYPES = ['image/jpeg', 'image/png'];
const SECONDS = 1000;
const MINUTES = SECONDS * 60;
const HOURS = MINUTES * 60;

export default function validateEvent({
  startTime,
  endTime,
  gameName,
  gameId,
  imageFile
}, options = {}) {
  let now = options.now || new Date();
  let validation = new Validation();

  if (!startTime) {
    validation.setError('startTime', VALIDATION_MESSAGES.startTimeMissing);
  } else if (startTime - now < 0) {
    validation.setWarning('startTime', VALIDATION_MESSAGES.eventStartsInPast);
  } else if (startTime - now < HOURS) {
    validation.setWarning('startTime', VALIDATION_MESSAGES.eventStartsSoon);
  }

  if (!endTime) {
    validation.setError('endTime', VALIDATION_MESSAGES.endTimeMissing);
  } else if (endTime - startTime < 30 * MINUTES) {
    validation.setError('endTime', VALIDATION_MESSAGES.eventTooShort);
  }

  if (gameName && gameName.length && !gameId) {
    validation.setError('game', VALIDATION_MESSAGES.gameInvalid);
  }

  if (imageFile) {
    if (!MIME_TYPES.includes(imageFile.type)) {
      validation.setWarning('imageFile', VALIDATION_MESSAGES.wrongFileType);
    } else if (imageFile.size > FILE_SIZE_LIMIT) {
      validation.setWarning('imageFile', VALIDATION_MESSAGES.imageTooBig);
    }
  }

  return validation;
}

class Validation {
  constructor() {
    this.errors = {};
    this.warnings = {};
    this.hasErrors = false;
  }

  setError(key, value) {
    this.hasErrors = true;
    this.errors[key] = value;
  }

  setWarning(key, value) {
    this.warnings[key] = value;
  }
}
