import type { RequestHandler } from './$types';
import { db } from '$lib/server/db';
import { dailyVerses } from '$lib/server/db/schema';
import { desc } from 'drizzle-orm';

// Helper: Escape XML special characters
function escapeXml(text: string): string {
	return text
		.replace(/&/g, '&amp;')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;')
		.replace(/"/g, '&quot;')
		.replace(/'/g, '&apos;');
}

// Helper: Format YYYY-MM-DD to RFC 822 date string
function formatRFC822(dateStr: string): string {
	// Parse date in America/New_York timezone (EST/EDT)
	// Assuming midnight ET
	const date = new Date(dateStr + 'T00:00:00-05:00');
	return date.toUTCString().replace('GMT', 'EST');
}

// Helper: Format YYYY-MM-DD to readable date
function formatReadableDate(dateStr: string): string {
	const date = new Date(dateStr + 'T00:00:00');
	return date.toLocaleDateString('en-US', {
		month: 'long',
		day: 'numeric',
		year: 'numeric',
		timeZone: 'America/New_York'
	});
}

// Helper: Format verse text (VerseDisplay + Imposter unbalanced punctuation handling)
function formatVerseText(text: string): string {
	let formatted = text;

	// Handle unbalanced opening/closing punctuation (from Imposter.svelte)
	const pairs: [string, string][] = [
		['(', ')'],
		['[', ']'],
		['{', '}'],
		['"', '"'],
		["'", "'"],
		['\u201C', '\u201D'], // " "
		['\u2018', '\u2019'] // ' '
	];

	// Check if text starts with opening punctuation without closing
	for (const [open, close] of pairs) {
		if (formatted.startsWith(open) && !formatted.includes(close)) {
			formatted += '...' + close;
			break;
		}
	}

	// Check if text ends with closing punctuation without opening
	for (const [open, close] of pairs) {
		if (formatted.endsWith(close) && !formatted.includes(open)) {
			formatted = open + '...' + formatted;
			break;
		}
	}

	// Check if text contains unbalanced opening quotes (not at start) without closing
	for (const [open, close] of pairs) {
		const openCount = (formatted.match(new RegExp(`\\${open}`, 'g')) || []).length;
		const closeCount = (formatted.match(new RegExp(`\\${close}`, 'g')) || []).length;
		if (openCount > closeCount) {
			formatted += close;
			break;
		}
	}

	// Capitalize first letter if lowercase (from VerseDisplay.svelte)
	formatted = formatted.replace(/^([a-z])/, (c) => c.toUpperCase());

	// Replace trailing punctuation with ellipsis
	// Preserve closing quotes/brackets that may have been added
	formatted = formatted.replace(/[,:;-—]([)\]}\"\'\u201D\u2019]*)$/, '...$1');

	return formatted;
}

export const GET: RequestHandler = async ({ request }) => {
	try {
		// Query last 30 verses, ordered by date descending
		const verses = await db
			.select()
			.from(dailyVerses)
			.orderBy(desc(dailyVerses.date))
			.limit(30);

		// Generate ETag based on latest verse date
		const etag = verses[0]?.date ? `"bibdle-feed-${verses[0].date}"` : '"bibdle-feed-empty"';

		// Check if client has cached version
		if (request.headers.get('If-None-Match') === etag) {
			return new Response(null, { status: 304 });
		}

		// Get site URL from environment or use default
		const SITE_URL = process.env.PUBLIC_SITE_URL || 'https://bibdle.com';

		// Build RSS XML
		const lastBuildDate = verses[0] ? formatRFC822(verses[0].date) : new Date().toUTCString();

		const items = verses
			.map(
				(verse) => `
    <item>
      <title>Bibdle verse for ${formatReadableDate(verse.date)}</title>
      <description>${escapeXml(formatVerseText(verse.verseText))}</description>
      <link>${SITE_URL}</link>
      <guid isPermaLink="false">bibdle-verse-${verse.date}</guid>
      <pubDate>${formatRFC822(verse.date)}</pubDate>
    </item>`
			)
			.join('');

		const xml = `<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Bibdle</title>
    <link>${SITE_URL}</link>
    <description>A daily Bible game</description>
    <language>en-us</language>
    <lastBuildDate>${lastBuildDate}</lastBuildDate>
    <ttl>720</ttl>${items}
  </channel>
</rss>`;

		return new Response(xml, {
			headers: {
				'Content-Type': 'application/rss+xml; charset=utf-8',
				'Cache-Control': 'public, max-age=3600, s-maxage=3600',
				ETag: etag
			}
		});
	} catch (error) {
		console.error('RSS feed generation error:', error);
		return new Response('Internal Server Error', { status: 500 });
	}
};
