'use strict';

const logger = require('../../utils/logger');
const { buildConfig: buildSoftRestaurantConfig, sql } = require('../../db');

let softRestaurantPool = null;
let softRestaurantConnecting = null;

let mysql;
try {
  mysql = require('mysql2/promise');
} catch (_) {
  mysql = null;
}

function buildRestCardConfig(overrides = {}) {
  return {
    host: overrides.host || process.env.RESTCARD_DB_HOST || '192.168.1.3',
    port: Number(overrides.port || process.env.RESTCARD_DB_PORT || 3306),
    user: overrides.user || process.env.RESTCARD_DB_USER || 'root',
    password: overrides.password || process.env.RESTCARD_DB_PASSWORD || '',
    database: overrides.database || process.env.RESTCARD_DB_NAME || 'restcard',
    connectTimeout: Number(process.env.RESTCARD_CONNECT_TIMEOUT || 8000),
    timezone: 'local',
    dateStrings: true,
    supportBigNumbers: true,
    bigNumberStrings: true,
  };
}

function safeConfig(config) {
  return {
    host: config.host,
    port: config.port,
    user: config.user,
    database: config.database,
  };
}

async function createRestCardConnection(overrides = {}) {
  if (!mysql) {
    const err = new Error('Dependencia mysql2 no disponible en el runtime');
    err.code = 'RESTCARD_MYSQL_DRIVER_MISSING';
    throw err;
  }
  const config = buildRestCardConfig(overrides);
  logger.info({ event: 'arkhon_card_restcard_connect', target: safeConfig(config) });
  return mysql.createConnection(config);
}

async function withRestCardConnection(work, overrides = {}) {
  const conn = await createRestCardConnection(overrides);
  try {
    return await work(conn);
  } finally {
    try { await conn.end(); } catch (_) {}
  }
}

async function getSoftRestaurantPool() {
  if (softRestaurantPool?.connected) return softRestaurantPool;
  if (softRestaurantConnecting) return softRestaurantConnecting;

  softRestaurantConnecting = (async () => {
    const config = buildSoftRestaurantConfig();
    config.pool = { max: 5, min: 0, idleTimeoutMillis: 30000, acquireTimeoutMillis: 30000 };
    const candidate = new sql.ConnectionPool(config);
    candidate.on('error', (err) => {
      logger.warn({ event: 'arkhon_card_softrestaurant_pool_error', error: err.message, code: err.code || null });
      if (softRestaurantPool === candidate) softRestaurantPool = null;
    });
    await candidate.connect();
    softRestaurantPool = candidate;
    logger.info({ event: 'arkhon_card_softrestaurant_pool_ready', database: config.database, max: config.pool.max });
    return candidate;
  })().finally(() => { softRestaurantConnecting = null; });

  return softRestaurantConnecting;
}

module.exports = {
  buildRestCardConfig,
  safeConfig,
  createRestCardConnection,
  withRestCardConnection,
  getSoftRestaurantPool,
  sql,
};
