import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose, { Document } from 'mongoose';
import bcrypt from 'bcrypt';
import { Subscription } from '../subscriptions/subscriptions.model';
import { UserAnalytics } from '../user-analytics/user-analytics.model';

export type UserDocument = User & Document;

@Schema({ timestamps: false, _id: false, versionKey: false })
export class Settings {
	@Prop({ required: false, default: true })
	isFilter: boolean;

	@Prop({ required: false, default: true })
	isImageInsideChat: boolean;
}

@Schema({ timestamps: { createdAt: 'date_created', updatedAt: false }, _id: false, versionKey: false })
export class MemoryItem {
	@Prop({ type: String, required: true })
	content: string;

	@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'SingleChat', required: false })
	messageId?: mongoose.Types.ObjectId;

	date_created: Date;
}

@Schema({ timestamps: true, autoIndex: true })
export class User {

	_id: string | mongoose.Types.ObjectId;

	@Prop({
		required: [true, 'Name is required'],
		minlength: [3, 'Name must be at least 3 characters long'],
		trim: true,
	})
	name: string;

	@Prop({ required: true, unique: true, trim: true, lowercase: true })
	email: string;

	@Prop({
		required: true,
		minlength: [6, 'Password must be at least 6 characters long'],
		select: false, // TODO: uncomment this and handle password select in auth service
	})
	password: string;

	@Prop({
		required: false,
		enum: {
			values: ['user', 'admin', 'super_admin'],
			message: 'Role is either: user or admin',
		},
		default: 'user',
	})
	role?: 'user' | 'admin' | 'super_admin';

	@Prop({ required: false, default: null })
	imageUrl?: string;

	@Prop({ required: false, default: false })
	isVerified?: boolean;

	@Prop({ required: false, default: false })
	isBlocked?: boolean;

	@Prop({ required: false, default: false })
	isDeleted?: boolean;

	@Prop({
		required: false,
		enum: {
			values: ['EN', 'HB'],
			message: 'Language is either: EN or HB',
		},
		default: 'HB',
	})
	language?: string;

	// @Prop({ required: false, default: true })
	// isAcceptTerms: boolean;

	@Prop({
		default: null,
		type: mongoose.Schema.Types.ObjectId,
		ref: 'Subscription',
	})
	subscription?: Subscription;

	@Prop({
		type: mongoose.Schema.Types.ObjectId,
		ref: 'UserAnalytics'
	})
	userAnalytics: UserAnalytics;

	@Prop({ type: Settings, default: new Settings() })
	settings: Settings;

	@Prop({ type: [MemoryItem], default: [] })
	memory: MemoryItem[];


	@Prop({ type: String, required: false})
	groupTag?: string;

	@Prop({ type: String, required: false })
	phoneNumber?: string;

	// @Prop({
	// 	type: mongoose.Schema.Types.ObjectId,
	// 	default: null,
	// })
	// whatsappId?: mongoose.Types.ObjectId;

	createdAt: Date;
	updatedAt: Date;
	timezone?: string;


	@Prop({ type: { accessToken: String, refreshToken: String, expiresAt: Number }, default: null, select: 0 })
	googleDrive: {
		accessToken: string;
		refreshToken: string;
		expiresAt: number;
	};
	

	checkPassword: (
		plainPassword: string,
		hashedPassword: string,
	) => Promise<boolean>;
}

export const UserSchema = SchemaFactory.createForClass(User);

UserSchema.pre('save', async function (next: any) {
	if (!this.isModified('password')) {
		return next();
	}
	this['password'] = await bcrypt.hash(this['password'], 10);
	next();
});

UserSchema.statics.checkPassword = async function (
	plainPassword: string,
	hashedPassword: string,
) {
	return await bcrypt.compare(plainPassword, hashedPassword);
};
