import crypto from "node:crypto";
import { TRPCError } from "@trpc/server";
import type { UsersId } from "~/schemas/public/Users";
import { db } from "~/server/db";
import { NewMail } from "../services/mailer";

const INVITE_EXPIRY_HOURS = 48;

export async function createInviteToken(email: string) {
	// Generate a secure random token
	const token = crypto.randomBytes(32).toString("hex");
	const expiresAt = new Date(Date.now() + INVITE_EXPIRY_HOURS * 60 * 60 * 1000);

	try {
		// Store in database
		await db
			.insertInto("user_invites")
			.values({
				email,
				token,
				expires_at: expiresAt,
			})
			.execute();
	} catch (e) {
		console.error("Error creating invite token:", e);
		throw new TRPCError({
			code: "INTERNAL_SERVER_ERROR",
			message: `Errore durante la creazione del token di invito.: ${(e as Error).message}`,
		});
	}
	return token;
}

export async function verifyInviteToken(token: string) {
	try {
		const invite = await db
			.selectFrom("user_invites")
			.selectAll()
			.where("token", "=", token)
			.where("expires_at", ">", new Date())
			.executeTakeFirst();
		if (!invite) {
			return null;
		}
		return invite;
	} catch (e) {
		console.error("Error verifying invite token:", e);
		throw new TRPCError({
			code: "INTERNAL_SERVER_ERROR",
			message: `Errore durante la verifica del token di invito.: ${(e as Error).message}`,
		});
	}
}

export async function consumeInviteToken(token: string) {
	try {
		await db.deleteFrom("user_invites").where("token", "=", token).execute();
	} catch (e) {
		console.error("Error consuming invite token:", e);
		throw new TRPCError({
			code: "INTERNAL_SERVER_ERROR",
			message: `Errore durante il consumo del token di invito.: ${(e as Error).message}`,
		});
	}
}

export const sendInvitoEmail = async ({
	userId,
	email,
	inviteUrl,
	nome,
}: {
	userId: UsersId;
	email: string;
	inviteUrl: string;
	nome: string;
}) => {
	try {
		await NewMail({
			template: {
				mailType: "invito",
				props: {
					inviteUrl,
					nome,
				},
			},
			mail: {
				subject: "Procedi ora su Infoalloggi.it",
				to: email,
			},
			userId,
		});

		return true;
	} catch (e) {
		throw new TRPCError({
			code: "INTERNAL_SERVER_ERROR",
			message: `Error sending email: ${(e as Error).message}`,
		});
	}
};
