import { PrismaClient } from '@prisma/client'

/**
 * 云原生数据库连接池配置
 * 
 * 核心目标：
 * - 防止Serverless扩容导致连接数超限
 * - 优雅关闭连接
 * - 支持本地和云端环境
 * 
 * 连接池计算公式：
 * connectionLimit = Math.floor(RDS_MAX_CONNECTIONS / MAX_INSTANCES) - 预留
 * 
 * 示例：
 * - RDS: 400最大连接
 * - SAE: 最多20个实例
 * - 每实例连接数: 400 / 20 = 20 - 预留 = 18
 * 
 * 环境变量：
 * - DATABASE_URL: 数据库连接URL（Prisma标准）
 * - DB_MAX_CONNECTIONS: RDS最大连接数（默认400）
 * - MAX_INSTANCES: SAE最大实例数（默认20）
 * - NODE_ENV: development | production
 */

/**
 * 计算连接池大小（工具函数）
 * 
 * ⚠️ 注意：Prisma不直接支持connectionLimit参数
 * 需要在DATABASE_URL中配置：
 * postgresql://user:pass@host:5432/db?connection_limit=20&pool_timeout=10
 * 
 * 本函数用于计算推荐的connection_limit值
 */
export function calculateConnectionLimit(): number {
  const dbMaxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
  const maxInstances = Number(process.env.MAX_INSTANCES) || 20
  const reservedConnections = 10 // 预留给管理任务和其他服务
  
  // 计算每实例可用连接数
  const connectionsPerInstance = Math.floor(dbMaxConnections / maxInstances) - reservedConnections
  
  // 确保至少有5个连接
  const connectionLimit = Math.max(connectionsPerInstance, 5)
  
  if (process.env.NODE_ENV === 'development') {
    console.log(`[Database] Connection pool calculation:`)
    console.log(`  - DB max connections: ${dbMaxConnections}`)
    console.log(`  - Max instances: ${maxInstances}`)
    console.log(`  - Recommended connections per instance: ${connectionLimit}`)
    console.log(`  💡 Add to DATABASE_URL: ?connection_limit=${connectionLimit}`)
  }
  
  return connectionLimit
}

// 创建Prisma Client实例（全局单例）
export const prisma = new PrismaClient({
  log: process.env.NODE_ENV === 'development' 
    ? ['query', 'info', 'warn', 'error'] 
    : ['error'],
  
  // ⭐ 云原生连接池配置
  datasources: {
    db: {
      url: process.env.DATABASE_URL,
    },
  },
  
  // Prisma 不直接支持 connectionLimit，但可以通过 DATABASE_URL 配置
  // 示例：postgresql://user:password@host:5432/db?connection_limit=20
})

/**
 * 数据库连接测试
 */
export async function testDatabaseConnection(): Promise<boolean> {
  try {
    await prisma.$connect()
    console.log('✅ 数据库连接成功！')
    
    // 获取数据库信息
    const result = await prisma.$queryRaw<Array<{ version: string }>>`SELECT version()`
    console.log('📊 数据库版本:', result[0]?.version.split(' ')[0], result[0]?.version.split(' ')[1])
    
    // 获取当前连接数
    const connectionCount = await getDatabaseConnectionCount()
    console.log('📊 当前数据库连接数:', connectionCount)
    
    return true
  } catch (error) {
    console.error('❌ 数据库连接失败:', error)
    return false
  }
}

/**
 * 获取当前数据库连接数
 * 用于监控和告警
 */
export async function getDatabaseConnectionCount(): Promise<number> {
  try {
    const result = await prisma.$queryRaw<Array<{ count: bigint }>>`
      SELECT count(*) as count 
      FROM pg_stat_activity 
      WHERE datname = current_database()
    `
    return Number(result[0]?.count || 0)
  } catch (error) {
    console.error('❌ 获取数据库连接数失败:', error)
    return 0
  }
}

/**
 * 优雅关闭数据库连接
 * 
 * 在以下情况下调用：
 * - 进程正常退出
 * - 收到SIGTERM信号（Serverless实例停止）
 * - 收到SIGINT信号（Ctrl+C）
 */
export async function closeDatabaseConnection(): Promise<void> {
  try {
    console.log('[Database] Closing connections...')
    await prisma.$disconnect()
    console.log('[Database] ✅ 连接已关闭')
  } catch (error) {
    console.error('[Database] ❌ 关闭连接失败:', error)
  }
}

// ⭐ 云原生：优雅关闭逻辑
let isShuttingDown = false

/**
 * 处理优雅关闭
 */
async function gracefulShutdown(signal: string): Promise<void> {
  if (isShuttingDown) {
    console.log(`[Database] Already shutting down, ignoring ${signal}`)
    return
  }
  
  isShuttingDown = true
  console.log(`[Database] Received ${signal}, shutting down gracefully...`)
  
  try {
    await closeDatabaseConnection()
    process.exit(0)
  } catch (error) {
    console.error('[Database] Error during shutdown:', error)
    process.exit(1)
  }
}

// 监听进程信号
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'))  // Serverless实例停止
process.on('SIGINT', () => gracefulShutdown('SIGINT'))    // Ctrl+C
process.on('beforeExit', async () => {
  if (!isShuttingDown) {
    await closeDatabaseConnection()
  }
})




