import { Schema, model, Document, Types } from 'mongoose'
import { ILocation, LocationSchema } from '../../utils/types'

export const LoggedinDeviceSchema = new Schema(
	{
		fcmToken: String,
		platform: {
			type: String,
			enum: ['android', 'ios', 'web']
		},
		tokenHash: {
			type: String,
			required: true
		},
		lastAccessedAt: {
			type: Date,
			default: Date
		}
	}, {versionKey: false, timestamps: true}
)

export interface ILoggedinDevice {
	_id: Types.ObjectId
  tokenHash: string
	fcmToken?: string
	platform?: 'android' | 'ios' | 'web'
	lastAccessedAt: Date
	createdAt: Date
	updatedAt: Date
}

export const AuthSchema = new Schema(
	{
		password: {
			type: String,
			required: true,
		},
		twoFactorAuthentication: Boolean,
		loggedinDevices: {
			type: [LoggedinDeviceSchema],
			default: []
		},

    phoneOtp: String,
		phoneOtpExpiry: Date,
		phoneVerified: Boolean,
		lastPhoneOtpSentAt: Date,

    emailOtp: String,
		emailOtpExpiry: Date,
		emailVerified: Boolean,
		lastEmailOtpSentAt: Date,
	},
	{ versionKey: false, _id: false }
)

export interface IAuth {
  password: string
	twoFactorAuthentication?: boolean
	loggedinDevices: ILoggedinDevice[]

  phoneOtp?: string
  phoneOtpExpiry?: Date
	phoneVerified?: boolean
	lastPhoneOtpSentAt?: Date

  emailOtp?: string
  emailOtpExpiry?: Date
	emailVerified?: boolean
	lastEmailOtpSentAt?: Date
}

export const PurposeSchema = new Schema(
	{
		type: {
			type: String,
			enum: ['short-term', 'long-term'],
			required: true,
		},
		value: {
			type: [String],
			required: true,
		},
	},
	{ versionKey: false, _id: false }
)

export interface IPurpose {
  type: 'short-term' | 'long-term'
	value: string[]
}

export const StudySchema = new Schema(
	{
		type: {
			type: String,
			required: true,
		},
		value: {
			type: [String],
			required: true,
		},
	},
	{ versionKey: false, _id: false }
)

export interface IStudy {
  type: string
	value: string[]
}

const UserSchema = new Schema(
	{
		name: {
			type: String,
      trim: true,
		},
		username: {
			type: String,
      trim: true,
		},
		bio: {
			type: String,
			trim: true,
		},
		url: {
			type: String,
			trim: true,
		},
		school: {
			type: String,
			trim: true,
		},
		courses: {
			type: String,
			trim: true,
		},
		email: {
			type: String,
			required: true,
			unique: true,
			match: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i
		},
		phone: String,
		dob: {
			type: Date,
			required: true
		},
		auth: {
			type: AuthSchema,
			required: true,
		},
    photo: String,
		terminated: Boolean,
		purposes: {
			type: [PurposeSchema],
			default: []
		},
		studies: {
			type: [StudySchema],
			default: []
		},
		categories: {
			type: [String],
			default: []
		},
		isManuallyOffline: Boolean,
		isOnline: Boolean,
		lastOnlineAt: Date,
		followers: {
			type: Number,
			default: 0,
		},
		followings: {
			type: Number,
			default: 0,
		},
		posts: {
			type: Number,
			default: 0
		},
		status: {
			type: Types.ObjectId,
			ref: 'Status'
		},
		deactivatedAt: Date,
		location: LocationSchema,
		locationString: String,
		data: Schema.Types.Mixed,
		verified: Boolean
	},
	{ versionKey: false, timestamps: true }
)

UserSchema.index({ location: '2dsphere' })

export interface IUser extends Document {
	_id: Types.ObjectId
	name?: string
	username?: string
	bio?: string
	url?: string
	school?: string
	courses?: string
	email: string
	phone?: string
	dob: Date
	auth: IAuth
  photo?: string
	terminated?: boolean
	purposes: IPurpose[]
	studies: IStudy[]
	categories: string[]
	isManuallyOffline?: boolean
	isOnline?: boolean
	lastOnlineAt?: Date
	followers: number
	followings: number
	posts: number
	status?: Types.ObjectId
	deactivatedAt?: Date
	location?: ILocation
	locationString?: string
	data?: Record<string, any>
	verified?: boolean
	createdAt: Date
  updatedAt: Date
}

export const User = model('User', UserSchema, 'users')
