import postgres from 'postgres';

/**
 * Canonical Postgres client for Deck Hearth.
 *
 * Supports:
 * - Homelab CT 102 (direct LAN — `postgresql://deckhearth@192.168.68.102:5432/deckhearth`)
 * - Supabase pooler (transaction mode, port 6543) if ever used
 *
 * Env:
 *   POSTGRES_URL — runtime (required)
 *   POSTGRES_URL_DIRECT — migrations (`npm run migrate`); on homelab, same as POSTGRES_URL
 *
 * API matches the former @vercel/postgres shape: `{ rows, rowCount }`.
 */

function resolveDatabaseUrl() {
  const url = process.env.POSTGRES_URL || process.env.DATABASE_URL;
  if (!url) {
    throw new Error('POSTGRES_URL is not set');
  }
  return url;
}

function resolveClientOptions(url) {
  const isSupabasePooler =
    url.includes('pgbouncer=true') || /:6543\//.test(url) || url.includes(':6543?');
  const isPrivateLan = /(?:^|@)(?:localhost|127\.0\.0\.1|192\.168\.|10\.|172\.(?:1[6-9]|2\d|3[01])\.)/.test(
    url
  );

  return {
    ssl: isPrivateLan ? false : 'require',
    max: 1,
    idle_timeout: 20,
    connect_timeout: 15,
    prepare: isSupabasePooler ? false : true,
  };
}

/** @type {import('postgres').Sql | null} */
let client = null;

function getClient() {
  if (!client) {
    const url = resolveDatabaseUrl();
    client = postgres(url, resolveClientOptions(url));
  }
  return client;
}

/**
 * Tagged-template SQL helper.
 * @param {TemplateStringsArray} strings
 * @param {...unknown} values
 * @returns {Promise<{ rows: Record<string, unknown>[], rowCount: number }>}
 */
export async function sql(strings, ...values) {
  const pg = getClient();
  const result = await pg(strings, ...values);
  const rows = Array.from(result);
  return {
    rows,
    rowCount: typeof result.count === 'number' ? result.count : rows.length,
  };
}

/** Close the pooled client (tests / long-running scripts). */
export async function closeSqlPool() {
  if (client) {
    await client.end({ timeout: 5 });
    client = null;
  }
}
