import { randomBytes, scryptSync } from "node:crypto";
import { db } from "@kk/db";
import * as schema from "@kk/db/schema/auth";
import { env } from "@kk/env/server";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { tanstackStartCookies } from "better-auth/tanstack-start";
import nodemailer from "nodemailer";

const _smtpFrom = env.SMTP_FROM ?? "Kunstenkamp <info@kunstenkamp.be>";

let _transport: nodemailer.Transporter | null | undefined;
function getTransport(): nodemailer.Transporter | null {
	if (_transport !== undefined) return _transport;
	if (!env.SMTP_HOST || !env.SMTP_USER || !env.SMTP_PASS) {
		_transport = null;
		return null;
	}
	_transport = nodemailer.createTransport({
		host: env.SMTP_HOST,
		port: env.SMTP_PORT,
		secure: env.SMTP_PORT === 465,
		auth: { user: env.SMTP_USER, pass: env.SMTP_PASS },
	});
	return _transport;
}

async function sendPasswordResetEmail(to: string, resetUrl: string) {
	const transport = getTransport();
	if (!transport) {
		console.warn("SMTP not configured — skipping password reset email");
		return;
	}
	const html = `<!DOCTYPE html>
<html lang="nl">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Wachtwoord opnieuw instellen</title>
</head>
<body style="margin:0;padding:0;background:#f4f4f5;font-family:sans-serif;">
  <table width="100%" cellpadding="0" cellspacing="0" style="background:#f4f4f5;padding:40px 0;">
    <tr>
      <td align="center">
        <table width="600" cellpadding="0" cellspacing="0" style="background:#214e51;border-radius:4px;overflow:hidden;">
          <tr>
            <td style="padding:40px 48px 32px;">
              <p style="margin:0;font-size:13px;color:rgba(255,255,255,0.5);letter-spacing:0.08em;text-transform:uppercase;">Kunstenkamp</p>
              <h1 style="margin:12px 0 0;font-size:28px;color:#ffffff;font-weight:700;">Wachtwoord opnieuw instellen</h1>
            </td>
          </tr>
          <tr>
            <td style="padding:0 48px 32px;">
              <p style="margin:0 0 16px;font-size:16px;color:rgba(255,255,255,0.85);line-height:1.6;">
                We hebben een aanvraag ontvangen om het wachtwoord van je Kunstenkamp-account opnieuw in te stellen.
              </p>
              <p style="margin:0 0 24px;font-size:16px;color:rgba(255,255,255,0.85);line-height:1.6;">
                Klik op de knop hieronder om een nieuw wachtwoord in te stellen. Deze link is <strong style="color:#ffffff;">1 uur geldig</strong>.
              </p>
              <table cellpadding="0" cellspacing="0">
                <tr>
                  <td style="border-radius:2px;background:#ffffff;">
                    <a href="${resetUrl}" style="display:inline-block;padding:14px 32px;font-size:16px;font-weight:600;color:#214e51;text-decoration:none;">
                      Stel wachtwoord in
                    </a>
                  </td>
                </tr>
              </table>
              <p style="margin:16px 0 0;font-size:13px;color:rgba(255,255,255,0.4);">
                Of kopieer deze link: <span style="color:rgba(255,255,255,0.6);">${resetUrl}</span>
              </p>
              <p style="margin:24px 0 0;font-size:14px;color:rgba(255,255,255,0.5);line-height:1.6;">
                Heb je dit niet aangevraagd? Dan hoef je niets te doen — je wachtwoord blijft ongewijzigd.
              </p>
            </td>
          </tr>
          <tr>
            <td style="padding:24px 48px;border-top:1px solid rgba(255,255,255,0.1);">
              <p style="margin:0;font-size:13px;color:rgba(255,255,255,0.4);line-height:1.6;">
                Vragen? Mail ons op <a href="mailto:info@kunstenkamp.be" style="color:rgba(255,255,255,0.6);">info@kunstenkamp.be</a><br/>
                Kunstenkamp vzw — Een initiatief voor en door kunstenaars.
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>`;
	await transport.sendMail({
		from: _smtpFrom,
		to,
		subject: "Wachtwoord opnieuw instellen — Kunstenkamp",
		html,
	});
}

export const auth = betterAuth({
	database: drizzleAdapter(db, {
		provider: "sqlite",

		schema: schema,
	}),
	trustedOrigins: [
		env.CORS_ORIGIN,
		"http://localhost:3000",
		"http://localhost:3001",
	],
	emailAndPassword: {
		enabled: true,
		// Use Cloudflare's native scrypt via node:crypto for better performance
		// This avoids CPU time limit errors on Cloudflare Workers
		password: {
			hash: async (password) => {
				const salt = randomBytes(16).toString("hex");
				const hash = scryptSync(password, salt, 64).toString("hex");
				return `${salt}:${hash}`;
			},
			verify: async ({ hash, password }) => {
				const [salt, key] = hash.split(":");
				if (!salt || !key) return false;
				const keyBuffer = Buffer.from(key, "hex");
				const hashBuffer = scryptSync(password, salt, 64);
				return keyBuffer.equals(hashBuffer);
			},
		},
		sendResetPassword: async ({ user, url }) => {
			await sendPasswordResetEmail(user.email, url);
		},
	},
	user: {
		additionalFields: {
			role: {
				type: "string",
				input: false,
			},
		},
	},
	plugins: [tanstackStartCookies()],
});
