/**
 * 외부 DB 연결 정보 추가 스크립트
 * 비밀번호를 암호화하여 안전하게 저장
 */

import { Pool } from "pg";
import { CredentialEncryption } from "../src/utils/credentialEncryption";

async function addExternalDbConnection() {
  const pool = new Pool({
    host: process.env.DB_HOST || "localhost",
    port: parseInt(process.env.DB_PORT || "5432"),
    database: process.env.DB_NAME || "plm",
    user: process.env.DB_USER || "postgres",
    password: process.env.DB_PASSWORD || "ph0909!!",
  });

  // 환경 변수에서 암호화 키 가져오기 (없으면 기본값 사용)
  const encryptionKey =
    process.env.ENCRYPTION_SECRET_KEY || "default-secret-key-for-development";
  const encryption = new CredentialEncryption(encryptionKey);

  try {
    // 외부 DB 연결 정보 (실제 사용할 외부 DB 정보를 여기에 입력)
    const externalDbConnections = [
      {
        name: "운영_외부_PostgreSQL",
        description: "운영용 외부 PostgreSQL 데이터베이스",
        dbType: "postgresql",
        host: "39.117.244.52",
        port: 11132,
        databaseName: "plm",
        username: "postgres",
        password: "ph0909!!", // 이 값은 암호화되어 저장됩니다
        sslEnabled: false,
        isActive: true,
      },
      // 필요한 경우 추가 외부 DB 연결 정보를 여기에 추가
      // {
      //   name: "테스트_MySQL",
      //   description: "테스트용 MySQL 데이터베이스",
      //   dbType: "mysql",
      //   host: "test-mysql.example.com",
      //   port: 3306,
      //   databaseName: "testdb",
      //   username: "testuser",
      //   password: "testpass",
      //   sslEnabled: true,
      //   isActive: true,
      // },
    ];

    for (const conn of externalDbConnections) {
      // 비밀번호 암호화
      const encryptedPassword = encryption.encrypt(conn.password);

      // 중복 체크 (이름 기준)
      const existingResult = await pool.query(
        "SELECT id FROM flow_external_db_connection WHERE name = $1",
        [conn.name]
      );

      if (existingResult.rows.length > 0) {
        console.log(
          `⚠️  이미 존재하는 연결: ${conn.name} (ID: ${existingResult.rows[0].id})`
        );

        // 기존 연결 업데이트
        await pool.query(
          `UPDATE flow_external_db_connection 
           SET description = $1,
               db_type = $2,
               host = $3,
               port = $4,
               database_name = $5,
               username = $6,
               password_encrypted = $7,
               ssl_enabled = $8,
               is_active = $9,
               updated_at = NOW(),
               updated_by = 'system'
           WHERE name = $10`,
          [
            conn.description,
            conn.dbType,
            conn.host,
            conn.port,
            conn.databaseName,
            conn.username,
            encryptedPassword,
            conn.sslEnabled,
            conn.isActive,
            conn.name,
          ]
        );
        console.log(`✅ 연결 정보 업데이트 완료: ${conn.name}`);
      } else {
        // 새 연결 추가
        const result = await pool.query(
          `INSERT INTO flow_external_db_connection (
            name, 
            description, 
            db_type, 
            host, 
            port, 
            database_name, 
            username, 
            password_encrypted,
            ssl_enabled,
            is_active,
            created_by
          ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, 'system')
          RETURNING id`,
          [
            conn.name,
            conn.description,
            conn.dbType,
            conn.host,
            conn.port,
            conn.databaseName,
            conn.username,
            encryptedPassword,
            conn.sslEnabled,
            conn.isActive,
          ]
        );
        console.log(
          `✅ 새 연결 추가 완료: ${conn.name} (ID: ${result.rows[0].id})`
        );
      }

      // 연결 테스트
      console.log(`🔍 연결 테스트 중: ${conn.name}...`);
      const testPool = new Pool({
        host: conn.host,
        port: conn.port,
        database: conn.databaseName,
        user: conn.username,
        password: conn.password,
        ssl: conn.sslEnabled,
        connectionTimeoutMillis: 5000,
      });

      try {
        const client = await testPool.connect();
        await client.query("SELECT 1");
        client.release();
        console.log(`✅ 연결 테스트 성공: ${conn.name}`);
      } catch (testError: any) {
        console.error(`❌ 연결 테스트 실패: ${conn.name}`, testError.message);
      } finally {
        await testPool.end();
      }
    }

    console.log("\n✅ 모든 외부 DB 연결 정보 처리 완료");
  } catch (error) {
    console.error("❌ 외부 DB 연결 정보 추가 오류:", error);
    throw error;
  } finally {
    await pool.end();
  }
}

// 스크립트 실행
addExternalDbConnection()
  .then(() => {
    console.log("✅ 스크립트 완료");
    process.exit(0);
  })
  .catch((error) => {
    console.error("❌ 스크립트 실패:", error);
    process.exit(1);
  });
