/**
 * Email queue types and dispatcher.
 *
 * All email sends are modelled as a discriminated union so the Cloudflare Queue
 * consumer can pattern-match on `msg.type` and call the right send*Email().
 *
 * The `Queue<EmailMessage>` type used in context.ts / server.ts refers to the
 * CF runtime binding type (`import type { Queue } from "@cloudflare/workers-types"`).
 */

import {
	sendCancellationEmail,
	sendConfirmationEmail,
	sendPaymentConfirmationEmail,
	sendPaymentReminderEmail,
	sendReminder24hEmail,
	sendReminderEmail,
	sendSubscriptionConfirmationEmail,
	sendUpdateEmail,
} from "./email";
import { sendDeductionEmail } from "./lib/drinkkaart-email";

// ---------------------------------------------------------------------------
// Message types — one variant per send*Email function
// ---------------------------------------------------------------------------

export type ConfirmationMessage = {
	type: "registrationConfirmation";
	to: string;
	firstName: string;
	managementToken: string;
	wantsToPerform: boolean;
	artForm?: string | null;
	giftAmount?: number;
	drinkCardValue?: number;
	signupUrl?: string;
};

export type UpdateMessage = {
	type: "updateConfirmation";
	to: string;
	firstName: string;
	managementToken: string;
	wantsToPerform: boolean;
	artForm?: string | null;
	giftAmount?: number;
	drinkCardValue?: number;
};

export type CancellationMessage = {
	type: "cancellation";
	to: string;
	firstName: string;
};

export type SubscriptionConfirmationMessage = {
	type: "subscriptionConfirmation";
	to: string;
};

export type Reminder24hMessage = {
	type: "reminder24h";
	to: string;
	firstName?: string | null;
};

export type Reminder1hMessage = {
	type: "reminder1h";
	to: string;
	firstName?: string | null;
};

export type PaymentReminderMessage = {
	type: "paymentReminder";
	to: string;
	firstName: string;
	managementToken: string;
	drinkCardValue?: number;
	giftAmount?: number;
};

export type PaymentConfirmationMessage = {
	type: "paymentConfirmation";
	to: string;
	firstName: string;
	managementToken: string;
	drinkCardValue?: number;
	giftAmount?: number;
};

export type DeductionMessage = {
	type: "deduction";
	to: string;
	firstName: string;
	amountCents: number;
	newBalanceCents: number;
};

export type EmailMessage =
	| ConfirmationMessage
	| UpdateMessage
	| CancellationMessage
	| SubscriptionConfirmationMessage
	| Reminder24hMessage
	| Reminder1hMessage
	| PaymentReminderMessage
	| PaymentConfirmationMessage
	| DeductionMessage;

// ---------------------------------------------------------------------------
// Consumer-side dispatcher — called once per queue message
// ---------------------------------------------------------------------------

export async function dispatchEmailMessage(msg: EmailMessage): Promise<void> {
	switch (msg.type) {
		case "registrationConfirmation":
			await sendConfirmationEmail(msg);
			break;
		case "updateConfirmation":
			await sendUpdateEmail(msg);
			break;
		case "cancellation":
			await sendCancellationEmail(msg);
			break;
		case "subscriptionConfirmation":
			await sendSubscriptionConfirmationEmail({ to: msg.to });
			break;
		case "reminder24h":
			await sendReminder24hEmail(msg);
			break;
		case "reminder1h":
			await sendReminderEmail(msg);
			break;
		case "paymentReminder":
			await sendPaymentReminderEmail(msg);
			break;
		case "paymentConfirmation":
			await sendPaymentConfirmationEmail(msg);
			break;
		case "deduction":
			await sendDeductionEmail(msg);
			break;
		default:
			// Exhaustiveness check — TypeScript will catch unhandled variants at compile time
			msg satisfies never;
	}
}
