/**
 * ElevenLabs prompt synthesizer for the SF Twilio IVR.
 *
 * Purpose: keep spoken IVR prompts outside Twilio's built-in TTS so the voice
 * can be swapped to ElevenLabs without changing the call-control webhook.
 *
 * Consumer: the Twilio IVR route requests this endpoint when ElevenLabs prompt
 * synthesis is configured.
 */

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

function noStoreHeaders(): HeadersInit {
	return {
		"Cache-Control": "no-store",
	};
}

function getElevenLabsConfig(): {
	apiKey: string;
	voiceId: string;
	modelId: string;
} | null {
	const env = process.env;
	const apiKey = env.ELEVENLABS_API_KEY?.trim() ?? "";
	const voiceId = env.ELEVENLABS_VOICE_ID?.trim() ?? "";
	if (!apiKey || !voiceId) return null;
	return {
		apiKey,
		modelId: env.ELEVENLABS_MODEL_ID?.trim() || "eleven_flash_v2_5",
		voiceId,
	};
}

function getPromptText(request: Request): string | null {
	const url = new URL(request.url);
	const text = url.searchParams.get("text")?.trim();
	return text ? text : null;
}

/**
 * Synthesize a spoken prompt with ElevenLabs and return audio bytes.
 *
 * Purpose: feed Twilio `<Play>` with a consistent prompt voice when the IVR is
 * configured to use ElevenLabs.
 *
 * Consumer: Twilio IVR TwiML route as an audio asset source.
 */
export async function GET(request: Request): Promise<Response> {
	const config = getElevenLabsConfig();
	const text = getPromptText(request);

	if (!config || !text) {
		return new Response("ElevenLabs prompt synthesis is not configured.", {
			status: 503,
			headers: noStoreHeaders(),
		});
	}

	const response = await fetch(
		`https://api.elevenlabs.io/v1/text-to-speech/${encodeURIComponent(config.voiceId)}?output_format=mp3_44100_128`,
		{
			method: "POST",
			headers: {
				"Content-Type": "application/json",
				"xi-api-key": config.apiKey,
				Accept: "audio/mpeg",
			},
			body: JSON.stringify({
				text,
				model_id: config.modelId,
			}),
		},
	);

	if (!response.ok) {
		const message = await response.text().catch(() => "");
		return new Response(message || "ElevenLabs prompt synthesis failed.", {
			status: response.status,
			headers: noStoreHeaders(),
		});
	}

	return new Response(response.body, {
		status: 200,
		headers: {
			"Cache-Control": "no-store",
			"Content-Type": response.headers.get("content-type") || "audio/mpeg",
		},
	});
}
