import { drizzle } from "drizzle-orm/node-postgres"
import { Pool, types } from "pg"
import * as schema from "./schema"

// ── pg type parsers ───────────────────────────────────────────────
// Make the driver return the value shapes the app relies on across its
// ~hundreds of read sites:
//   numeric  -> JS number
//   date     -> "YYYY-MM-DD" string
//   timestamp / timestamptz -> ISO 8601 string
types.setTypeParser(1700, (v) => (v === null ? null : parseFloat(v))) // numeric
types.setTypeParser(1082, (v) => v) // date (identity string)
types.setTypeParser(1114, (v) => (v === null ? null : new Date(v + "Z").toISOString())) // timestamp
types.setTypeParser(1184, (v) => (v === null ? null : new Date(v).toISOString())) // timestamptz

const globalForDb = globalThis as unknown as { pool?: Pool }

// ── TLS policy ────────────────────────────────────────────────────
// Production MUST use verified TLS so credentials and tenant data are
// never sent in plaintext over the network. The default below is
// encrypted + certificate-verified. Behavior is controlled explicitly
// via DATABASE_SSL:
//   "disable"   -> ssl: false (ONLY for local dev / unix-socket Postgres)
//   "no-verify" -> encrypted but unverified (self-signed certs)
//   "require" / unset / default -> encrypted + verified (recommended)
// When verifying, an optional custom CA can be supplied via DATABASE_CA.
function resolveSsl(): false | { rejectUnauthorized: boolean; ca?: string } {
  switch (process.env.DATABASE_SSL) {
    case "disable":
      return false
    case "no-verify":
      return { rejectUnauthorized: false }
    default: {
      const ca = process.env.DATABASE_CA
      return ca
        ? { rejectUnauthorized: true, ca }
        : { rejectUnauthorized: true }
    }
  }
}

export const pool =
  globalForDb.pool ??
  new Pool({
    connectionString: process.env.DATABASE_URL,
    ssl: resolveSsl(),
  })

if (process.env.NODE_ENV !== "production") globalForDb.pool = pool

export const db = drizzle(pool, { schema })

export { schema }
