import type { Metadata } from "next";
import prisma from "@/lib/prisma";
import { cache } from "react";
import Link from "next/link";
import { notFound } from "next/navigation";
import { withAvatarUrls } from "@/lib/media";
import StickySearchBar from "@/components/shared/sticky-search-bar";
import Breadcrumbs from "@/components/shared/breadcrumbs";
import InfiniteEscortGrid from "@/components/shared/infinite-escort-grid";

// ISR — country+city pages render at most every 10 min, with build-time
// fallback. Sitemap regenerates daily and crawlers re-fetch on miss.
export const revalidate = 600;

interface Props {
  params: Promise<{ countrySlug: string; citySlug: string }>;
}

const getCountry = cache(async (slug: string) =>
  prisma.country.findFirst({ where: { slug, active: true } })
);
const getCity = cache(async (countryId: number, slug: string) =>
  prisma.city.findFirst({ where: { slug, country_id: countryId } })
);
const getCount = cache(async (countryId: number, cityId: number) =>
  prisma.user.count({
    where: { user_type: "escort", country_id: countryId, city_id: cityId },
  })
);

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { countrySlug, citySlug } = await params;
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "https://www.adultworld.ai";
  const country = await getCountry(countrySlug);
  if (!country) return { title: "Escorts" };
  const city = await getCity(country.id, citySlug);
  if (!city) return { title: `Escorts in ${country.name}` };
  const totalCount = await getCount(country.id, city.id);
  const description = `Find ${totalCount.toLocaleString()} verified escorts in ${city.name}, ${country.name}. Browse profiles with photos, rates, services, and reviews. Book incall and outcall escorts.`;
  const cityUrl = `${baseUrl}/escorts/${country.slug}/${city.slug}`;
  return {
    title: `Escorts in ${city.name}, ${country.name} | AdultWorld`,
    description,
    alternates: {
      canonical: cityUrl,
      // hreflang signals to crawlers (G.4): all locales share the same URL,
      // content is translated client-side via next-intl cookie.
      languages: {
        en: cityUrl,
        es: cityUrl,
        de: cityUrl,
        fr: cityUrl,
        "x-default": cityUrl,
      },
    },
    openGraph: {
      title: `Escorts in ${city.name}, ${country.name} | AdultWorld`,
      description,
    },
    twitter: {
      card: "summary_large_image",
      title: `Escorts in ${city.name}, ${country.name} | AdultWorld`,
      description,
    },
  };
}

export default async function EscortsByCityPage({
  params,
}: {
  params: Promise<{ countrySlug: string; citySlug: string }>;
}) {
  const { countrySlug, citySlug } = await params;
  const country = await getCountry(countrySlug);
  if (!country) notFound();
  const city = await getCity(country.id, citySlug);
  if (!city) notFound();

  const escortWhere = {
    user_type: "escort" as const,
    country_id: country.id,
    city_id: city.id,
    active: true,
    banned_at: null,
  };

  const [escortsRaw, totalCount] = await Promise.all([
    prisma.user.findMany({
      where: escortWhere,
      orderBy: { lastonline_at: "desc" },
      take: 48,
    }),
    prisma.user.count({ where: escortWhere }),
  ]);
  const escorts = await withAvatarUrls(escortsRaw);

  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "https://www.adultworld.ai";

  const cityUrl = `${baseUrl}/escorts/${countrySlug}/${citySlug}`;
  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "CollectionPage",
    name: `Escorts in ${city.name}, ${country.name}`,
    description: `Browse verified escorts in ${city.name}, ${country.name} on AdultWorld.`,
    url: cityUrl,
    inLanguage: "en",
    about: {
      "@type": "Place",
      name: `${city.name}, ${country.name}`,
      address: {
        "@type": "PostalAddress",
        addressLocality: city.name,
        addressCountry: country.name,
      },
    },
    isPartOf: {
      "@type": "WebSite",
      name: "AdultWorld",
      url: baseUrl,
    },
    breadcrumb: {
      "@type": "BreadcrumbList",
      itemListElement: [
        { "@type": "ListItem", position: 1, name: "Escorts", item: `${baseUrl}/escorts` },
        { "@type": "ListItem", position: 2, name: country.name, item: `${baseUrl}/escorts/${countrySlug}` },
        { "@type": "ListItem", position: 3, name: city.name, item: cityUrl },
      ],
    },
    mainEntity: {
      "@type": "ItemList",
      numberOfItems: totalCount,
      itemListElement: escorts.slice(0, 20).map((escort, index) => ({
        "@type": "ListItem",
        position: index + 1,
        url: `${baseUrl}/view/${escort.id_aw}`,
        name: escort.username,
      })),
    },
  };

  return (
    <>
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
    />
    <div className="space-y-6">
      <StickySearchBar />
      <div>
        <div className="mb-2">
          <Breadcrumbs items={[
            { label: "Escorts", href: "/escorts" },
            { label: country.name, href: `/escorts/${countrySlug}` },
            { label: city.name },
          ]} />
        </div>
        <h1 className="text-2xl font-bold">
          {totalCount.toLocaleString()} {totalCount === 1 ? "escort" : "escorts"} in {city.name}, {country.name}
        </h1>
      </div>

      {/* Escort Grid with Infinite Scroll */}
      <InfiniteEscortGrid
        initialEscorts={escorts}
        initialHasMore={escorts.length === 48}
        sort="recently-active"
        countryId={country.id}
        cityId={city.id}
      />

      {escorts.length === 0 && (
        <div className="text-center py-16 text-text-muted">
          <p className="text-lg">
            No escorts found in {city.name}, {country.name}
          </p>
          <Link
            href={`/escorts/${countrySlug}`}
            className="text-primary hover:underline mt-2 inline-block"
          >
            View all escorts in {country.name}
          </Link>
        </div>
      )}

      {/* SEO Content */}
      <section className="mt-8 border-t border-surface-light pt-6">
        <h2 className="text-lg font-semibold text-white mb-3">
          Escorts in {city.name}, {country.name}
        </h2>
        <div className="text-sm text-text-muted space-y-3">
          <p>
            Discover {totalCount.toLocaleString()} verified escorts in {city.name}, {country.name} on AdultWorld.ai.
            Browse detailed profiles with photos, rates, services offered, and genuine client reviews.
          </p>
          <p>
            Whether you&apos;re looking for companionship, a dinner date, massage services, or a memorable evening in {city.name},
            our verified providers offer a range of services tailored to your preferences. All profiles are verified
            for your safety and peace of mind.
          </p>
          <p>
            New to AdultWorld? <Link href="/for-clients" className="text-gold hover:underline">Learn how it works</Link> or
            browse our <Link href="/safety" className="text-gold hover:underline">safety guidelines</Link> before your first booking.
            Escorts in {city.name} can also be found through our{" "}
            <Link href="/search" className="text-gold hover:underline">advanced search</Link> with filters for services, appearance, and availability.
          </p>
        </div>
      </section>
    </div>
    </>
  );
}
