/**
 * Email checklist routes — mounted at top level to bypass space auth middleware.
 * GET  /rtasks/check/:token  — verify HMAC, toggle AC, render page
 * POST /api/rtasks/send      — build + send checklist email
 */

import { Hono } from "hono";
import { checklistConfig } from "./lib/checklist-config";
import { createToken, verifyToken } from "./lib/token";
import { readTask, toggleAC } from "./lib/backlog";
import { renderEmailHTML, renderWebPage, renderError } from "./lib/render";

export const checklistCheckRoutes = new Hono();
export const checklistApiRoutes = new Hono();

// ── GET /rtasks/check/:token ──
checklistCheckRoutes.get("/:token", async (c) => {
	const token = c.req.param("token");

	let verified;
	try {
		verified = await verifyToken(token);
	} catch (err) {
		const message = err instanceof Error ? err.message : "Unknown error";
		const title = message === "Token expired" ? "Link Expired" : "Invalid Link";
		const body = message === "Token expired"
			? "This checklist link has expired. Request a new checklist email."
			: "This link is not valid. It may have been corrupted.";
		return c.html(renderError(title, body), title === "Link Expired" ? 410 : 400);
	}

	try {
		const result = await toggleAC(verified.repo, verified.taskId, verified.acIndex);

		const tokens = new Map<number, string>();
		for (const ac of result.criteria) {
			tokens.set(ac.index, await createToken(verified.repo, verified.taskId, ac.index));
		}

		return c.html(renderWebPage(result.title, verified.taskId, result.criteria, tokens, verified.acIndex, result.toggled));
	} catch (err) {
		console.error("[Tasks/checklist] Check error:", err);
		return c.html(renderError("Error", "Could not update task. Please try again."), 500);
	}
});

// ── POST /api/rtasks/send ──
checklistApiRoutes.post("/send", async (c) => {
	const authHeader = c.req.header("Authorization");
	if (!authHeader || authHeader !== `Bearer ${checklistConfig.apiKey}`) {
		return c.json({ error: "Unauthorized" }, 401);
	}

	const body = await c.req.json<{
		repo: string;
		taskId: string;
		to: string;
		subject?: string;
	}>();

	if (!body.repo || !body.taskId || !body.to) {
		return c.json({ error: "Missing required fields: repo, taskId, to" }, 400);
	}

	try {
		const task = await readTask(body.repo, body.taskId);

		const tokens = new Map<number, string>();
		for (const ac of task.criteria) {
			if (!ac.checked) {
				tokens.set(ac.index, await createToken(body.repo, body.taskId, ac.index));
			}
		}

		if (tokens.size === 0) {
			return c.json({ error: "All acceptance criteria already checked" }, 400);
		}

		const subject = body.subject || `Checklist: ${task.title}`;
		const html = renderEmailHTML(task.title, body.taskId, task.criteria, tokens);

		const nodemailer = await import("nodemailer");
		const transport = nodemailer.createTransport({
			host: process.env.SMTP_HOST || "mailcowdockerized-postfix-mailcow-1",
			port: Number(process.env.SMTP_PORT) || 587,
			secure: false,
			auth: {
				user: process.env.SMTP_USER || "noreply@rmail.online",
				pass: process.env.SMTP_PASS,
			},
			tls: { rejectUnauthorized: false },
		});

		const result = await transport.sendMail({
			from: process.env.SMTP_FROM || `rTasks <${process.env.SMTP_USER || "noreply@rmail.online"}>`,
			to: body.to,
			subject,
			html,
		});

		const firstToken = tokens.values().next().value;
		const url = `${checklistConfig.baseUrl}/rtasks/check/${firstToken}`;

		return c.json({ ok: true, messageId: result.messageId, url, unchecked: tokens.size });
	} catch (err) {
		console.error("[Tasks/checklist] Send error:", err);
		const message = err instanceof Error ? err.message : "Unknown error";
		return c.json({ error: message }, 500);
	}
});
