import type { Metadata } from "next";
import { notFound, redirect } from "next/navigation";

import LocalSEO from "@/views/LocalSEO";
import ReferenceDetail from "@/views/ReferenceDetail";
import JsonLd from "@/components/seo/JsonLd";
import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
import StickyMobileCTA from "@/components/StickyMobileCTA";
import { BlockRenderer } from "@/components/blocks/BlockRenderer";
import {
  industryCanonicalPath,
  industrySlugForProdPath,
  productCanonicalPath,
  productSlugForProdPath,
  referenceCanonicalPath,
  referenceSlugForProdPath,
} from "@/lib/frProdRoutes";
import {
  MOCK_ZONE_SLUGS,
  buildZoneJsonLd,
  buildZoneSeo,
  buildZoneSeoBase,
  resolveZone,
} from "@/lib/zoneSeo";
import { SITE_URL } from "@/lib/seo";
import { mapImage } from "@/lib/wp/mappers";
import { getIndustrie } from "@/lib/wp/queries/industrie";
import { getAllLieuSlugs, getLieu } from "@/lib/wp/queries/lieu";
import { getAllWpPageUris, getWpPage } from "@/lib/wp/queries/page";
import { getProduit } from "@/lib/wp/queries/produit";
import { getReference } from "@/lib/wp/queries/reference";
import { isExcludedUri, isHardcodedUri, normalizeUri } from "@/lib/wp/hardcodedUris";
import { breadcrumbJsonLd, wpSeoToMetadata } from "@/lib/wp/seoToMetadata";
import { toCustomerReference } from "@/lib/wp/toCustomerReference";
import { wpLieuToZoneData } from "@/lib/wp/toZoneData";
import type { WpPage } from "@/lib/wp/types";
import SectorView from "../industries/[slug]/sector-view-client";

// Catch-all public et indexable.
// 1) slug = un des 3 templates mock locaux → noindex pour le dev.
// 2) slug = un CPT WordPress `lieu` publié → modèle LocalSEO à la racine
//    (JSON-LD LocalBusiness + SEO WP, sans block builder).
// 3) sinon → page native WordPress via BlockRenderer (indexable, ISR par tag
//    `page:{uri}`), pour que toute page créée au BO soit servie à son URI.
// 4) sinon → 404.
// L'index "/" reste servi par app/page.tsx ; les routes statiques et CPT
// préfixées prennent la priorité sur ce catch-all (cf. précédence App Router).
// Les URIs déjà servies ailleurs (home, routes en dur) sont exclues via
// HARDCODED_URIS (cf. @/lib/wp/hardcodedUris) — source de vérité partagée
// avec app/sitemap.ts.

// Pages neuves créées au BO : rendues à la demande puis mises en cache (ISR).
export const dynamicParams = true;

const SECTOR_TEMPLATE_SLUGS = ["tertiaire", "collectivites", "agricole", "erp"];

/** Convertit le slug catch-all en URI attendue par getWpPage (`/a/b`). */
function slugToUri(slug: string[]): string {
  return `/${slug.join("/")}`;
}

export async function generateStaticParams(): Promise<{ slug: string[] }[]> {
  // Les 3 templates mock (noindex), conservés pour le dev.
  const mockParams = MOCK_ZONE_SLUGS.map((slug) => ({
    slug: [slug],
  }));

  let lieuParams: { slug: string[] }[] = [];
  try {
    const slugs = await getAllLieuSlugs();
    lieuParams = slugs.map((slug) => ({ slug: [slug] }));
  } catch (error) {
    console.error("[wp] énumération des lieux indisponible pour generateStaticParams :", error);
  }

  let wpParams: { slug: string[] }[] = [];
  try {
    const uris = await getAllWpPageUris();
    wpParams = uris
      .filter((uri) => !isHardcodedUri(uri))
      .map((uri) => uri.replace(/^\/|\/$/g, "").split("/").filter(Boolean))
      .filter((segments) => segments.length > 0) // exclut la home ("/")
      .map((slug) => ({ slug }));
  } catch (error) {
    console.error("[wp] énumération des pages indisponible pour generateStaticParams :", error);
  }

  return [...mockParams, ...lieuParams, ...wpParams];
}

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string[] }>;
}): Promise<Metadata> {
  const { slug } = await params;
  if (slug.length === 0) return {};

  // a) Template mock local.
  const candidate = slug.join("/");
  const uri = slugToUri(slug);

  const productSlug = productSlugForProdPath(uri);
  if (productSlug) {
    try {
      const produit = await getProduit(productSlug);
      if (produit) {
        const canonical = `${SITE_URL}${productCanonicalPath(productSlug)}`;
        return wpSeoToMetadata({ ...produit.seo, canonical }, {
          title: produit.title ?? undefined,
          canonical,
        });
      }
    } catch (error) {
      console.error("[wp] metadata produit indisponible pour", productSlug, error);
    }
  }

  const industrySlug = industrySlugForProdPath(uri);
  if (industrySlug) {
    try {
      const industrie = await getIndustrie(industrySlug);
      if (industrie) {
        const canonical = `${SITE_URL}${industryCanonicalPath(industrySlug)}`;
        return wpSeoToMetadata({ ...industrie.seo, canonical }, {
          title: industrie.title ?? undefined,
          canonical,
        });
      }
    } catch (error) {
      console.error("[wp] metadata industrie indisponible pour", industrySlug, error);
    }
  }

  const referenceSlug = referenceSlugForProdPath(uri);
  if (referenceSlug) {
    try {
      const reference = await getReference(referenceSlug);
      if (reference) {
        const canonical = `${SITE_URL}${referenceCanonicalPath(referenceSlug)}`;
        return wpSeoToMetadata({ ...reference.seo, canonical }, {
          title: reference.title ?? undefined,
          canonical,
        });
      }
    } catch (error) {
      console.error("[wp] metadata reference indisponible pour", referenceSlug, error);
    }
  }

  const resolvedMock = slug.length === 1 ? resolveZone(candidate) : undefined;
  if (resolvedMock) {
    const { metadata } = buildZoneSeo(resolvedMock.zoneData, { noindex: true });
    return metadata;
  }

  // b) Lieu WordPress local.
  if (slug.length === 1) {
    try {
      const lieu = await getLieu(candidate);
      if (lieu?.ficheLieu) {
        const zoneData = wpLieuToZoneData(lieu);
        const fallback = buildZoneSeoBase(zoneData);
        return wpSeoToMetadata(lieu.seo, {
          ...fallback,
          image: zoneData.heroImage
            ? {
                url: zoneData.heroImage.src,
                width: zoneData.heroImage.width,
                height: zoneData.heroImage.height,
                alt: zoneData.heroImage.alt,
              }
            : undefined,
        });
      }
    } catch (error) {
      console.error("[wp] metadata lieu indisponible pour", candidate, error);
    }
  }

  // c) URI déjà servie par la home ou une route en dur → pas de metadata ici.
  if (isHardcodedUri(uri)) return {};
  if (isExcludedUri(uri)) return {}; // pages de test/démo WP → pas de metadata

  // d) Page native WordPress (indexable, SEO réel via le champ seo WP).
  try {
    const page = await getWpPage(uri);
    if (page) {
      return wpSeoToMetadata(page.seo, {
        ...(page.title ? { title: page.title } : {}),
        canonical: `${SITE_URL}${uri}`,
      });
    }
  } catch (error) {
    console.error("[wp] metadata indisponible pour", uri, error);
  }

  // d) Inconnu : pas de metadata (la page rendra notFound()).
  return {};
}

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string[] }>;
}) {
  const { slug } = await params;
  if (slug.length === 0) notFound();

  // a) Template mock local.
  const candidate = slug.join("/");
  const uri = slugToUri(slug);

  const productSlug = productSlugForProdPath(uri);
  if (productSlug) {
    const produit = await getProduit(productSlug);
    if (!produit) notFound();

    const pageUrl = `${SITE_URL}${productCanonicalPath(productSlug)}`;
    const ogImage = mapImage(produit.seo?.ogImage);
    const productJsonLd = {
      "@context": "https://schema.org",
      "@type": "Product",
      name: produit.ficheProduit?.productName || produit.title || productSlug,
      brand: { "@type": "Brand", name: "Covalba" },
      ...(produit.seo?.metaDescription
        ? { description: produit.seo.metaDescription }
        : {}),
      ...(ogImage ? { image: ogImage.sourceUrl } : {}),
      url: pageUrl,
    };

    return (
      <div className="min-h-screen bg-background">
        <JsonLd
          id={`produit-${productSlug}-legacy-jsonld`}
          data={[
            productJsonLd,
            breadcrumbJsonLd([
              { name: "Accueil", url: `${SITE_URL}/` },
              { name: "Solutions", url: `${SITE_URL}/nos-solutions-cool-roof` },
              { name: produit.title ?? productSlug, url: pageUrl },
            ]),
          ]}
        />
        <Navbar />
        <main>
          <BlockRenderer
            sections={produit.sections?.sections}
            accentColor={produit.ficheProduit?.accentColor}
          />
        </main>
        <Footer />
        <StickyMobileCTA />
      </div>
    );
  }

  const industrySlug = industrySlugForProdPath(uri);
  if (industrySlug) {
    const industrie = await getIndustrie(industrySlug);
    if (!industrie) notFound();

    const pageUrl = `${SITE_URL}${industryCanonicalPath(industrySlug)}`;
    const breadcrumb = (
      <JsonLd
        id={`industrie-${industrySlug}-legacy-breadcrumb-jsonld`}
        data={breadcrumbJsonLd([
          { name: "Accueil", url: `${SITE_URL}/` },
          { name: "Industries", url: `${SITE_URL}/industrie` },
          { name: industrie.title ?? industrySlug, url: pageUrl },
        ])}
      />
    );

    if (SECTOR_TEMPLATE_SLUGS.includes(industrySlug)) {
      return (
        <>
          {breadcrumb}
          <SectorView slug={industrySlug} sections={industrie.sections?.sections ?? null} />
        </>
      );
    }

    return (
      <div className="min-h-screen bg-background">
        {breadcrumb}
        <Navbar />
        <main>
          <BlockRenderer sections={industrie.sections?.sections} />
        </main>
        <Footer />
        <StickyMobileCTA />
      </div>
    );
  }

  const referenceSlug = referenceSlugForProdPath(uri);
  if (referenceSlug) {
    const reference = await getReference(referenceSlug);
    if (!reference) notFound();

    const pageUrl = `${SITE_URL}${referenceCanonicalPath(referenceSlug)}`;
    const ogImage = mapImage(reference.seo?.ogImage);
    const articleJsonLd = {
      "@context": "https://schema.org",
      "@type": "Article",
      headline: reference.title ?? referenceSlug,
      ...(reference.seo?.metaDescription
        ? { description: reference.seo.metaDescription }
        : {}),
      ...(ogImage ? { image: ogImage.sourceUrl } : {}),
      url: pageUrl,
      about:
        reference.ficheReference?.produit?.nodes?.[0]?.title ?? "Cool roof Covalba",
    };

    return (
      <>
        <JsonLd
          id={`reference-${referenceSlug}-legacy-jsonld`}
          data={[
            articleJsonLd,
            breadcrumbJsonLd([
              { name: "Accueil", url: `${SITE_URL}/` },
              { name: "Références", url: `${SITE_URL}/references` },
              { name: reference.title ?? referenceSlug, url: pageUrl },
            ]),
          ]}
        />
        <ReferenceDetail slug={referenceSlug} reference={toCustomerReference(reference)} />
      </>
    );
  }

  const resolvedMock = slug.length === 1 ? resolveZone(candidate) : undefined;
  if (resolvedMock) {
    const { jsonLd } = buildZoneSeo(resolvedMock.zoneData, { noindex: true });
    return (
      <>
        <JsonLd id="local-seo-localbusiness" data={jsonLd} />
        <LocalSEO slug={candidate} />
      </>
    );
  }

  // b) Lieu WordPress → modèle local sans flexible block builder.
  if (slug.length === 1) {
    let lieu = null;
    try {
      lieu = await getLieu(candidate);
    } catch (error) {
      console.error("[wp] lieu indisponible pour", candidate, error);
    }

    if (lieu?.ficheLieu) {
      const zoneData = wpLieuToZoneData(lieu);
      const fallback = buildZoneSeoBase(zoneData);
      const jsonLd = buildZoneJsonLd(zoneData, {
        description: lieu.seo?.metaDescription ?? fallback.description,
        canonical: lieu.seo?.canonical ?? fallback.canonical,
      });

      return (
        <>
          <JsonLd id="local-seo-localbusiness" data={jsonLd} />
          <LocalSEO slug={candidate} zoneData={zoneData} />
        </>
      );
    }
  }

  // c) URI déjà servie ailleurs : éviter le doublon indexable.
  if (isHardcodedUri(uri)) {
    // "/accueil" = contenu de la home, déjà servi à "/" → redirige (301).
    // Les autres URIs en dur ont leur propre route ; ce catch-all ne devrait
    // pas les atteindre (précédence), mais on 404 par sécurité.
    if (normalizeUri(uri) === "/accueil") redirect("/");
    notFound();
  }

  // c-bis) Page de test/démo WP (sample-page, test-blocks) → jamais publique.
  if (isExcludedUri(uri)) notFound();

  // d) Page native WordPress → rendu public via BlockRenderer (indexable).
  let page: WpPage | null = null;
  try {
    page = await getWpPage(uri);
  } catch (error) {
    console.error("[wp] page indisponible pour", uri, error);
    notFound();
  }

  if (page) {
    const pageUrl = `${SITE_URL}${uri}`;
    return (
      <div className="min-h-screen bg-background">
        <JsonLd
          id="wp-page-breadcrumb-jsonld"
          data={breadcrumbJsonLd([
            { name: "Accueil", url: `${SITE_URL}/` },
            { name: page.title ?? candidate, url: pageUrl },
          ])}
        />
        <Navbar />
        <main>
          <BlockRenderer sections={page.sections?.sections} />
        </main>
        <Footer />
        <StickyMobileCTA />
      </div>
    );
  }

  // d) Ni zone, ni page WP → 404.
  notFound();
}
