// IndexNow submission helper.
//
// One POST to https://api.indexnow.org/indexnow notifies Bing, Yandex and
// Seznam in one call (IndexNow is a shared protocol). The key file lives at
// public/<key>.txt and must be reachable at https://www.elevaseo.com/<key>.txt
// for crawlers to verify ownership before honouring the submission.

const INDEXNOW_HOST = "www.elevaseo.com";
const INDEXNOW_KEY = "540b2517d9dfd97043c9ee3ce5273c69";
const INDEXNOW_KEY_LOCATION = `https://${INDEXNOW_HOST}/${INDEXNOW_KEY}.txt`;
const INDEXNOW_ENDPOINT = "https://api.indexnow.org/indexnow";

// IndexNow spec hard limit per batch.
const MAX_URLS_PER_BATCH = 10_000;
const ALLOWED_HOST_PREFIX = `https://${INDEXNOW_HOST}/`;

export interface IndexNowBatchResult {
  batchSize: number;
  ok: boolean;
  status: number;
  statusText: string;
}

export interface IndexNowResult {
  batches: IndexNowBatchResult[];
  ok: boolean;
  rejectedCount: number;
  submittedCount: number;
}

/**
 * Submit one or more URLs to IndexNow for instant crawl notification.
 *
 * Chunks into 10 000-URL batches (IndexNow spec maximum) and validates that
 * every URL belongs to {@link INDEXNOW_HOST}. IndexNow rejects the entire
 * batch if even one URL is off-host, so any URL that does not match is
 * filtered out and counted as `rejectedCount`.
 *
 * @param urls Array of absolute URLs on the configured host. URLs must match
 *             the canonical form exactly (no trailing-slash drift, no 301).
 */
export async function submitToIndexNow(
  urls: string[]
): Promise<IndexNowResult> {
  const accepted: string[] = [];
  let rejectedCount = 0;
  for (const url of urls) {
    if (url.startsWith(ALLOWED_HOST_PREFIX)) {
      accepted.push(url);
    } else {
      rejectedCount += 1;
    }
  }

  if (accepted.length === 0) {
    return { ok: true, submittedCount: 0, rejectedCount, batches: [] };
  }

  const batches: IndexNowBatchResult[] = [];
  let submittedCount = 0;
  let allOk = true;

  for (let i = 0; i < accepted.length; i += MAX_URLS_PER_BATCH) {
    const batch = accepted.slice(i, i + MAX_URLS_PER_BATCH);
    const response = await fetch(INDEXNOW_ENDPOINT, {
      method: "POST",
      headers: { "Content-Type": "application/json; charset=utf-8" },
      body: JSON.stringify({
        host: INDEXNOW_HOST,
        key: INDEXNOW_KEY,
        keyLocation: INDEXNOW_KEY_LOCATION,
        urlList: batch,
      }),
    });

    batches.push({
      ok: response.ok,
      status: response.status,
      statusText: response.statusText,
      batchSize: batch.length,
    });

    if (response.ok) {
      submittedCount += batch.length;
    } else {
      allOk = false;
    }
  }

  return { ok: allOk, submittedCount, rejectedCount, batches };
}
