export interface HrefLangLink {
  hreflang: string
  href: string
}

export interface UrlEntry {
  loc: string
  lastmod?: string
  hrefLangs?: HrefLangLink[]
}

export interface SitemapIndexChild {
  loc: string
  lastmod?: string
}

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

export function buildUrlEntry(
  loc: string,
  options: { hrefLangs?: HrefLangLink[]; lastmod?: string } = {},
): UrlEntry {
  return {
    loc,
    ...(options.lastmod ? { lastmod: options.lastmod } : {}),
    ...(options.hrefLangs?.length ? { hrefLangs: options.hrefLangs } : {}),
  }
}

function renderHrefLangAlternates(links: HrefLangLink[]): string {
  return links
    .map(
      (link) =>
        `    <xhtml:link rel="alternate" hreflang="${escapeXml(link.hreflang)}" href="${escapeXml(link.href)}"/>`,
    )
    .join('\n')
}

function renderUrlNode(entry: UrlEntry): string {
  const lines = [`  <url>`, `    <loc>${escapeXml(entry.loc)}</loc>`]
  if (entry.lastmod) lines.push(`    <lastmod>${escapeXml(entry.lastmod)}</lastmod>`)
  if (entry.hrefLangs?.length) lines.push(renderHrefLangAlternates(entry.hrefLangs))
  lines.push('  </url>')
  return lines.join('\n')
}

export function renderUrlSet(urls: UrlEntry[]): string {
  const body = urls.map(renderUrlNode).join('\n')
  return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">\n${body}\n</urlset>\n`
}

export function renderSitemapIndex(children: SitemapIndexChild[]): string {
  const body = children
    .map((child) => {
      const lines = [`  <sitemap>`, `    <loc>${escapeXml(child.loc)}</loc>`]
      if (child.lastmod) lines.push(`    <lastmod>${escapeXml(child.lastmod)}</lastmod>`)
      lines.push('  </sitemap>')
      return lines.join('\n')
    })
    .join('\n')
  return `<?xml version="1.0" encoding="UTF-8"?>\n<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${body}\n</sitemapindex>\n`
}
