const { DataTypes } = require("sequelize");

module.exports = (sequelize) => {
	const User = sequelize.define(
		"user",
		{
			id: {
				type: DataTypes.INTEGER,
				autoIncrement: true,
				primaryKey: true,
			},
			creation: { type: DataTypes.DATE, allowNull: false },
			modified: { type: DataTypes.DATE, allowNull: false },
			modified_by: { type: DataTypes.INTEGER, allowNull: false },
			owner: { type: DataTypes.INTEGER, allowNull: false },
			enabled: { type: DataTypes.BOOLEAN, allowNull: false },

			// main
			email: { type: DataTypes.STRING(100), allowNull: true, unique: false },
			phone_number: { type: DataTypes.STRING(20), allowNull: true },
			mobile_no: { type: DataTypes.STRING(20), allowNull: true },
			hash: { type: DataTypes.STRING(100), allowNull: false },
			secret: { type: DataTypes.STRING(100), allowNull: true },
			full_name: { type: DataTypes.STRING(100), allowNull: true },
			username: { type: DataTypes.STRING(50), allowNull: false, unique: false },
			user_image: { type: DataTypes.STRING, allowNull: true },
			api_key: { type: DataTypes.STRING(150), allowNull: true },
			api_secret: { type: DataTypes.STRING(150), allowNull: true },
			last_ip: { type: DataTypes.STRING(25), allowNull: true },
			last_login: { type: DataTypes.DATE, allowNull: true },
			last_known_versions: { type: DataTypes.JSON, allowNull: true },
			last_location: { type: DataTypes.JSON, allowNull: true },
			last_location_name: { type: DataTypes.TEXT("long"), allowNull: true },
			last_active: { type: DataTypes.DATE, allowNull: true },

			// fk
			role_id: { type: DataTypes.INTEGER, allowNull: true },
			company_id: { type: DataTypes.INTEGER, allowNull: true },

			// sappsv1 or erpnext
			idx: { type: DataTypes.STRING, allowNull: true },
			ids: { type: DataTypes.INTEGER, allowNull: true },
			import_from: { type: DataTypes.STRING(100), allowNull: true },
		},
		{
			defaultScope: { attributes: { exclude: ["hash"] } },
			scopes: { withHash: { attributes: {} } },
			tableName: "users",
			freezeTableName: true,
			indexes: [
				// OPTIMIZATION: Index on email for fast login lookup
				{
					name: "idx_users_email",
					fields: ["email"],
					where: {
						email: { [require("sequelize").Op.ne]: null },
					},
				},
				// OPTIMIZATION: Index on phone_number for fast login lookup
				{
					name: "idx_users_phone_number",
					fields: ["phone_number"],
					where: {
						phone_number: { [require("sequelize").Op.ne]: null },
					},
				},
				// OPTIMIZATION: Composite index for enabled + email lookup
				{
					name: "idx_users_enabled_email",
					fields: ["enabled", "email"],
				},
				// OPTIMIZATION: Composite index for enabled + phone_number lookup
				{
					name: "idx_users_enabled_phone",
					fields: ["enabled", "phone_number"],
				},
				// OPTIMIZATION: Index on role_id for role-based queries
				{
					name: "idx_users_role_id",
					fields: ["role_id"],
				},
			],
		}
	);

	// jika satu model memanggil refrence ke model nya sendiri maka atur di luar asosisasi
	User.belongsTo(User, { foreignKey: "modified_by", as: "modifierself" });

	User.associate = (models) => {
		User.hasOne(models.Patient, { foreignKey: "user_id", as: "patient" });
		User.hasOne(models.Employee, { foreignKey: "user_id", as: "employee" });
		User.hasMany(models.Video, { foreignKey: "owner", as: "videos" });
		User.hasMany(models.Image, { foreignKey: "owner", as: "images" });
		User.hasMany(models.Document, { foreignKey: "owner", as: "documents" });
		User.hasMany(models.UserActivity, { foreignKey: "user_id", as: "user_activities" });
		User.hasMany(models.UserAnswer, { foreignKey: "user_id", as: "user_answers" });
		User.hasMany(models.EmployeeRequest, { foreignKey: "owner", as: "employee_requests" });
		User.hasMany(models.Udk, { foreignKey: "owner", as: "udks" });
		User.hasMany(models.DeliveryTrip, { foreignKey: "owner", as: "delivery_trips" });
		User.hasMany(models.EmployeeRequest, { foreignKey: "modified_by", as: "modifiers" });
		User.hasMany(models.JobPosting, { foreignKey: "owner", as: "job_postings" });
		User.hasMany(models.JobPostingChild, { foreignKey: "owner", as: "job_posting_children" });
		User.hasMany(models.NcProduct, { foreignKey: "owner", as: "nc_products" });
		User.hasMany(models.ProductReturn, { foreignKey: "owner", as: "product_returns" });
		User.hasMany(models.Comment, { foreignKey: "owner", as: "comments" });
		User.hasMany(models.InvoiceReceipt, { foreignKey: "owner", as: "invoice_receipts" });
		User.hasMany(models.Fse, { foreignKey: "owner", as: "fses" });
		User.hasMany(models.EmployeeGroupTable, { foreignKey: "user_id", as: "employee_group_tables" });
		User.hasMany(models.TrackingLocation, { foreignKey: "user_id", as: "trackinglocations" });
		User.belongsTo(models.Role, { foreignKey: "role_id", as: "role" });
		User.belongsTo(models.Company, { foreignKey: "company_id", as: "company" });
		User.belongsToMany(models.Company, { through: models.UserCompany, foreignKey: "user_id", otherKey: "company_id", as: "companies" });
	};

	return User;
};
