import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { headers } from "next/headers";
import Link from "next/link";
import { Globe } from "lucide-react";
import { auth } from "@/lib/auth/server";
import { db, collections, eq, and, ne } from "@epicure/db";
import { isFollowing } from "@/lib/social-follows";
import { RecipeGridCard } from "@/components/recipe/recipe-grid-card";
import { buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { getMessages } from "@/lib/i18n/server";

type Params = { params: Promise<{ id: string }> };

export async function generateMetadata({ params }: Params): Promise<Metadata> {
  const { id } = await params;
  const col = await db.query.collections.findFirst({
    where: (c, { and, eq }) => and(eq(c.id, id), eq(c.visibility, "public")),
  });
  if (!col) return {};
  return {
    title: col.name,
    description: col.description ?? undefined,
    openGraph: { title: col.name, description: col.description ?? undefined, type: "article" },
  };
}

export default async function PublicCollectionPage({ params }: Params) {
  const { id } = await params;
  const session = await auth.api.getSession({ headers: await headers() }).catch(() => null);
  const m = getMessages((session?.user as { locale?: string } | undefined)?.locale);

  const col = await db.query.collections.findFirst({
    where: and(eq(collections.id, id), ne(collections.visibility, "private")),
    with: {
      user: true,
      recipes: {
        orderBy: (t, { asc }) => asc(t.position),
        with: { recipe: { with: { photos: true } } },
      },
    },
  });

  if (!col) notFound();

  // Same rationale as /r/[id]: this route has no session-based access
  // control otherwise, so a "followers"-only collection needs an explicit
  // gate — the owner, or a signed-in follower of the owner.
  if (col.visibility === "followers") {
    const viewerId = session?.user?.id;
    const allowed = !!viewerId && (viewerId === col.userId || await isFollowing(viewerId, col.userId));
    if (!allowed) notFound();
  }

  const viewerId = session?.user?.id;
  const recipeEntries = await Promise.all(
    col.recipes.map(async (r) => {
      const recipe = r.recipe;
      if (!recipe) return null;
      if (recipe.visibility === "public" || recipe.visibility === "unlisted") return recipe;
      if (recipe.visibility === "followers" && viewerId) {
        if (viewerId === recipe.authorId || await isFollowing(viewerId, recipe.authorId)) return recipe;
      }
      // Owner's own private recipes (allowed in their own collection) aren't
      // shown to anyone else here — this route has no owner-only branch.
      return null;
    })
  );
  const visibleRecipes = recipeEntries.filter((r): r is NonNullable<typeof r> => r !== null);

  return (
    <div className="container mx-auto max-w-5xl px-4 py-8 space-y-8">
      <div className="flex items-center gap-2 text-sm text-muted-foreground">
        <Globe className="h-3.5 w-3.5" />
        <span>{m.publicCollection.publicCollectionBy}</span>
        <Link href={`/u/${col.user.username ?? col.user.id}`} className="hover:text-foreground font-medium">
          {col.user.name}
        </Link>
        {session && (
          <div className="ml-auto">
            <Link href={`/collections/${id}`} className={cn(buttonVariants({ variant: "outline", size: "sm" }))}>
              {m.publicCollection.viewInLibrary}
            </Link>
          </div>
        )}
        {!session && (
          <div className="ml-auto flex items-center gap-2">
            <Link href="/signup" className={cn(buttonVariants({ size: "sm" }))}>{m.publicRecipe.signUpFree}</Link>
            <Link href="/login" className={cn(buttonVariants({ variant: "outline", size: "sm" }))}>{m.publicRecipe.logIn}</Link>
          </div>
        )}
      </div>

      <div className="space-y-2">
        <h1 className="text-3xl font-bold tracking-tight">{col.name}</h1>
        {col.description && <p className="text-muted-foreground leading-relaxed">{col.description}</p>}
        <p className="text-sm text-muted-foreground">
          {visibleRecipes.length} recipe{visibleRecipes.length !== 1 ? "s" : ""}
        </p>
      </div>

      {visibleRecipes.length > 0 && (
        <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
          {visibleRecipes.map((recipe) => (
            <Link key={recipe.id} href={`/r/${recipe.id}`}>
              <RecipeGridCard recipe={recipe} />
            </Link>
          ))}
        </div>
      )}

      {!session && (
        <div className="rounded-xl border bg-muted/40 p-6 text-center space-y-3">
          <p className="font-semibold">{m.publicCollection.wantToSave}</p>
          <p className="text-sm text-muted-foreground">{m.publicCollection.wantToSaveDescription}</p>
          <Link href="/signup" className={cn(buttonVariants())}>{m.publicRecipe.getStartedFree}</Link>
        </div>
      )}
    </div>
  );
}
