import pg from 'pg';
import { config } from '../config/config.js';
import { logger } from '../utils/logger.js';

const { Pool } = pg;

const columns = [
  'guid',
  'ts_ms',
  'write_ts_ms',
  'hotel_id',
  'room_id',
  'device_id',
  'direction',
  'cmd_word',
  'frame_id',
  'udp_raw',
  'action_type',
  'sys_lock_status',
  'report_count',
  'dev_type',
  'dev_addr',
  'dev_loop',
  'dev_data',
  'fault_count',
  'error_type',
  'error_data',
  'type_l',
  'type_h',
  'details',
  'extra',
  'loop_name'
];

export class DatabaseManager {
  constructor(dbConfig) {
    this.pool = new Pool({
      host: dbConfig.host,
      port: dbConfig.port,
      user: dbConfig.user,
      password: dbConfig.password,
      database: dbConfig.database,
      max: dbConfig.max,
      ssl: dbConfig.ssl
    });
  }

  async insertRows({ schema, table, rows }) {
    if (!rows || rows.length === 0) {
      return;
    }
    const values = [];
    const placeholders = rows.map((row, rowIndex) => {
      const offset = rowIndex * columns.length;
      columns.forEach((column) => {
        values.push(row[column] ?? null);
      });
      const params = columns.map((_, columnIndex) => `$${offset + columnIndex + 1}`);
      return `(${params.join(', ')})`;
    });
    const statement = `INSERT INTO ${schema}.${table} (${columns.join(', ')}) VALUES ${placeholders.join(', ')}`;
    try {
      await this.pool.query(statement, values);
    } catch (error) {
      logger.error('Database insert failed', {
        error: error?.message,
        schema,
        table,
        rowsLength: rows.length
      });
      throw error;
    }
  }

  async testConnection() {
    try {
      await this.pool.query('SELECT 1');
      return true;
    } catch (error) {
      return false;
    }
  }

  async close() {
    await this.pool.end();
  }
}

const dbManager = new DatabaseManager(config.db);
export default dbManager;
