import type { MetadataRoute } from "next";
import type { Locale } from "next-intl";
import { seo } from "@/config/seo";
import { site } from "@/config/site";
import { getPathname } from "@/i18n/navigation";
import { routing } from "@/i18n/routing";
import { articlePath, getAllPosts } from "@/lib/blog";

/** Absolute blog URL from an as-needed path (`/sourcing` or `/fr/sourcing`). */
function blogUrl(asNeededPath: string): string {
  return `${site.url}${asNeededPath}`;
}

const staticRoutes = [
  "/",
  "/about-us",
  "/production-process",
  "/design-development",
  "/gallery",
  "/news-events",
  "/sustainability",
  "/contact-us",
] as const;

type Route = (typeof staticRoutes)[number];

function absoluteUrl(path: string) {
  return `${site.url}${path === "/" ? "" : path}`;
}

/** Newest `updated ?? date` across a locale's posts, or `undefined` when it has none. */
function latestPostDate(locale: Locale): Date | undefined {
  const stamps = getAllPosts(locale).map((post) => post.updated ?? post.date);
  if (stamps.length === 0) return undefined;
  return new Date(stamps.reduce((newest, stamp) => (stamp > newest ? stamp : newest)));
}

export default function sitemap(): MetadataRoute.Sitemap {
  const staticEntries = staticRoutes
    .filter((href) => !seo.sitemap.exclude.includes(href))
    .flatMap((href) =>
      routing.locales.map((locale) => {
        const localizedPath = getPathname({ href: href as Route, locale });
        const languages = Object.assign(
          Object.fromEntries(
            routing.locales.map((alt) => [
              alt,
              absoluteUrl(getPathname({ href: href as Route, locale: alt })),
            ]),
          ),
          {
            "x-default": absoluteUrl(
              getPathname({ href: href as Route, locale: routing.defaultLocale }),
            ),
          },
        );
        // No `lastModified`: these pages have no modification date we actually know,
        // and stamping the build time on all of them — which is what a module-level
        // `new Date()` did — is exactly the unreliable signal Google says it ignores.
        // Better to say nothing than to say something false on every deploy.
        return {
          url: absoluteUrl(localizedPath),
          changeFrequency: seo.sitemap.changeFreq,
          priority: href === "/" ? 1 : seo.sitemap.priority,
          alternates: { languages },
        } satisfies MetadataRoute.Sitemap[number];
      }),
    );

  const blogEntries: MetadataRoute.Sitemap = [];

  // Blog index (`/blog`), both locales, with hreflang + x-default.
  const blogIndexLanguages = Object.fromEntries(
    routing.locales.map((l) => [
      l,
      `${site.url}${l === routing.defaultLocale ? "" : `/${l}`}/blog`,
    ]),
  );
  blogIndexLanguages["x-default"] = blogIndexLanguages[routing.defaultLocale];
  for (const locale of routing.locales) {
    // The index does change: when its newest article does. That date is real.
    const indexLastModified = latestPostDate(locale);
    blogEntries.push({
      url: `${site.url}${locale === routing.defaultLocale ? "" : `/${locale}`}/blog`,
      ...(indexLastModified ? { lastModified: indexLastModified } : {}),
      changeFrequency: "weekly",
      priority: 0.6,
      alternates: { languages: blogIndexLanguages },
    });
  }

  // Articles (non-draft, both locales), with paired hreflang alternates.
  for (const locale of routing.locales) {
    for (const post of getAllPosts(locale)) {
      const languages = Object.fromEntries(
        routing.locales.flatMap((l) => {
          const lp = getAllPosts(l).find((x) => x.postId === post.postId);
          return lp ? [[l, blogUrl(articlePath(l, lp.category, lp.slug))]] : [];
        }),
      );
      const defaultPost = getAllPosts(routing.defaultLocale).find((x) => x.postId === post.postId);
      if (defaultPost) {
        languages["x-default"] = blogUrl(
          articlePath(routing.defaultLocale, defaultPost.category, defaultPost.slug),
        );
      }
      blogEntries.push({
        url: blogUrl(articlePath(locale, post.category, post.slug)),
        lastModified: new Date(post.updated ?? post.date),
        changeFrequency: "monthly",
        priority: 0.7,
        alternates: { languages },
      });
    }
  }

  return [...staticEntries, ...blogEntries];
}
