import type { EmailMessage } from "@kk/api/email-queue";
import { dispatchEmailMessage } from "@kk/api/email-queue";
import { runSendReminders } from "@kk/api/routers/index";
import {
	createStartHandler,
	defaultStreamHandler,
} from "@tanstack/react-start/server";

// ---------------------------------------------------------------------------
// CF Workers globals — not in DOM/ES2022 lib
// ---------------------------------------------------------------------------
type MessageItem<Body> = {
	body: Body;
	ack(): void;
	retry(): void;
};
type MessageBatch<Body> = { messages: Array<MessageItem<Body>> };
type ExecutionContext = { waitUntil(promise: Promise<unknown>): void };

// ---------------------------------------------------------------------------
// Minimal CF Queue binding shape
// ---------------------------------------------------------------------------
type EmailQueue = {
	send(
		message: EmailMessage,
		options?: { contentType?: string },
	): Promise<void>;
	sendBatch(
		messages: Array<{ body: EmailMessage }>,
		options?: { contentType?: string },
	): Promise<void>;
};

type Env = {
	EMAIL_QUEUE?: EmailQueue;
};

const startHandler = createStartHandler(defaultStreamHandler);

export default {
	fetch(request: Request, env: Env) {
		// Cast required: TanStack Start's BaseContext doesn't know about emailQueue,
		// but it threads the value through to route handlers via requestContext.
		return startHandler(request, {
			context: { emailQueue: env.EMAIL_QUEUE } as Record<string, unknown>,
		});
	},

	async queue(
		batch: MessageBatch<EmailMessage>,
		_env: Env,
		_ctx: ExecutionContext,
	) {
		for (const msg of batch.messages) {
			try {
				await dispatchEmailMessage(msg.body);
				msg.ack();
			} catch (err) {
				console.error("Queue dispatch failed:", err);
				msg.retry();
			}
		}
	},

	async scheduled(
		_event: { cron: string; scheduledTime: number },
		env: Env,
		ctx: ExecutionContext,
	) {
		ctx.waitUntil(runSendReminders(env.EMAIL_QUEUE));
	},
};
