// NOTE: cannot use `import 'server-only'` here — see logger/index.ts for
// the explanation (custom `tsx server.ts` bootstrap doesn't honor the
// `react-server` export condition, so the marker package crashes on boot).
import { drizzle } from 'drizzle-orm/node-postgres';
import { getPool } from './index';
import * as schema from './schema/schema';
import { childLogger } from '../logger';

const drizzleLog = childLogger('db.drizzle');

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const PHONE_RE = /^\+?[\d\s().-]{7,}$/;
const TOKEN_RE = /^(sk-|pk_|rk_|whsec_|pi_|cus_|sub_|sess_|tok_|sk_test_|sk_live_|Bearer\s|eyJ)/i;
const HEX_OR_B64_RE = /^[A-Za-z0-9+/=_-]{32,}$/;
const SECRET_PREFIX_RE = /^(password|passwd|secret|api[_-]?key|access[_-]?token|refresh[_-]?token|auth[_-]?token|bearer|cookie)[:=]/i;

function sanitizeParam(v: unknown): unknown {
  if (v === null || v === undefined) return v;
  if (typeof v === 'number' || typeof v === 'boolean' || typeof v === 'bigint') return v;
  if (v instanceof Date) return v.toISOString();
  if (Array.isArray(v)) return v.map(sanitizeParam);
  if (typeof v === 'object') return '[object]';
  if (typeof v !== 'string') return '[unknown]';
  const s = v;
  if (s.length === 0) return s;
  if (EMAIL_RE.test(s)) {
    const at = s.indexOf('@');
    return `${s.slice(0, Math.min(2, at))}***@${s.slice(at + 1)}`;
  }
  if (PHONE_RE.test(s) && s.replace(/\D/g, '').length >= 7) {
    const d = s.replace(/\D/g, '');
    return `***${d.slice(-4)}`;
  }
  if (TOKEN_RE.test(s) || SECRET_PREFIX_RE.test(s)) return '***REDACTED***';
  if (HEX_OR_B64_RE.test(s) && s.length >= 40) return `***${s.slice(-4)}`;
  if (s.length > 200) return `${s.slice(0, 80)}…[${s.length}ch]`;
  return s;
}

// Per-query SQL logging is OFF by default, even in development, because it
// floods the console and drowns out real signal. To turn it back on for a
// debugging session, either:
//   - set `LOG_SQL=1` in the environment, or
//   - set `LOG_LEVEL=trace` (drizzleLog will then emit at trace).
const SQL_LOG_OPT_IN = process.env.LOG_SQL === '1';

export const db = drizzle(getPool(), {
  schema,
  logger: {
    logQuery(query, params) {
      if (!SQL_LOG_OPT_IN && !drizzleLog.isLevelEnabled('trace')) return;
      const level = SQL_LOG_OPT_IN ? 'debug' : 'trace';
      drizzleLog[level]({ query, params: (params as unknown[]).map(sanitizeParam) }, 'sql');
    },
  },
});

export { schema };
export const {
  languages,
  translations,
  translationKeys,
  users,
  restaurants,
  branches,
  subscriptions,
  plans,
  passwordResetTokens,
  orders,
  bookings,
  customers,
  menuCategories,
  menuItems,
  menuModifierGroups,
  menuModifierOptions,
  phoneNumbers,
  conversations,
  aiAgentConfigs,
  aiAgents,
  llmModels,
  voiceModels,
  voiceProviders,
  knowledgeBase,
  staff,
  webhooks,
  apiKeys,
  notifications,
  supportTickets,
  blogPosts,
  callLogs,
  platformSettings,
  notificationPreferences,
  messageTemplates,
  auditLogs,
  webhookDeliveryLogs,
  llmProviders,
  restaurantApiKeys,
  telephoneSettings,
  sipRegistrations,
  sipCallSessions,
  widgetSettings,
  roles,
  alertSettings,
  agentKnowledgeBases,
  adminUsers,
} = schema;
