// Pool MySQL partagé pour les Server Components / Route Handlers du panel.
// User dédié `superadmin_ro` avec GRANT SELECT (+ INSERT activities_log) — il
// ne peut pas muter les autres tables, ce qui plafonne la blast radius si le
// panel est compromis. Les mutations sensibles (suspend/resume tenant, billing)
// passent toujours par les endpoints HTTP de missioflow-app, jamais ici.

import "server-only";
import mysql, { type Pool, type PoolOptions } from "mysql2/promise";

// Singleton — Next.js peut hot-reload les modules en dev, on évite la fuite
// de pools en stockant la ref sur globalThis.
declare global {
  var __mfPanelPool: Pool | undefined;
}

function readPoolOptions(): PoolOptions {
  const host = process.env.DB_HOST;
  const port = process.env.DB_PORT;
  const user = process.env.DB_USER;
  const password = process.env.DB_PASSWORD;
  const database = process.env.DB_NAME;
  if (!host || !user || !password || !database) {
    throw new Error(
      "Variables DB manquantes — il faut DB_HOST, DB_USER, DB_PASSWORD, DB_NAME (cf. .env.example).",
    );
  }
  return {
    host,
    port: port ? Number(port) : 3306,
    user,
    password,
    database,
    connectionLimit: 5,
    waitForConnections: true,
    enableKeepAlive: true,
    timezone: "Z",
    dateStrings: false,
    charset: "utf8mb4",
  };
}

export function getPool(): Pool {
  if (!globalThis.__mfPanelPool) {
    globalThis.__mfPanelPool = mysql.createPool(readPoolOptions());
  }
  return globalThis.__mfPanelPool;
}

// Helper typé pour les SELECT. Toujours utiliser des `?` placeholders, jamais
// de concat avec input utilisateur — le user MySQL est SELECT-only mais une
// SQL injection peut quand même fuiter des données cross-tenant.
export async function query<T = Record<string, unknown>>(
  sql: string,
  params: unknown[] = [],
): Promise<T[]> {
  const pool = getPool();
  const [rows] = await pool.query(sql, params);
  return rows as T[];
}
