import type { MetadataRoute } from "next";
import { api } from "@/lib/api";

const BASE = process.env.NEXT_PUBLIC_SITE_URL ?? "https://alqove.com";

export const dynamic = "force-dynamic";

/** Maximum number of item entries to include */
const MAX_ITEM_ENTRIES = 50_000;

/** Each storefront costs one API call, so cap the fan-out. */
const MAX_STOREFRONT_ENTRIES = 500;

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const entries: MetadataRoute.Sitemap = [
    { url: `${BASE}/`, changeFrequency: "daily", priority: 1 },
    { url: `${BASE}/items`, changeFrequency: "daily", priority: 0.9 },
  ];

  // --- Categories ---
  try {
    const catRes = await api.categories.list();
    const cats = catRes.data ?? [];

    function addCategory(cat: { slug: string; children?: { slug: string; children?: unknown[] }[] }) {
      entries.push({
        url: `${BASE}/items?category_slug=${cat.slug}`,
        changeFrequency: "weekly",
        priority: 0.7,
      });
      if (cat.children) {
        for (const child of cat.children) {
          addCategory(child as typeof cat);
        }
      }
    }

    for (const cat of cats) {
      addCategory(cat);
    }
  } catch {
    // fail-open: sitemap still serves base entries
  }

  // --- Stores ---
  try {
    const storeRes = await api.stores.listPublic();
    const stores = storeRes.data ?? [];

    for (const store of stores) {
      entries.push({
        url: `${BASE}/stores/${store.id}`,
        changeFrequency: "weekly",
        priority: 0.6,
      });
    }

    // --- Storefronts ---
    // A store's own landing page and its sub-pages. The shell request 404s for
    // an unpublished site, which is how an unlisted storefront stays unlisted.
    // Custom domains are deliberately absent: the canonical URL is the slug
    // path, so indexing both would split the store's ranking.
    const withSlug = stores
      .filter((store): store is typeof store & { slug: string } => Boolean(store.slug))
      .slice(0, MAX_STOREFRONT_ENTRIES);

    const shells = await Promise.all(
      withSlug.map(async (store) => {
        try {
          return { slug: store.slug, shell: (await api.storefront.getShell(store.slug)).data };
        } catch {
          return null;
        }
      }),
    );

    for (const resolved of shells) {
      if (!resolved) continue;

      entries.push({
        url: `${BASE}/s/${resolved.slug}`,
        changeFrequency: "weekly",
        priority: 0.8,
      });

      for (const link of resolved.shell.nav ?? []) {
        if (!link.slug || link.is_home) continue;
        entries.push({
          url: `${BASE}/s/${resolved.slug}/${link.slug}`,
          changeFrequency: "monthly",
          priority: 0.5,
        });
      }
    }
  } catch {
    // fail-open
  }

  // --- Items (paginated) ---
  try {
    let page = 1;
    let totalPages = 1;
    let itemCount = 0;

    while (page <= totalPages && itemCount < MAX_ITEM_ENTRIES) {
      const res = await api.items.browse({ page, per_page: 100, sort: "newest" });

      totalPages = res.meta.total_pages;

      for (const item of res.data) {
        if (itemCount >= MAX_ITEM_ENTRIES) break;
        if (item.id) {
          entries.push({
            url: `${BASE}/items/${item.id}`,
            changeFrequency: "weekly",
            priority: 0.5,
          });
          itemCount++;
        }
      }

      page++;
    }
  } catch {
    // fail-open
  }

  return entries;
}
