import { execSync } from "node:child_process";
import path from "node:path";
import { allBlogs } from "content-collections";
import type { MetadataRoute } from "next";
import { siteConfig } from "@/lib/site";

const SITE_URL = siteConfig.url;

// ============================================================================
// LASTMOD VIA GIT (mono-locale, Vercel shallow-clone aware)
// ============================================================================
// Référence : Obsidian SEO/Techniques/Sitemap Nextjs i18n.md
// Règles Google :
//   - lastmod doit être "consistently and verifiably accurate" → sinon Google
//     l'ignore (et apprend à se méfier du sitemap entier).
//   - changefreq + priority sont ignorés depuis 2023 → on les retire.
//   - "missing lastmod" est préférable à un "lying lastmod".

// Détection shallow clone au module load.
// Vercel clone toujours en --depth 1 et `git fetch --unshallow` est
// silencieusement rejeté dans la sandbox. Sur shallow clone, git log retourne
// la même date pour tous les fichiers plus anciens que la profondeur = poison.
// Si shallow → on omet lastmod sur les pages statiques.
const hasFullGitHistory = (() => {
  try {
    const result = execSync("git rev-parse --is-shallow-repository", {
      cwd: path.resolve(process.cwd()),
      stdio: ["ignore", "pipe", "ignore"],
    });
    return result.toString().trim() === "false";
  } catch {
    return false;
  }
})();

/**
 * Retourne la date du dernier commit non-merge ayant modifié `relPath`.
 *
 * --no-merges est critique : sans ça, après merge dev→main, git retourne le
 * merge commit pour tous les fichiers qui viennent de dev → toutes les pages
 * auraient la même date. Avec --no-merges, git descend au commit feature qui
 * a réellement modifié le fichier.
 */
function getGitLastMod(relPath: string): Date | undefined {
  if (!hasFullGitHistory) return undefined;
  try {
    const stdout = execSync(
      `git log -1 --no-merges --format=%cI -- ${relPath}`,
      {
        cwd: path.resolve(process.cwd()),
        stdio: ["ignore", "pipe", "ignore"],
      },
    );
    const dateStr = stdout.toString().trim();
    if (!dateStr) return undefined;
    return new Date(dateStr);
  } catch {
    return undefined;
  }
}

// ============================================================================
// PAGES STATIQUES — href ↔ source file pour git mtime
// ============================================================================

type StaticPage = { href: string; source: string };

const STATIC_PAGES: StaticPage[] = [
  { href: "/", source: "app/page.tsx" },
  { href: "/contact/", source: "app/contact/page.tsx" },
  { href: "/ressources/", source: "app/ressources/page.tsx" },
  { href: "/courtier-en-energie/", source: "app/courtier-en-energie/page.tsx" },
  {
    href: "/guides/regulation-energetique-2026/",
    source: "app/guides/regulation-energetique-2026/page.tsx",
  },
  {
    href: "/expertise/courtage-energie-pro/",
    source: "app/expertise/courtage-energie-pro/page.tsx",
  },
  {
    href: "/expertise/management-energie/",
    source: "app/expertise/management-energie/page.tsx",
  },
  {
    href: "/expertise/optimisation-arenh-turpe/",
    source: "app/expertise/optimisation-arenh-turpe/page.tsx",
  },
  {
    href: "/solutions/efficacite-energetique/",
    source: "app/solutions/efficacite-energetique/page.tsx",
  },
  {
    href: "/solutions/electricite-verte/",
    source: "app/solutions/electricite-verte/page.tsx",
  },
  {
    href: "/solutions/garanties-origine/",
    source: "app/solutions/garanties-origine/page.tsx",
  },
  {
    href: "/outils/",
    source: "app/outils/page.tsx",
  },
  {
    href: "/outils/comparateur-electricite-pro/",
    source: "app/outils/comparateur-electricite-pro/page.tsx",
  },
  {
    href: "/outils/simulateur-exoneration-accise-electricite/",
    source: "app/outils/simulateur-exoneration-accise-electricite/page.tsx",
  },
  {
    href: "/secteurs/commerces-artisans/",
    source: "app/secteurs/commerces-artisans/page.tsx",
  },
  {
    href: "/secteurs/industrie/",
    source: "app/secteurs/industrie/page.tsx",
  },
  {
    href: "/secteurs/tertiaire/",
    source: "app/secteurs/tertiaire/page.tsx",
  },
  {
    href: "/secteurs/collectivites/",
    source: "app/secteurs/collectivites/page.tsx",
  },
];

// ============================================================================
// SITEMAP GENERATION
// ============================================================================
// Pages exclues volontairement (noindex dans leurs metadata respectives) :
//   - /mentions-legales/ — retiré pour cohérence indexation 2026
//   - /politique-confidentialite/
//   - /cgu/

export default function sitemap(): MetadataRoute.Sitemap {
  // ─── Pages statiques : lastmod conditionnel via git ─────────────────────────
  const staticEntries: MetadataRoute.Sitemap = STATIC_PAGES.map((page) => {
    const lastModified = getGitLastMod(page.source);
    return {
      url: `${SITE_URL}${page.href}`,
      // Spread conditionnel : omet le champ quand git ne sait pas (shallow Vercel).
      ...(lastModified ? { lastModified } : {}),
    };
  });

  // ─── Articles de blog : lastmod = frontmatter MDX ─────────────────────────
  // Le blog est INDÉPENDANT du shallow clone : il utilise post.lastmod du
  // frontmatter MDX (committed dans le fichier .mdx, lu par content-collections),
  // pas git log.
  const blogEntries: MetadataRoute.Sitemap = allBlogs
    .slice()
    .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
    .map((blog) => ({
      url: `${SITE_URL}/${blog.category}/${blog.slug}/`,
      lastModified: new Date(
        blog.lastmod || blog.updatedAt || blog.date,
      ),
    }));

  // ─── Category index pages : lastmod = max(post.lastmod) des articles ───────
  const categoryLastMod = new Map<string, Date>();
  for (const blog of allBlogs) {
    const blogDate = new Date(blog.lastmod || blog.updatedAt || blog.date);
    const current = categoryLastMod.get(blog.category);
    if (!current || blogDate > current) {
      categoryLastMod.set(blog.category, blogDate);
    }
  }
  const categoryEntries: MetadataRoute.Sitemap = Array.from(
    categoryLastMod.entries(),
  ).map(([category, lastModified]) => ({
    url: `${SITE_URL}/${category}/`,
    lastModified,
  }));

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