// Next.js App Router + Sanity Integration
// Demonstrates: sanity client setup, GROQ queries, server components, ISR, draft mode

// --- lib/sanity.client.ts ---
import { createClient } from "next-sanity"

export const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET ?? "production",
  apiVersion: "2024-01-01",
  useCdn: true,
  // For authenticated requests (preview/drafts)
  token: process.env.SANITY_API_READ_TOKEN,
})

// --- lib/sanity.queries.ts ---
import { groq } from "next-sanity"

export const postsQuery = groq`*[_type == "post"] | order(publishedAt desc) {
  _id,
  title,
  slug,
  publishedAt,
  "author": author->name,
  "categories": categories[]->title,
  mainImage
}`

export const postBySlugQuery = groq`*[_type == "post" && slug.current == $slug][0] {
  _id,
  title,
  slug,
  body,
  publishedAt,
  "author": author->{name, image, bio},
  "categories": categories[]->title,
  mainImage
}`

// --- app/posts/page.tsx ---
// Server Component — fetches at request time with ISR
import { client } from "@/lib/sanity.client"
import { postsQuery } from "@/lib/sanity.queries"
import Link from "next/link"

// Enable ISR with revalidation
export const revalidate = 60

interface Post {
  _id: string
  title: string
  slug: { current: string }
  publishedAt: string
  author: string
  categories: string[]
}

export default async function PostsPage() {
  const posts = await client.fetch<Post[]>(postsQuery)

  return (
    <main>
      <h1>Blog Posts</h1>
      <ul>
        {posts.map((post) => (
          <li key={post._id}>
            <Link href={`/posts/${post.slug.current}`}>
              {post.title}
            </Link>
            <span>by {post.author}</span>
          </li>
        ))}
      </ul>
    </main>
  )
}

// --- app/posts/[slug]/page.tsx ---
import { client } from "@/lib/sanity.client"
import { postBySlugQuery, postsQuery } from "@/lib/sanity.queries"
import { notFound } from "next/navigation"

export const revalidate = 60

// Generate static paths for all posts
export async function generateStaticParams() {
  const posts = await client.fetch<Array<{ slug: { current: string } }>>(
    groq`*[_type == "post"]{ slug }`
  )
  return posts.map((post) => ({ slug: post.slug.current }))
}

export default async function PostPage({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  const post = await client.fetch(postBySlugQuery, { slug })

  if (!post) notFound()

  return (
    <article>
      <h1>{post.title}</h1>
      <p>By {post.author?.name}</p>
      {/* Render portable text body with @portabletext/react */}
    </article>
  )
}

// --- app/api/draft-mode/enable/route.ts ---
import { draftMode } from "next/headers"
import { redirect } from "next/navigation"

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url)
  const secret = searchParams.get("secret")
  const slug = searchParams.get("slug") ?? "/"

  if (secret !== process.env.SANITY_PREVIEW_SECRET) {
    return new Response("Invalid secret", { status: 401 })
  }

  const draft = await draftMode()
  draft.enable()
  redirect(slug)
}
