import type { APIRoute } from 'astro'

import { api, DEFAULT_SITE_SETTINGS } from '../lib/api/client'

export const prerender = false

function escapeXml(value: string) {
  return value
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&apos;')
}

function ensureAbsoluteUrl(baseUrl: string, path: string) {
  const normalizedBase = baseUrl.replace(/\/$/, '')
  return `${normalizedBase}${path.startsWith('/') ? path : `/${path}`}`
}

export const GET: APIRoute = async ({ request }) => {
  const fallbackOrigin = new URL(request.url).origin
  let siteSettings = DEFAULT_SITE_SETTINGS
  let posts = await api.getRawPosts().catch(() => [])

  try {
    siteSettings = await api.getSiteSettings()
  } catch {
    siteSettings = DEFAULT_SITE_SETTINGS
  }

  const siteUrl = (siteSettings.siteUrl || fallbackOrigin).replace(/\/$/, '')
  const feedTitle = siteSettings.siteTitle || siteSettings.siteName || 'Blog RSS Feed'
  const feedDescription =
    siteSettings.siteDescription || `${siteSettings.siteName || 'Blog'} RSS Feed`

  const sortedPosts = [...posts]
    .filter((post) => !post.noindex)
    .sort((left, right) => right.created_at.localeCompare(left.created_at))
    .slice(0, 60)

  const itemsXml = sortedPosts
    .map((post) => {
      const title = escapeXml(post.title || 'Untitled')
      const description = escapeXml(post.description || '')
      const link = ensureAbsoluteUrl(siteUrl, `/articles/${post.slug}`)
      const guid = escapeXml(link)
      const pubDate = new Date(post.updated_at || post.created_at).toUTCString()

      return `
    <item>
      <title>${title}</title>
      <link>${escapeXml(link)}</link>
      <guid isPermaLink="true">${guid}</guid>
      <description>${description}</description>
      <pubDate>${escapeXml(pubDate)}</pubDate>
    </item>`
    })
    .join('')

  const xml = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>${escapeXml(feedTitle)}</title>
    <link>${escapeXml(siteUrl)}</link>
    <description>${escapeXml(feedDescription)}</description>
    <language>zh-CN</language>
    <lastBuildDate>${escapeXml(new Date().toUTCString())}</lastBuildDate>${itemsXml}
  </channel>
</rss>`

  return new Response(xml, {
    headers: {
      'Content-Type': 'application/rss+xml; charset=utf-8',
      'Cache-Control': 'public, max-age=600',
    },
  })
}
