/* Vercel Serverless Function: sitemap.xml dan robots.txt dinamis dari Firestore.
   Selalu terbaru. Novel atau chapter baru langsung ikut, tanpa update manual.
   Dipakai lewat rewrite di vercel.json:
     /sitemap.xml            -> daftar sitemap (index)
     /sitemap-main.xml       -> halaman utama, kategori, dan semua novel
     /sitemap-novel-SLUG.xml -> semua chapter satu novel
     /robots.txt             -> aturan crawler + alamat sitemap */
const PROJECT = 'sjshwihdiwb';
const KEY = 'AIzaSyD__0-LFKB___JnwwWyQ-pnLoUNCH6TTfc';   // web API key Firebase (memang publik)
const DOCS = `https://firestore.googleapis.com/v1/projects/${PROJECT}/databases/(default)/documents`;
const PAGES = [['/', 'weekly', '1.0'], ['/home', 'daily', '0.9'], ['/search', 'weekly', '0.6'], ['/c/project', 'daily', '0.7'], ['/c/original', 'daily', '0.7'], ['/c/korean', 'daily', '0.7'], ['/c/china', 'daily', '0.7'], ['/c/japan', 'daily', '0.7'], ['/documenter', 'monthly', '0.4'], ['/support', 'monthly', '0.3']];

const esc = s => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
const val = (d, k) => { const v = d.fields && d.fields[k]; return v ? (v.stringValue ?? v.integerValue ?? v.doubleValue ?? v.timestampValue ?? '') : ''; };
const day = t => (t ? String(t).slice(0, 10) : '');

async function list(path, mask, ref, max = 20000) {
  const out = []; let token = '';
  do {
    const url = `${DOCS}/${path}?pageSize=300&key=${KEY}${mask.map(m => '&mask.fieldPaths=' + m).join('')}${token ? '&pageToken=' + encodeURIComponent(token) : ''}`;
    const r = await fetch(url, { headers: { Referer: ref + '/' } });   // aman juga kalau API key dibatasi per domain
    if (!r.ok) throw new Error('Firestore ' + r.status);
    const j = await r.json();
    out.push(...(j.documents || [])); token = j.nextPageToken || '';
  } while (token && out.length < max);
  return out;
}
const idOf = d => d.name.split('/').pop();
const urlset = (base, rows) => `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${rows.map(r => `<url><loc>${esc(base + r.p)}</loc>${r.m ? `<lastmod>${r.m}</lastmod>` : ''}<changefreq>${r.c}</changefreq><priority>${r.pr}</priority></url>`).join('\n')}\n</urlset>\n`;
const sorted = a => a.sort((x, y) => String(val(y, 'updatedAt')).localeCompare(String(val(x, 'updatedAt'))));

module.exports = async (req, res) => {
  const host = req.headers['x-forwarded-host'] || req.headers.host, base = `https://${host}`, q = req.query || {};
  try {
    if (q.t === 'robots') {
      res.setHeader('Content-Type', 'text/plain; charset=utf-8'); res.setHeader('Cache-Control', 'public, s-maxage=86400');
      return res.status(200).send(`User-agent: *\nAllow: /\nDisallow: /settings\nDisallow: /chat\nDisallow: /studio\nDisallow: /login\nDisallow: /register\nDisallow: /forgot\nDisallow: /verify\nDisallow: /bookmarks\n\nSitemap: ${base}/sitemap.xml\n`);
    }
    res.setHeader('Content-Type', 'application/xml; charset=utf-8');
    res.setHeader('Cache-Control', 'public, s-maxage=3600, stale-while-revalidate=86400');

    if (q.n) {   // chapter satu novel
      const slug = String(q.n);
      if (!/^[A-Za-z0-9_-]{1,100}$/.test(slug)) return res.status(404).send('not found');
      const ch = await list(`novels/${slug}/chapters`, ['number', 'updatedAt'], base);
      ch.sort((a, b) => Number(val(a, 'number')) - Number(val(b, 'number')));
      return res.status(200).send(urlset(base, ch.map(d => ({ p: `/${encodeURIComponent(slug)}/${val(d, 'number') || idOf(d)}`, m: day(val(d, 'updatedAt')), c: 'monthly', pr: '0.5' }))));
    }

    const novels = sorted(await list('novels', ['updatedAt', 'chapterCount'], base));
    if (q.t === 'main') {
      const rows = PAGES.map(([p, c, pr]) => ({ p, c, pr }));
      novels.forEach(d => rows.push({ p: '/' + encodeURIComponent(idOf(d)), m: day(val(d, 'updatedAt')), c: 'daily', pr: '0.8' }));
      return res.status(200).send(urlset(base, rows));
    }
    // sitemap index
    const items = [`<sitemap><loc>${esc(base)}/sitemap-main.xml</loc>${novels[0] ? `<lastmod>${day(val(novels[0], 'updatedAt'))}</lastmod>` : ''}</sitemap>`];
    novels.filter(d => Number(val(d, 'chapterCount')) > 0).forEach(d => items.push(`<sitemap><loc>${esc(base)}/sitemap-novel-${esc(encodeURIComponent(idOf(d)))}.xml</loc>${val(d, 'updatedAt') ? `<lastmod>${day(val(d, 'updatedAt'))}</lastmod>` : ''}</sitemap>`));
    return res.status(200).send(`<?xml version="1.0" encoding="UTF-8"?>\n<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${items.join('\n')}\n</sitemapindex>\n`);
  } catch (e) {
    res.setHeader('Cache-Control', 'no-store');
    return res.status(500).send('sitemap error');
  }
};
