import type { Metadata } from "next";
import Link from "next/link";
import Image from "next/image";
import { Reveal, RevealGroup, RevealItem } from "../components/Reveal";
import { Newsletter } from "../components/Newsletter";
import { Footer } from "../components/Footer";
import { BlogCategoryFilter } from "../components/BlogCategoryFilter";
import { getBlogPosts, getBlogFilterEnabled } from "../lib/payload";
import { formatDate } from "../lib/format";

export const metadata: Metadata = {
  title: "Blog",
  description: "Gedanken, Methoden und Impulse für einen leichteren und klareren Alltag.",
  alternates: { canonical: "/blog" },
  openGraph: {
    title: "Blog | einfach produktiv.",
    description: "Gedanken, Methoden und Impulse für einen leichteren und klareren Alltag.",
    url: "/blog",
    type: "website",
    images: ["/blog-featured.jpg"],
  },
};

// Every distinct category name in DOM order — Payload's `categories` field
// stores related docs, no separate slug on this side, but since this page
// already fetches every published post (limit 100, no pagination), a
// plain client-agnostic array filter is enough; no separate Payload query
// per category needed.
function distinctCategories(posts: { categories: string[] }[]): string[] {
  const seen = new Set<string>();
  for (const post of posts) for (const c of post.categories) seen.add(c);
  return Array.from(seen);
}

export default async function BlogOverviewPage({
  searchParams,
}: {
  searchParams: Promise<{ categories?: string }>;
}) {
  const [allPosts, blogFilterEnabled] = await Promise.all([getBlogPosts(100), getBlogFilterEnabled()]);
  const { categories: categoriesParam } = await searchParams;
  const activeCategories = blogFilterEnabled && categoriesParam ? categoriesParam.split(",").filter(Boolean) : [];
  const allCategories = blogFilterEnabled ? distinctCategories(allPosts) : [];
  const posts =
    activeCategories.length === 0 ? allPosts : allPosts.filter((post) => post.categories.some((c) => activeCategories.includes(c)));
  // getBlogPosts sorts "-featured,-publishedAt", so index 0 IS the actual
  // featured post when the unfiltered list is shown — but a category
  // filter can (and often will) exclude it entirely, in which case index 0
  // is just the newest matching post, not an editorially featured one. It
  // still doesn't deserve the big hero-card treatment (implies "the
  // featured post", not "whatever sorted first"), so that layout is gated
  // on the post's own `featured` flag, not on array position.
  const [first, ...restAll] = posts;
  const featured = first?.featured ? first : undefined;
  const rest = featured ? restAll : posts;

  return (
    <>
      <main className="flex flex-col flex-1 bg-bg-base">
        {/* Header — plain text, same treatment as /shop's ShopHeader.tsx
            and every legal page (the bespoke photo-bleed hero this used to
            be predated that convention being established elsewhere). */}
        <Reveal className="flex flex-col gap-4 items-start pb-6 pt-10 px-[var(--layout-padding-x)] w-full border-b border-border">
          <p className="flex items-center gap-2 text-body-sm text-text-muted">
            <Link href="/" className="hover:text-brand transition-colors">Startseite</Link>
            <span>›</span>
            <span className="text-text-primary">Blog</span>
          </p>
          <p
            className="font-semibold text-display text-text-primary"
            style={{ fontFamily: "var(--font-lora)" }}
          >
            Blog
          </p>
          <p className="text-body text-text-muted">
            Gedanken, Methoden und Impulse für einen leichteren und klareren Alltag.
          </p>
          {allCategories.length > 1 && (
            <BlogCategoryFilter allCategories={allCategories} activeCategories={activeCategories} />
          )}
        </Reveal>

        {posts.length === 0 && (
          <p className="text-body text-text-muted w-full max-w-[80rem] mx-auto px-[var(--layout-padding-x)] pt-10">
            Keine Beiträge in dieser Kategorie gefunden.
          </p>
        )}

        {featured && (
          // key'd for the same reason as RevealGroup below — guards against
          // the same stuck-at-opacity-0 failure mode if a future filter
          // combination ever swaps in a *different* featured post without
          // an intervening moment where `featured` was falsy.
          <Reveal key={featured.id} delay={0.1} className="w-full px-[var(--layout-padding-x)] pt-8 pb-4">
            <Link
              href={`/blog/${featured.slug}`}
              className="group grid grid-cols-1 sm:grid-cols-2 w-full max-w-[80rem] mx-auto rounded-md overflow-hidden bg-bg-muted transition-transform duration-300 hover:-translate-y-1"
            >
              <div className="relative w-full aspect-video sm:aspect-auto sm:h-full bg-bg-muted">
                {featured.thumbnail && (
                  <Image alt="" src={featured.thumbnail} fill sizes="(min-width: 640px) 40rem, 100vw" className="object-cover" />
                )}
              </div>
              <div className="flex flex-col justify-center gap-3 p-8 sm:p-12 min-w-0">
                <div className="flex flex-wrap items-center gap-x-2 gap-y-1 font-semibold text-text-muted text-body-sm uppercase tracking-wide">
                  <span className="whitespace-nowrap">{featured.categories.join(", ")}</span>
                  <span>•</span>
                  <span className="whitespace-nowrap">{featured.readTime} Min</span>
                  <span>•</span>
                  <span className="uppercase whitespace-nowrap">{formatDate(featured.publishedAt)}</span>
                </div>
                <p
                  className="font-semibold text-h-section text-text-primary"
                  style={{ fontFamily: "var(--font-lora)" }}
                >
                  {featured.title}
                </p>
                <p className="text-body text-text-muted line-clamp-3">{featured.excerpt}</p>
                <span className="flex items-center gap-1.5 font-bold text-body text-text-primary mt-1">
                  Zum Beitrag
                  <svg
                    viewBox="0 0 20 20"
                    className="size-4 transition-transform duration-200 group-hover:translate-x-1"
                    fill="none"
                    aria-hidden="true"
                  >
                    <path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </span>
              </div>
            </Link>
          </Reveal>
        )}

        {rest.length > 0 && (
          // key'd on the rendered post set — RevealGroup's `whileInView`
          // only fires once per component instance (viewport.once=true),
          // and a category-filter change re-renders this same page
          // component in place (only `searchParams` differs, no full
          // remount). Since `rest.length > 0` stays true across most
          // filter transitions, RevealGroup itself never naturally
          // unmounts, so once it has already fired "show" for one
          // filter's list, freshly swapped-in RevealItems (new post ids)
          // mount into an already-settled parent that has no reason to
          // re-fire the reveal trigger — they were stuck at opacity 0
          // forever, reported as the list appearing blank after refiltering.
          // Forcing a remount on every distinct post set restarts
          // RevealGroup's viewport tracking from scratch each time.
          <RevealGroup
            key={rest.map((post) => post.id).join(",")}
            className="flex flex-col w-full max-w-[80rem] mx-auto px-[var(--layout-padding-x)] py-6 divide-y divide-border"
          >
            {rest.map((post) => (
              <RevealItem key={post.id} className="py-8 first:pt-0 last:pb-0">
                <Link href={`/blog/${post.slug}`} className="group flex flex-col sm:flex-row gap-6 items-start">
                  <div className="relative w-full sm:w-[18.75rem] aspect-video sm:aspect-[300/192] shrink-0 rounded-md overflow-hidden bg-bg-muted">
                    {post.thumbnail && (
                      <Image alt="" src={post.thumbnail} fill sizes="(min-width: 640px) 18.75rem, 100vw" className="object-cover" />
                    )}
                  </div>
                  <div className="flex flex-col gap-2 min-w-0 flex-1">
                    <div className="flex flex-wrap items-center gap-x-2 gap-y-1 font-semibold text-text-muted text-body-sm uppercase tracking-wide">
                      <span className="whitespace-nowrap">{post.categories.join(", ")}</span>
                      <span>•</span>
                      <span className="whitespace-nowrap">{post.readTime} Min</span>
                      <span>•</span>
                      <span className="uppercase whitespace-nowrap">{formatDate(post.publishedAt)}</span>
                    </div>
                    <p
                      className="font-semibold text-h-small text-text-primary"
                      style={{ fontFamily: "var(--font-lora)" }}
                    >
                      {post.title}
                    </p>
                    <p className="text-body text-text-muted">{post.excerpt}</p>
                    <span className="flex items-center gap-1.5 font-bold text-body-sm text-text-primary mt-1">
                      Zum Beitrag
                      <svg
                        viewBox="0 0 20 20"
                        className="size-3.5 transition-transform duration-200 group-hover:translate-x-1"
                        fill="none"
                        aria-hidden="true"
                      >
                        <path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                      </svg>
                    </span>
                  </div>
                </Link>
              </RevealItem>
            ))}
          </RevealGroup>
        )}

        <Newsletter
          title="Neue Impulse im richtigen Moment."
          description="Melde dich zum Newsletter an und erhalte regelmäßig Gedanken, Methoden und praktische Tipps."
        />
      </main>
      <Footer />
    </>
  );
}
