import { Mail, MailDetails, MailFolder } from "../../../common/api/entities/tutanota/TypeRefs"
import { MailPhishingStatus, MailSetKind } from "../../../common/api/common/TutanotaConstants"
import { SpamClassifier } from "../../workerUtils/spamClassification/SpamClassifier"
import { assertNotNull } from "@tutao/tutanota-utils"
import { FolderSystem } from "../../../common/api/common/mail/FolderSystem"
import { assertMainOrNode } from "../../../common/api/common/Env"
import { UnencryptedProcessInboxDatum } from "./ProcessInboxHandler"
import { ClientClassifierType } from "../../../common/api/common/ClientClassifierType"
import { createSpamMailDatum } from "../../../common/api/common/utils/spamClassificationUtils/SpamMailProcessor"
import { isSameId } from "../../../common/api/common/utils/EntityUtils"

assertMainOrNode()

export class SpamClassificationHandler {
	public constructor(private readonly spamClassifier: SpamClassifier) {}

	public async predictSpamForNewMail(
		mail: Mail,
		mailDetails: MailDetails,
		sourceFolder: MailFolder,
		folderSystem: FolderSystem,
	): Promise<{ targetFolder: MailFolder; processInboxDatum: UnencryptedProcessInboxDatum }> {
		const spamMailDatum = createSpamMailDatum(mail, mailDetails)

		const vectorizedMail = await this.spamClassifier.vectorize(spamMailDatum)
		const isSpam = (await this.spamClassifier.predict(vectorizedMail, spamMailDatum.ownerGroup)) ?? null

		let targetFolder = sourceFolder
		if (isSpam && sourceFolder.folderType === MailSetKind.INBOX) {
			targetFolder = assertNotNull(folderSystem.getSystemFolderByType(MailSetKind.SPAM))
		} else if (!isSpam && sourceFolder.folderType === MailSetKind.SPAM && mail.phishingStatus !== MailPhishingStatus.SUSPICIOUS) {
			// move mail from spam to inbox only if the phishingStatus is not suspicious
			// i.e. override the client spam classifier result and keep the mail in spam if the server thinks that the mail is a phishing mail
			targetFolder = assertNotNull(folderSystem.getSystemFolderByType(MailSetKind.INBOX))
		}
		const processInboxDatum: UnencryptedProcessInboxDatum = {
			mailId: mail._id,
			targetMoveFolder: targetFolder._id,
			classifierType: ClientClassifierType.CLIENT_CLASSIFICATION,
			vector: await this.spamClassifier.vectorizeAndCompress(spamMailDatum),
		}
		return { targetFolder, processInboxDatum: processInboxDatum }
	}
}
