const bcryptjs = require('bcryptjs');
const { UUID, UUIDV4, STRING, DATEONLY, BOOLEAN, DOUBLE, TEXT, JSON } = require('sequelize');

module.exports = (sequelize, DataTypes) => {
	const Users = sequelize.define(
		'Users',
		{
			id: {
				type: UUID,
				defaultValue: UUIDV4,
				allowNull: false,
				primaryKey: true,
			},
			firstname: {
				type: STRING,
				allowNull: true,
			},
			lastname: {
				type: STRING,
				allowNull: true,
			},
			phone_no: {
				type: STRING,
				allowNull: false,
			},
			email_address: {
				type: STRING,
				allowNull: true,
			},
			password: {
				type: STRING,
				allowNull: true,
			},
			birthdate: {
				type: DATEONLY,
				allowNull: true,
			},
			image: {
				type: STRING,
				allowNull: true,
				defaultValue: null,
			},
			is_phone_verified: {
				type: BOOLEAN,
				allowNull: false,
				defaultValue: false,
			},
			is_host: {
				type: BOOLEAN,
				allowNull: false,
				defaultValue: false,
			},
			hosting_date: {
				type: DATEONLY,
				allowNull: true,
			},
			has_pending_host_application: {
				type: BOOLEAN,
				allowNull: false,
				defaultValue: false,
			},
			status: {
				type: BOOLEAN,
				allowNull: false,
				defaultValue: true,
			},
			address_long: {
				type: DOUBLE,
				allowNull: true,
			},
			address_lat: {
				type: DOUBLE,
				allowNull: true,
			},
			address_country: {
				type: STRING,
				allowNull: true,
			},
			address_street: {
				type: STRING,
				allowNull: true,
			},
			address_apt: {
				type: STRING,
				allowNull: true,
			},
			address_city: {
				type: STRING,
				allowNull: true,
			},
			address_state: {
				type: STRING,
				allowNull: true,
			},
			address_zip: {
				type: STRING,
				allowNull: true,
			},
			valid_id_type: {
				type: STRING,
				allowNull: true,
			},
			valid_id_image: {
				type: STRING,
				allowNull: true,
			},
			language: {
				type: STRING,
				defaultValue: 'English',
			},
			about_me: {
				type: TEXT,
				allowNull: true,
			},
			school: {
				type: STRING,
				allowNull: true,
			},
			work: {
				type: STRING,
				allowNull: true,
			},
			music: {
				type: STRING,
				allowNull: true,
			},
			lived_in: {
				type: STRING,
				allowNull: true,
			},
			languages: {
				type: JSON,
				allowNull: true,
			},
			pets: {
				type: STRING,
				allowNull: true,
			},
			hangouts: {
				type: STRING,
				allowNull: true,
			},
			birth_year: {
				type: STRING,
				allowNull: true,
			},
			likes: {
				type: STRING,
				allowNull: true,
			},
			dislikes: {
				type: STRING,
				allowNull: true,
			},
			interests: {
				type: JSON,
				allowNull: true,
			},
			show_travels: {
				type: BOOLEAN,
				defaultValue: true,
			},
			verified: {
				type: BOOLEAN,
				defaultValue: false,
			},
			is_facebook: {
				type: BOOLEAN,
				defaultValue: false,
			},
			is_google: {
				type: BOOLEAN,
				defaultValue: false,
			},
			is_apple: {
				type: BOOLEAN,
				defaultValue: false,
			},
		},
		{
			hooks: {
				beforeCreate: async (customer) => {
					if (customer.changed('password')) {
						const saltRounds = 10;
						customer.password = await bcryptjs.hash(customer.password, saltRounds);
					}
				},
				beforeUpdate: async (customer) => {
					if (customer.changed('password')) {
						const saltRounds = 10;
						customer.password = await bcryptjs.hash(customer.password, saltRounds);
					}
				},
			},
			tableName: 'users',
			timestamps: true,
		},
	);

	Users.associate = function (models) {
		Users.hasMany(models.HostReviews, {
			foreignKey: 'user_id',
			as: 'hostReviews',
		});

		Users.hasMany(models.Bookings, {
			foreignKey: 'customer_id',
		});

		Users.hasMany(models.CustomerReviews, {
			foreignKey: 'user_id',
		});
	};

	Users.prototype.validatePassword = async function (plainPassword) {
		return bcryptjs.compare(plainPassword, this.password);
	};

	return Users;
};
