import { cache, Suspense } from "react"
import { notFound } from "next/navigation"
import Link from "next/link"
import dynamic from "next/dynamic"
import { ExperimentMetadata } from "@/lib/types" // Your defined types
import { Metadata } from "next" // For Next.js metadata API

const MonacoDiffViewer = dynamic(() => import("@/components/trace/monaco-diff-viewer"), {
  loading: () => <div className="animate-pulse p-8">Loading editor...</div>,
})
import { auth0 } from "@/lib/auth0"
import { isTeamMember } from "@/app/utils/auth"
import { prisma } from "@/lib/prisma"

interface TraceDetailsPageProps {
  params: Promise<{
    trace_id: string
  }>
}

// Deduplicate the Prisma query between generateMetadata and the page component.
// React cache() ensures the same trace_id only hits the DB once per request.
const getOptimizationFeature = cache(async (trace_id: string) => {
  return prisma.optimization_features.findUnique({
    where: { trace_id },
    select: {
      experiment_metadata: true,
      metadata: true,
      organization: true,
      repository: true,
      review_quality: true,
      review_explanation: true,
    },
  })
})
// Function to generate dynamic metadata (e.g., page title)
export async function generateMetadata(props: TraceDetailsPageProps): Promise<Metadata> {
  const params = await props.params
  const { trace_id } = params

  // Optionally fetch minimal data for title generation to avoid over-fetching
  // For simplicity, we'll use a generic title or one derived if data is fetched quickly
  // A more optimized approach might involve a separate lightweight query or using default values.

  const optimizationFeature = await getOptimizationFeature(trace_id)

  let title = `Python Diff Trace: ${trace_id.substring(0, 8)}`
  if (optimizationFeature?.experiment_metadata) {
    const metadata = optimizationFeature.experiment_metadata as unknown as ExperimentMetadata // Type assertion
    const repoName =
      optimizationFeature.organization && optimizationFeature.repository
        ? `${optimizationFeature.organization}/${optimizationFeature.repository}`
        : metadata.owner && metadata.repo
          ? `${metadata.owner}/${metadata.repo}`
          : ""

    if (metadata.prCommentFields?.function_name) {
      title = `Diff: ${metadata.prCommentFields.function_name} (${repoName})`
    } else if (repoName) {
      title = `Diff: ${repoName} - Trace ${trace_id.substring(0, 8)}`
    }
  }

  return {
    title: `${title} | Codeflash AI`,
    description: `Review CodeFlash Python code optimization diffs for trace ID ${trace_id}.`,
    // You can add more OpenGraph tags, etc.
  }
}

// Inner content component — runs inside a Suspense boundary so that
// dynamic data access (auth0.getSession → headers()) doesn't block
// the static shell from being prerendered with cacheComponents.
async function TraceContent({ params }: { params: Promise<{ trace_id: string }> }) {
  const resolvedParams = await params
  const { trace_id } = resolvedParams

  if (!trace_id) {
    notFound()
  }

  const session = await auth0.getSession()
  if (!session?.user) return null

  // Check team member access - only team members can view traces
  const hasTeamAccess = await isTeamMember()
  if (!hasTeamAccess) {
    // Create a custom access denied page or redirect to a generic error
    return (
      <div className="flex flex-col items-center justify-center h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-slate-200">
        <div className="text-center max-w-md">
          <div className="mb-6">
            <svg
              className="w-16 h-16 mx-auto text-red-400"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
              />
            </svg>
          </div>
          <h1 className="text-2xl font-bold text-red-400 mb-4">Access Denied</h1>
          <p className="text-slate-300 mb-6">
            This trace is restricted to CodeFlash team members only.
          </p>
          <div className="text-sm text-slate-400 mb-6">
            <p>
              Logged in as:{" "}
              <span className="font-mono">{session.user.email || session.user.nickname}</span>
            </p>
            <p>
              Trace ID: <span className="font-mono">{trace_id}</span>
            </p>
          </div>
          <Link
            href="/app"
            className="inline-block bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg transition-colors"
          >
            Go to Dashboard
          </Link>
        </div>
      </div>
    )
  }

  // Uses the same cached function as generateMetadata — one DB round-trip per request
  let optimizationFeature: Awaited<ReturnType<typeof getOptimizationFeature>> = null
  try {
    optimizationFeature = await getOptimizationFeature(trace_id)
  } catch (error) {
    console.error(`[TracePage] Failed to fetch data for trace_id ${trace_id}:`, error)
  }

  // If feature is not found, or metadata is explicitly null (and you expect it for valid traces)
  if (!optimizationFeature) {
    notFound() // Triggers the Next.js 404 page
  }

  // Type assertion is safe here due to the check above or if your DB guarantees metadata for valid traces.
  // If experiment_metadata can be legitimately null for an existing trace_id, handle it gracefully.
  // Pass experiment metadata directly since modifications are now stored in diffContents
  const metadata = optimizationFeature.experiment_metadata as ExperimentMetadata | null
  const review_quality = optimizationFeature.review_quality as string | null
  const review_explanation = optimizationFeature.review_explanation as string | null
  // Determine repository full name for display
  const repoFullName =
    optimizationFeature.organization && optimizationFeature.repository
      ? `${optimizationFeature.organization}/${optimizationFeature.repository}`
      : metadata?.owner && metadata?.repo
        ? `${metadata.owner}/${metadata.repo}`
        : "N/A"

  return (
    <MonacoDiffViewer
      metadata={metadata} // Pass the potentially null metadata; component handles it
      repoFullName={repoFullName}
      traceId={trace_id}
      review_quality={review_quality || ""}
      review_explanation={review_explanation || ""}
    />
  )
}

// The main page component
export default async function TraceDetailsPage(props: TraceDetailsPageProps) {
  return (
    <Suspense fallback={<div className="animate-pulse p-8">Loading trace...</div>}>
      <TraceContent params={props.params} />
    </Suspense>
  )
}
