// IndexNow: уведомить Yandex/Bing о новых/обновлённых URL.
// Запускается после деплоя из CI или вручную:
//   node scripts/indexnow.js
//
// IndexNow ключ хранится в файле public/<key>.txt — он должен быть доступен по
// тому же URL что и сайт, чтобы поисковики могли подтвердить ownership.
//
// Источник URL (по приоритету):
//   1) dist/sitemap-index.xml (Astro @astrojs/sitemap) + входящие sitemap-*.xml
//   2) dist/sitemap.txt / dist/sitemap.xml
//   3) fetch с прод-сайта: https://pushkinohistory.ru/sitemap-index.xml
//      (для запуска из CI после удалённого деплоя — без локального build)

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const root = path.resolve(__dirname, '..');
const BASE = 'https://pushkinohistory.ru';
const HOST = 'pushkinohistory.ru';
const KEY = '9018cf11050b4f379b8cec01ae3239bb';

// На случай если кто-то удалит файл — пересоздадим автоматически.
const keyFile = path.join(root, 'public', `${KEY}.txt`);
if (!fs.existsSync(keyFile)) {
  fs.writeFileSync(keyFile, KEY, 'utf-8');
  console.log(`created key file: public/${KEY}.txt`);
}

function extractLocs(xml) {
  return [...xml.matchAll(/<loc>([^<]+)<\/loc>/g)].map((m) => m[1].trim());
}

let urls = [];
const distDir = path.join(root, 'dist');
const sitemapIndex = path.join(distDir, 'sitemap-index.xml');
const sitemapTxt = path.join(distDir, 'sitemap.txt');
const fallbackTxt = path.join(distDir, 'sitemap.xml');

if (fs.existsSync(sitemapIndex)) {
  const idx = fs.readFileSync(sitemapIndex, 'utf-8');
  const subs = extractLocs(idx);
  for (const sub of subs) {
    // sub — абсолютный URL вида https://pushkinohistory.ru/sitemap-0.xml
    const fname = sub.split('/').pop();
    const localPath = path.join(distDir, fname);
    if (fs.existsSync(localPath)) {
      const subXml = fs.readFileSync(localPath, 'utf-8');
      urls.push(...extractLocs(subXml));
    } else {
      console.warn(`  sub-sitemap not found locally: ${localPath}`);
    }
  }
} else if (fs.existsSync(sitemapTxt)) {
  urls = fs
    .readFileSync(sitemapTxt, 'utf-8')
    .split(/\r?\n/)
    .map((l) => l.trim())
    .filter((l) => l.startsWith('http'));
} else if (fs.existsSync(fallbackTxt)) {
  const xml = fs.readFileSync(fallbackTxt, 'utf-8');
  urls = extractLocs(xml);
} else {
  console.log('no local sitemap found, fetching from production…');
  try {
    const idxResp = await fetch(`${BASE}/sitemap-index.xml`);
    if (!idxResp.ok) throw new Error(`HTTP ${idxResp.status}`);
    const idxXml = await idxResp.text();
    const subs = extractLocs(idxXml);
    for (const sub of subs) {
      const subResp = await fetch(sub);
      if (!subResp.ok) {
        console.warn(`  ${sub}: HTTP ${subResp.status}`);
        continue;
      }
      const subXml = await subResp.text();
      urls.push(...extractLocs(subXml));
    }
  } catch (e) {
    console.error(`failed to fetch sitemap from ${BASE}: ${e.message}`);
    process.exit(1);
  }
}

// Дедупликация и фильтрация на всякий случай.
urls = [...new Set(urls)].filter((u) => u.startsWith(BASE));

if (urls.length === 0) {
  console.error('no URLs collected — nothing to submit');
  process.exit(1);
}

console.log(`Submitting ${urls.length} URLs to IndexNow…`);

const payload = {
  host: HOST,
  key: KEY,
  keyLocation: `${BASE}/${KEY}.txt`,
  urlList: urls,
};

async function submit(endpoint) {
  try {
    const r = await fetch(endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json; charset=utf-8' },
      body: JSON.stringify(payload),
    });
    console.log(`  ${endpoint}: HTTP ${r.status}`);
  } catch (e) {
    console.error(`  ${endpoint}: ${e.message}`);
  }
}

await Promise.all([
  submit('https://yandex.com/indexnow'),
  submit('https://api.indexnow.org/indexnow'),
]);
