const ObjectId = require('bson').ObjectID;
const tv4 = require('tv4');

const Email = require('./email');
const Recipient = require('./recipient');
const Todo = require('./todo');
const REMINDER_STATUS = require('../../constant/reminder/reminder-status.constant');
const REMINDER_TYPE = require('../../constant/reminder/reminder-type.constant');
const Helper = require('../../helper/helper');

class Reminder {
  constructor(opt) {
    this._id = null;
    this.label = null;
    this.campusCode = null;
    this.tenantCode = null;
    this.applicationName = null;
    this.status = null;
    this.type = null;
    this.createdDate = null;
    this.completedDate = null;
    this.details = {};
    if (opt) {
      this.fillObject(opt);
    }
  }

  fillObject(opt) {
    this._id = new ObjectId(opt._id);
    this.label = opt.label;
    this.campusCode = opt.campusCode;
    this.tenantCode = opt.tenantCode;
    this.applicationName = opt.applicationName;
    this.status = opt.status || REMINDER_STATUS.PENDING;
    this.type = opt.type;
    this.createdDate = opt.createdDate;
    this.completedDate = opt.completedDate || null;
    if (this.type === REMINDER_TYPE.EMAIL) {
      this.validateObj(new Email(opt));
    } else if (this.type === REMINDER_TYPE.TODO) {
      this.validateObj(new Todo(opt));
    }
  }

  validateObj(obj) {
    const validation = obj.validate();
    if (!validation.valid) {
      throw Helper.validateError(validation).msg;
    }
    this.details = obj;
  }

  validate() {
    const validation = tv4.validateMultiple(this, Reminder.schema());
    const labelIsValid = Helper.validateLabel(this.label);
    if (!labelIsValid) {
      validation.errors.push(new Error('Invalid type (expecting string, boolean or number) for values on label'));
      validation.valid = false;
    }
    return validation;
  }

  static schema() {
    return {
      $schema: 'http://json-schema.org/draft-04/schema#',
      id: 'reminder.schema.json',
      type: 'object',
      additionalProperties: false,
      properties: {
        _id: { type: ['object', 'null'] },
        label: { type: 'object' },
        tenantCode: { type: 'string' },
        campusCode: { type: 'string' },
        applicationName: { type: 'string' },
        status: { enum: Object.keys(REMINDER_STATUS) },
        type: { enum: Object.keys(REMINDER_TYPE) },
        details: { type: ['object'] },
        createdDate: { type: 'object' },
        completedDate: { type: ['object', 'null'] },
      },
      required: [
        '_id',
        'label',
        'tenantCode',
        'campusCode',
        'status',
        'type',
        'applicationName',
        'createdDate',
        'completedDate',
      ],
    };
  }
}

tv4.addSchema(Email.schema());
tv4.addSchema(Todo.schema());
tv4.addSchema(Recipient.schema());

module.exports = Reminder;
