import { Pool } from "pg"
import { PrismaPg } from "@prisma/adapter-pg"
import { PrismaClient } from "@/generated/prisma/client"

type PrismaClientInstance = InstanceType<typeof PrismaClient>
type TransactionCallback = Extract<
  Parameters<PrismaClientInstance["$transaction"]>[0],
  (tx: PrismaClientInstance) => Promise<unknown>
>
export type PrismaTransactionClient = TransactionCallback extends (tx: infer Client) => Promise<unknown>
  ? Client
  : never
export type PrismaDelegateClient = PrismaClientInstance

declare global {
  var prisma: PrismaClientInstance | undefined
  var pgPool: Pool | undefined
}

// PostgreSQL connection - requires DATABASE_URL environment variable
const databaseUrl = process.env.DATABASE_URL

if (!databaseUrl) {
  throw new Error("DATABASE_URL environment variable is required for PostgreSQL connection")
}

// Create PostgreSQL connection pool (reused in development to prevent connection exhaustion)
const pool = global.pgPool ?? new Pool({
  connectionString: databaseUrl,
})

// Create Prisma adapter with the pg pool
const adapter = new PrismaPg(pool)

// Create Prisma client with the adapter
export const prisma = global.prisma ?? new PrismaClient({ adapter })

if (process.env.NODE_ENV !== "production") {
  global.prisma = prisma
  global.pgPool = pool
  console.log("[prisma] Using PostgreSQL database with pg adapter")
}

export * from "@/generated/prisma/client"

type PrismaKnownErrorLike = {
  code?: string
  meta?: Record<string, unknown>
  message?: string
}

export function asPrismaKnownError(error: unknown): PrismaKnownErrorLike | null {
  if (!error || typeof error !== "object") {
    return null
  }
  const candidate = error as PrismaKnownErrorLike
  if (typeof candidate.code !== "string") {
    return null
  }
  return candidate
}
