import { Suspense } from "react"
import { type JSX } from "react"
import { redirect } from "next/navigation"
import { auth0 } from "@/lib/auth0"
import { CreateApiKeyDialog } from "./dialog-create-api-key"
import { Separator } from "@/components/ui/separator"
import { ApiKeyTable, type ApiKeyWithOrg } from "./api-key-table"
import PostHogClient from "@/lib/posthog"
import { cacheLife, cacheTag } from "next/cache"
import { VS_CODE_KEY_NAME } from "@codeflash-ai/common"
import { Prisma } from "@prisma/client"
import { prisma } from "@/lib/prisma"

async function getCachedApiKeys(userId: string): Promise<ApiKeyWithOrg[]> {
  "use cache"
  cacheLife("frequent")
  cacheTag(`apikeys:${userId}`)

  // Rewrite as raw SQL with UNION to avoid bitmap OR merge and nested EXISTS subquery.
  // Branch 1: personal API keys (user_id match, no org)
  // Branch 2: org API keys (user is member of the org)

  const result = await prisma.$queryRaw<
    Array<{
      id: number
      key: string
      suffix: string
      name: string
      created_at: Date
      last_used: Date | null
      user_id: string | null
      organization_id: string | null
      tier: string | null
      org_id: string | null
      org_name: string | null
      owner_user_id: string | null
      owner_github_username: string | null
      owner_name: string | null
      owner_email: string | null
    }>
  >(Prisma.sql`
    SELECT
      ak.id, ak.key, ak.suffix, ak.name, ak.created_at, ak.last_used,
      ak.user_id, ak.organization_id, ak.tier,
      o.id as org_id, o.name as org_name,
      u.user_id as owner_user_id, u.github_username as owner_github_username,
      u.name as owner_name, u.email as owner_email
    FROM (
      -- Personal API keys
      SELECT id FROM cf_api_keys
      WHERE user_id = ${userId} AND organization_id IS NULL
      UNION
      -- Organization API keys (user is member)
      SELECT ak.id
      FROM cf_api_keys ak
      INNER JOIN organization_members om ON ak.organization_id = om.organization_id
      WHERE om.user_id = ${userId} AND ak.organization_id IS NOT NULL
    ) AS filtered_ids
    INNER JOIN cf_api_keys ak ON ak.id = filtered_ids.id
    LEFT JOIN organizations o ON ak.organization_id = o.id
    LEFT JOIN users u ON ak.user_id = u.user_id
    ORDER BY ak.created_at DESC
  `)

  // Map raw result to ApiKeyWithOrg format
  return (
    result as Array<{
      id: number
      key: string
      suffix: string
      name: string
      created_at: Date
      last_used: Date | null
      user_id: string | null
      organization_id: string | null
      tier: string | null
      org_id: string | null
      org_name: string | null
      owner_user_id: string | null
      owner_github_username: string | null
      owner_name: string | null
      owner_email: string | null
    }>
  ).map(row => ({
    id: row.id,
    key: row.key,
    suffix: row.suffix,
    name: row.name,
    created_at: row.created_at,
    last_used: row.last_used,
    user_id: row.user_id,
    organization_id: row.organization_id,
    tier: row.tier,
    organization: row.org_id
      ? {
          id: row.org_id,
          name: row.org_name!,
        }
      : null,
    user: row.owner_user_id
      ? {
          user_id: row.owner_user_id,
          github_username: row.owner_github_username!,
          name: row.owner_name,
          email: row.owner_email,
        }
      : null,
  }))
}

async function APIKeyContent(): Promise<JSX.Element> {
  const session = await auth0.getSession()
  // Auth handled by middleware + layout; redirect bails out of prerendering
  if (!session?.user) {
    redirect("/login")
  }
  const userId = session.user.sub

  const apiKeys = await getCachedApiKeys(userId)

  const posthog = PostHogClient()
  posthog?.capture({
    distinctId: userId,
    properties: { username: session.nickname },
    event: "webapp-loaded-api-keys",
  })

  posthog?.flush()

  return (
    <div>
      <h3 className="scroll-m-20 text-2xl font-semibold tracking-tight max-w-full pb-1">
        API Keys
      </h3>
      <Separator />
      {apiKeys.length === 0 ? (
        <>
          <p className="leading-7 mt-6">
            Welcome! Check out the{" "}
            <a
              href="https://docs.codeflash.ai/getting-started/local-installation"
              target="_blank"
              className="underline"
            >
              Getting Started
            </a>{" "}
            docs, or create your first API key below to start using Codeflash.
          </p>
          <p>
            For help with setting up Codeflash on your codebase, please check out the Docs or{" "}
            <a
              href="https://calendly.com/codeflash-saurabh/codeflash-setup"
              target="_blank"
              className="underline"
            >
              book a call
            </a>{" "}
            with the founder.
          </p>
        </>
      ) : (
        <>
          {" "}
          <p className="leading-7 mt-6">
            These API keys are used to authenticate your requests to Codeflash&apos;s AI services.
          </p>
          <ApiKeyTable
            apiKeys={apiKeys}
            vscodeKeyName={VS_CODE_KEY_NAME}
            currentUserId={userId}
          />{" "}
        </>
      )}

      <CreateApiKeyDialog />
    </div>
  )
}

export default async function APIKeyGenerator(): Promise<JSX.Element> {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <APIKeyContent />
    </Suspense>
  )
}
