let libNodemailer = require('nodemailer');

fcf.module({
  name: "fcfSimpleAuthorization:templates/registration-form.receive.js",
  dependencies: [],
  module: function(){
    var self = this;

    fcf.addException("USER_ALREADY_EXISTS", "The specified user name already exists");
    fcf.addException("EMAIL_ALREADY_EXISTS", "The specified email already exists");
    fcf.addException("FAILED_SEND_EMAIL", "Couldn't send email to the specified address");

    return class Handler {
      receive(a_fields, a_files, a_request) {
        let token  = fcf.id(64);

        if (!fcf.application.getConfiguration().fcfSimpleAuthorization_enableRegistration) {
          throw new fcf.Exception("OPERATION_NOT_SUPPORTED");
        }

        return fcf.application.getStorage().query(
          {
            type: "select",
            from: fcf.application.getConfiguration().userProjectionName,
            fields: [{field: "user"}, {field: "email"}],
            where:[
              { logic: "or", type: "=", args: [{field: "user"}, {value: a_fields.user}] },
              { logic: "or", type: "=", args: [{field: "email"}, {value: a_fields.email}] },
            ]
          },
          {roles: ["root"]}
        )
        .then((a_records)=>{
          if (a_records[0][0]){
            if (a_records[0][0].email == a_fields.email)
              throw new fcf.Exception("EMAIL_ALREADY_EXISTS");
            else
              throw new fcf.Exception("USER_ALREADY_EXISTS");
          }
        })
        // build message template
        .then(()=>{
          return fcf.application.render({
            template: fcf.application.getConfiguration().fcfSimpleAuthorization_registrationEmailTemplate,
            args: {
              email:    a_fields.email,
              user:     a_fields.user,
              password: a_fields.password,
              token:    token,
            }
          });
        })
        // send message
        .then((a_template, a_act)=>{
          let transporter = libNodemailer.createTransport({
            host: fcf.application.getConfiguration().mailService,
            port: 465,
            secure: true,
            auth: {
              user: fcf.application.getConfiguration().mailUser,
              pass: fcf.application.getConfiguration().mailPassword
            }
          });
          let options = {
            from:     fcf.application.getConfiguration().mailAddress,
            to:       a_fields.email,
            subject:  fcf.t('Registration'),
            html:     a_template.content,
          };
          transporter.sendMail(options, function(a_error, a_info){
            if (a_error) {
              a_act.error(new fcf.Exception("FAILED_SEND_EMAIL", {}, a_error));
              return;
            }
            a_act.complete();
          });
        })
        // Read group
        .then(()=>{
          return fcf.application.getStorage().query("SELECT id FROM ___fcf___groups WHERE name = ${1}", ["user"]);
        })
        // Create user
        .then((a_recordsGroup)=>{
          let userGroupId = a_recordsGroup[0][0].id;
          return fcf.application.getStorage().query(
            {
              type: "insert",
              from: fcf.application.getConfiguration().userProjectionName,
              values: [
                { field: "user",     value: a_fields.user },
                { field: "email",    value: a_fields.email },
                { field: "password", value: a_fields.password },
                { field: "active",   value: true },
                { field: "initialized",  value: false },
                { field: "time_creation",  value: fcf.dateFormat(new Date(), "Y-m-d H:i:s") },
                { field: "groups",   value: [userGroupId] }
              ]
            },
            {roles: ["root"]}
            )
        })
        // Create token
        .then((a_recordsUser)=>{
          let userId = a_recordsUser[0][0]["@key"];
          return fcf.application.getStorage().query(
            {
              type: "insert",
              from: "___fcfSimpleAuthorization___registration_requests",
              values:[
                { field: "user", value: userId },
                { field: "token", value: token }
              ]
            },
            { roles: ["root"]}
          )
          .then(()=>{
            return token;
          })
        })

      }
    }
  }
});
