'use strict';

const { events: eventsApi } = require('./api');

const validate = (event) => {
  if (!event) {
    throw new Error('An "event" is required.');
  }

  if (typeof event !== 'object') {
    throw new Error('The "event" argument must be an object');
  }

  const validateObject = ({ event: type, action }) => {
    if (!type || typeof type !== 'string') {
      throw new Error(
        'The "event" property containing the event type is required and must be a string'
      );
    }

    if (!action) {
      throw new Error(
        'The "action" property containing the event action is required and must be a string'
      );
    }

    if (!event.data) {
      event.data = {};
    }

    if (typeof event.data !== 'object') {
      throw new Error(`The data of event must be object, but it is ${event.data}`);
    }
  };

  if (Array.isArray(event)) {
    if (!event.length) {
      throw new Error('Event batch must be non empty');
    }

    const events = new Set();
    const actions = new Set();
    event.forEach((obj) => {
      validateObject(obj);
      events.add(obj.event);
      actions.add(obj.action);
    });

    // If each event has same event_type and action, we just think they are a batch of same events
    if (events.size === 1 && actions.size === 1) {
      return {
        event: 'batch',
        action: actions.values()[0],
        originEvent: event.values()[0],
        data: event,
      };
    }
  } else {
    validateObject(event);
  }

  return event;
};

const publish = async (sdk, eventData) => {
  const data = validate(eventData);

  return await eventsApi.publish(sdk, data);
};

module.exports = {
  publish,
};
