'use strict';

const Sequelize = require('sequelize'),
  config = require('config');

function init() {
  const db = {
    sequelize: new Sequelize(config.get('db.goodtimes')),
    Sequelize: Sequelize
  };

  return db.sequelize.authenticate().then(function () {
    const Group = db.sequelize.define('group', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      name: Sequelize.STRING,
      description: Sequelize.STRING,
      public: {
        type: Sequelize.BOOLEAN,
        allowNull: false, 
        defaultValue: true
      },
      ownerId: Sequelize.INTEGER
    }, {
      timestamps: false,
      classMethods: {
        associate: function() {}
      }
    });

    const User = db.sequelize.define('users', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      familyName: Sequelize.STRING,
      firstName: Sequelize.STRING,
      uid: Sequelize.STRING,
      md5: Sequelize.STRING, /* md5 of email address for Gravatar */
      authToken: Sequelize.STRING,
      authDate: Sequelize.DATE,
      authenticated: Sequelize.BOOLEAN,
      mailVerified: Sequelize.BOOLEAN,
      email: Sequelize.STRING,
      memberSince: Sequelize.DATE,
      password: Sequelize.STRING, /* SHA hash of user supplied password */
      passwordExpires: Sequelize.DATE
    }, {
      timestamps: false
    });

    // eslint-disable-next-line no-unused-vars
    const Location = db.sequelize.define('locations', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      groupId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: Group,
          key: 'id'
        }
      },
      name: Sequelize.STRING,
      location: Sequelize.STRING,
      map: Sequelize.STRING,
      url: Sequelize.STRING,
      note: Sequelize.STRING,
      disabled: Sequelize.BOOLEAN,
      beerlist: Sequelize.STRING,
      added: Sequelize.DATE
    }, {
      timestamps: false
    });

    // eslint-disable-next-line no-unused-vars
    const Authentication = db.sequelize.define('authentication', {
      key: {
        type: Sequelize.STRING,
        primaryKey: true,
        allowNull: false
      },
      issued: Sequelize.DATE,
      type: {
        type: Sequelize.ENUM,
        values: ['account-setup', 'password-reset']
      },
      userId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: User,
          key: 'id',
        }
      }
    }, {
      timestamps: false
    });
    
    // eslint-disable-next-line no-unused-vars
    const GroupUsers = db.sequelize.define('groupusers', {
      groupId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: Group,
          key: 'id'
        }
      },
      userId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: User,
          key: 'id'
        }
      }
    }, {
      timestamps: false
    });

    const Event = db.sequelize.define('events', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      groupId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: Group,
          key: 'id'
        }
      },
      date: Sequelize.DATE
    }, {
      timestamps: false
    });

    // eslint-disable-next-line no-unused-vars
    const EventVote = db.sequelize.define('eventvotes', {
      eventId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: Event,
          key: 'id'
        }
      },
      userId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: User,
          key: 'id'
        }
      },
      locationId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: Location,
          key: 'id'
        }
      },
      rating: Sequelize.INTEGER,
      submitted: Sequelize.DATE
    }, {
      timestamps: false
    });
    
    // eslint-disable-next-line no-unused-vars
    const Attendance = db.sequelize.define('attendees', {
      eventId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: Event,
          key: 'id'
        }
      },
      userId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        references: {
          model: User,
          key: 'id'
        }
      },
      state: {
        type: {
          type: Sequelize.ENUM,
          values: ['unknown', 'in', 'out']
        }
      },
      note: Sequelize.STRING
    }, {
      timestamps: false
    });

    return db.sequelize.sync({
      force: false
    }).then(function () {
      return db;
    });
  }).catch(function (error) {
    console.log('ERROR: Failed to authenticate with GROUP DB');
    console.log('ERROR: ' + JSON.stringify(config.get('db'), null, 2));
    console.log(error);
    throw error;
  });
}

module.exports = { goodTimesDB: { init } };
