import { Pool, PoolClient, QueryResult } from 'pg';
import config from '../config/environment';

/**
 * PostgreSQL Raw Query 서비스
 * Prisma 대신 직접 pg 라이브러리를 사용
 */
export class PostgreSQLService {
  private static pool: Pool;

  /**
   * 데이터베이스 연결 풀 초기화
   */
  static initialize() {
    if (!this.pool) {
      this.pool = new Pool({
        connectionString: config.databaseUrl,
        max: 20, // 최대 연결 수
        idleTimeoutMillis: 30000,
        connectionTimeoutMillis: 2000,
      });

      // 연결 풀 이벤트 리스너
      this.pool.on('connect', () => {
        console.log('🔗 PostgreSQL 연결 성공');
      });

      this.pool.on('error', (err) => {
        console.error('❌ PostgreSQL 연결 오류:', err);
      });
    }
  }

  /**
   * 연결 풀 가져오기
   */
  static getPool(): Pool {
    if (!this.pool) {
      this.initialize();
    }
    return this.pool;
  }

  /**
   * 단일 쿼리 실행
   */
  static async query(text: string, params?: any[]): Promise<QueryResult> {
    const pool = this.getPool();
    const start = Date.now();
    
    try {
      const result = await pool.query(text, params);
      const duration = Date.now() - start;
      
      if (config.debug) {
        console.log('🔍 Query executed:', { text, duration: `${duration}ms`, rows: result.rowCount });
      }
      
      return result;
    } catch (error) {
      console.error('❌ Query error:', { text, params, error });
      throw error;
    }
  }

  /**
   * 트랜잭션 실행
   */
  static async transaction<T>(callback: (client: PoolClient) => Promise<T>): Promise<T> {
    const pool = this.getPool();
    const client = await pool.connect();
    
    try {
      await client.query('BEGIN');
      const result = await callback(client);
      await client.query('COMMIT');
      return result;
    } catch (error) {
      await client.query('ROLLBACK');
      throw error;
    } finally {
      client.release();
    }
  }

  /**
   * 연결 테스트
   */
  static async testConnection(): Promise<boolean> {
    try {
      const result = await this.query('SELECT NOW() as current_time');
      console.log('✅ PostgreSQL 연결 테스트 성공:', result.rows[0]);
      return true;
    } catch (error) {
      console.error('❌ PostgreSQL 연결 테스트 실패:', error);
      return false;
    }
  }

  /**
   * 연결 풀 종료
   */
  static async close(): Promise<void> {
    if (this.pool) {
      await this.pool.end();
      console.log('🔒 PostgreSQL 연결 풀 종료');
    }
  }
}

// 애플리케이션 시작 시 초기화
PostgreSQLService.initialize();

// 프로세스 종료 시 연결 정리
process.on('SIGINT', async () => {
  await PostgreSQLService.close();
  process.exit(0);
});

process.on('SIGTERM', async () => {
  await PostgreSQLService.close();
  process.exit(0);
});

process.on('beforeExit', async () => {
  await PostgreSQLService.close();
});
