import { usePrisma } from "../utils/prisma"; export async function getMailConnections(userId: string) { const db = usePrisma(); return db.mailConnection.findMany({ where: { userId, isActive: true }, orderBy: { createdAt: "asc" }, }); } export async function getAllActiveMailUserIds() { const db = usePrisma(); const rows = await db.mailConnection.findMany({ where: { isActive: true, nextScanAt: { lte: new Date() } }, select: { userId: true }, distinct: ["userId"], }); return rows.map((r) => r.userId); } export async function countMailConnections(userId: string) { const db = usePrisma(); return db.mailConnection.count({ where: { userId, isActive: true } }); } export async function upsertMailConnection(data: { userId: string; email: string; provider: string; providerName: string; imapHost: string; imapPort: number; passwordEncrypted: string; rejectUnauthorized?: boolean; useStarttls?: boolean; }) { const db = usePrisma(); return db.mailConnection.upsert({ where: { userId_email: { userId: data.userId, email: data.email } }, create: { ...data, isActive: true, rejectUnauthorized: data.rejectUnauthorized ?? true, useStarttls: data.useStarttls ?? false, }, update: { providerName: data.providerName, imapHost: data.imapHost, imapPort: data.imapPort, passwordEncrypted: data.passwordEncrypted, rejectUnauthorized: data.rejectUnauthorized ?? true, useStarttls: data.useStarttls ?? false, isActive: true, // Bei Re-Connect (z.B. neues App-Passwort): alte Error-Spuren clearen, // damit UI sofort wieder "Live" zeigt — IDLE-daemon übernimmt. lastConnectError: null, lastConnectErrorAt: null, }, }); } export async function deleteMailConnection( userId: string, connectionId: string, ) { const db = usePrisma(); return db.mailConnection.deleteMany({ where: { id: connectionId, userId }, }); } export async function deleteAllMailConnections(userId: string) { const db = usePrisma(); return db.mailConnection.deleteMany({ where: { userId } }); } export async function updateMailConnectionInterval( userId: string, connectionId: string, interval: number, ) { const db = usePrisma(); return db.mailConnection.updateMany({ where: { id: connectionId, userId }, data: { scanInterval: interval }, }); } export async function updateMailConnectionScanStats( connectionId: string, scanned: number, blocked: number, currentBlocked: number, currentScanned: number, scanIntervalHours: number, ) { const db = usePrisma(); return db.mailConnection.update({ where: { id: connectionId }, data: { lastScannedAt: new Date(), emailsBlocked: currentBlocked + blocked, emailsScanned: currentScanned + scanned, nextScanAt: new Date(Date.now() + scanIntervalHours * 3_600_000), }, }); } export async function getMailBlockedStats(userId: string) { const db = usePrisma(); const since7d = new Date(Date.now() - 7 * 86_400_000); return db.mailBlocked.findMany({ where: { userId, createdAt: { gte: since7d } }, select: { createdAt: true }, }); } export async function isMailAlreadyBlocked( gmailMessageId: string, userId: string, ) { const db = usePrisma(); const existing = await db.mailBlocked.findFirst({ where: { gmailMessageId, userId }, select: { id: true }, }); return !!existing; } export async function getAlreadyBlockedUidSet( uids: string[], userId: string, ): Promise> { if (uids.length === 0) return new Set(); const db = usePrisma(); const existing = await db.mailBlocked.findMany({ where: { gmailMessageId: { in: uids }, userId }, select: { gmailMessageId: true }, }); return new Set(existing.map((e) => e.gmailMessageId)); } export async function insertMailBlocked( entries: { userId: string; connectionId: string; gmailMessageId: string; senderEmail: string; senderName: string | null; subject: string; receivedAt: Date; action: string; }[], ) { if (entries.length === 0) return; const db = usePrisma(); await db.mailBlocked.createMany({ data: entries, skipDuplicates: true }); } export async function getImapProxyAccounts(userId: string) { const db = usePrisma(); return db.imapProxyAccount.findMany({ where: { userId } }); } export async function upsertImapProxyAccount(data: { userId: string; proxyUsername: string; proxyPassword: string; connectionId: string; }) { const db = usePrisma(); return db.imapProxyAccount.upsert({ where: { connectionId: data.connectionId }, create: data, update: { proxyPassword: data.proxyPassword }, }); } export async function deleteOldMailBlocked(userId: string) { const db = usePrisma(); const cutoff = new Date(Date.now() - 24 * 3_600_000); return db.mailBlocked.deleteMany({ where: { userId, createdAt: { lt: cutoff } }, }); } export async function getMailBlockedPaginated( userId: string, page: number, limit = 20, ) { const db = usePrisma(); const offset = (page - 1) * limit; const [results, total] = await Promise.all([ db.mailBlocked.findMany({ where: { userId }, orderBy: { createdAt: "desc" }, skip: offset, take: limit, }), db.mailBlocked.count({ where: { userId } }), ]); return { results, total, page, pages: Math.ceil(total / limit) }; }