import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
import * as nodemailer from "nodemailer"
import { prisma } from "#lib/server/prisma.js";
import { decodeToken, encodeToken } from "#lib/auth/token.js";
import { TokenType } from "#lib/auth/types.js";
import { hashPassword } from "#lib/password.js";
import { transport } from "#lib/mail.js";

export const GET = defineApiRoute({
	input: z.object({
		email: z.string().email()
	}),
	output: z.void(),
	async fetch(input, context, transfer) {
		const user = await prisma.benutzer.findUnique({
			where: {
				email: input.email
			}
		})

		if (!user) {
			// Wir senden einen INTERNAL_SERVER_ERROR zurück, damit man nicht aus dem Fehler schließen kann, ob es den Nutzer gibt.
			throw new APIError({
				code: "INTERNAL_SERVER_ERROR",
				message: "Etwas ist schiefgelaufen, bitte versuchen sie es erneut."
			})
		}

		// Wir generieren einen Token der für 30 Minuten gültig ist, damit der Nutzer das Passwort zurücksetzen kann.
		const resetToken = encodeToken({
			exp: Date.now() + 15 * 60 * 1000,
			typ: TokenType.Reset,
			uid: user.uid
		})

		const info = await transport.sendMail({
			from: `"IBCornelsen" <info@online-energieausweis.org>`,
			to: input.email,
			subject: "Zurücksetzen ihres Passworts",
			text: `Hallo ${user.vorname},

sie haben eine Anfrage zum Zurücksetzen ihres Passworts gestellt. Klicken sie auf den folgenden Link, um ein neues Passwort festzulegen:

https://ibcornelsen.de/auth/passwort-zuruecksetzen?t=${resetToken}

Dieser Link ist für die nächsten 15 Minuten gültig. Falls du diese Anfrage nicht gestellt hast, kannst du diese E-Mail ignorieren - dein Passwort bleibt unverändert.

Falls du Hilfe benötigst, kontaktiere uns unter info@online-energieausweis.org.

Viele Grüße,
IBCornelsen`
		})

		if (info.rejected.length > 0) {
			throw new APIError({
				code: "INTERNAL_SERVER_ERROR",
				message: "Etwas ist schiefgelaufen, bitte versuchen sie es erneut."
			})
		}
	},
})

export const POST = defineApiRoute({
	input: z.object({
		token: z.string(),
		passwort: z.string()
	}),
	output: z.void(),
	async fetch(input, context, transfer) {
		const decoded = decodeToken(input.token);

		if (!decoded.exp || decoded.exp < Date.now() || decoded.typ !== TokenType.Reset || !decoded.uid) {
			throw new APIError({
				code: "BAD_REQUEST",
				message: "Der von ihnen benutzte Token ist nicht mehr gültig."
			})
		}

		const user = await prisma.benutzer.findUnique({
			where: {
				uid: decoded.uid
			}
		})

		if (!user) {
			throw new APIError({
				code: "NOT_FOUND",
				message: "Kein Benutzer passt zu dem genutzten Token."
			})
		}

		const hashed = hashPassword(input.passwort)

		await prisma.benutzer.update({
			where: {
				uid: decoded.uid
			},
			data: {
				passwort: hashed
			}
		})

		const transport = nodemailer.createTransport({
			host: "smtp.ionos.de",
			port: 465,
			secure: true,
			auth: {
				user: "info@online-energieausweis.org",
				pass: "Katendeich5a2024!"
			}
		})

		const info = await transport.sendMail({
			from: `"IBCornelsen" <info@online-energieausweis.org>`,
			to: user.email,
			subject: "Ihr Passwort wurde erfolgreich zurückgesetzt",
			text: `Hallo ${user.vorname},

Ihr Passwort wurde erfolgreich zurückgesetzt. Sie können sich jetzt mit Ihrem neuen Passwort anmelden.

Falls Sie diese Änderung nicht selbst vorgenommen haben, setzen Sie Ihr Passwort bitte sofort erneut zurück und kontaktieren Sie unseren Support unter info@online-energieausweis.org.

Viele Grüße,
IBCornelsen`
		})
	},
})