// auth/src/index.js
import chalk from 'chalk';
import express from 'express';
import expressLayouts from 'express-ejs-layouts';
import cors from 'cors';
import { Pool } from 'pg';
import bcrypt from'bcrypt';

// Rutas
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Variables de Entorno
import dotenv, { config } from 'dotenv';

// Obtención de la ruta de la variable de entorno correspondiente a NODE_ENV
try {
  if (process.env.NODE_ENV === 'development') {
    dotenv.config({ path: path.resolve(__dirname, '../.env.development' )});
    console.log(`Activando entorno de ->${chalk.green(` DEVELOPMENT `)}`);
  } else if (process.env.NODE_ENV === 'stage') {
    dotenv.config({ path: path.resolve(__dirname, '../.env.test' )});
    console.log(`Activando entorno de ->${chalk.yellow(` TESTING `)}`);
  } else if (process.env.NODE_ENV === 'production') {
    dotenv.config({ path: path.resolve(__dirname, '../.env.production' )});
    console.log(`Activando entorno de ->${chalk.red(` PRODUCTION `)}`);
  }
} catch (error) {
  console.log("A ocurrido un error al seleccionar el entorno. \nError: " + error);
}

// Configuración de renderizado
const app = express();
app.use(cors());
app.use(express.json());
app.set('trust proxy', true);
app.use(express.static(path.join(__dirname, 'pages')));


// Configuración de conexión PostgreSQL

const dbConfig = {
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASS,
  database: process.env.DB_NAME,
  port: process.env.DB_LOCAL_PORT
};

const pool = new Pool(dbConfig);


async function verificarConexion() {
  try {
    const client = await pool.connect();
    const res = await client.query('SELECT NOW() AS hora');
    console.log(`\nConexión con la base de datos ${chalk.green(process.env.DB_NAME)} fue exitosa.`);
    console.log('Fecha y hora actual de la base de datos:', res.rows[0].hora);
    client.release(); // liberar el cliente de nuevo al pool
  } catch (error) {
    console.error('Error al conectar con la base de datos al iniciar:', error.message);
    console.error(`Troubleshooting:\n1. Compruebe que las bases de datos se iniciaron correctamente.\n2. Verifique las credenciales y puertos de acceso a la base de datos.\n3. Si está conectandose a una base de datos externa a localhost, verifique las reglas del firewal de entrada y salida de ambos dispositivos.`);
  }
}


// === Servir páginas estáticas ===

app.get('/',(req, res) => res.sendFile(path.join(__dirname, 'pages', 'index.html')));

app.get('/planes', async (req, res) => {
  try {
    const { rows: [row] } = await pool.query(
      'SELECT api.get_planes_json($1) AS data;',
      [true]
    );
    res.type('application/json').send(row.data);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Error al cargar planes' });
  }
});


app.post('/api/registro', async (req, res) => {
  const {
    nombre_empresa,
    rut,
    correo,
    telefono,
    direccion,
    logo,
    clave_acceso,
    plan_id
  } = req.body;

  try {
    const client = await pool.connect();

    // 1. Hashear la contraseña
    const hash = await bcrypt.hash(clave_acceso, 10);

    // 2. Insertar el tenant
    const result = await client.query(`
      INSERT INTO tenant (
        nombre_empresa, rut, correo, telefono, direccion, logo,
        clave_acceso, plan_id, nombre_base_datos
      ) VALUES (
        $1, $2, $3, $4, $5, $6,
        $7, $8, 'TEMPORAL'
      )
      RETURNING uuid;
    `, [
      nombre_empresa, rut, correo, telefono, direccion, logo,
      hash, plan_id
    ]);

    const uuid = result.rows[0].uuid;
    const nombre_base_datos = `tenantdb_${uuid}`.replace(/-/g, '').substring(0, 24); // ajustamos para longitud segura

    // 3. Actualizar el campo nombre_base_datos
    await client.query(`
      UPDATE tenant SET nombre_base_datos = $1 WHERE uuid = $2
    `, [nombre_base_datos, uuid]);

    client.release();

    return res.status(201).json({
      message: 'Tenant registrado correctamente',
      uuid,
      nombre_base_datos
    });
  } catch (err) {
    console.error(err);
    return res.status(500).json({ error: 'Error al registrar tenant' });
  }
});


app.post('/api/login', async (req, res) => {
  const { correo, clave_acceso } = req.body;

  try {
    const client = await pool.connect();

    const result = await client.query(`
      SELECT uuid, clave_acceso, nombre_empresa, nombre_base_datos
      FROM tenant
      WHERE correo = $1 AND estado = true
    `, [correo]);

    client.release();

    if (result.rows.length === 0) {
      return res.status(401).json({ error: 'Correo no registrado o inactivo' });
    }

    const tenant = result.rows[0];
    const coincide = await bcrypt.compare(clave_acceso, tenant.clave_acceso);

    if (!coincide) {
      return res.status(401).json({ error: 'Clave incorrecta' });
    }

    return res.status(200).json({
      message: 'Login correcto',
      uuid: tenant.uuid,
      nombre_empresa: tenant.nombre_empresa,
      base_datos: tenant.nombre_base_datos
    });

  } catch (err) {
    console.error(err);
    return res.status(500).json({ error: 'Error al validar login' });
  }
});


// Colores personalizados
let primaryColor = chalk.hex('#'+`${process.env.COL_PRI}`);
let secondaryColor = chalk.hex('#'+`${process.env.COL_SEC}`);
// let backgroundColor = chalk.hex('#'+`${process.env.COL_BG}`);


app.use(expressLayouts);
// Iniciar servidor
app.listen( process.env.PORT, () => {
  console.log(`Servidor de ${chalk.yellow('autenticación')} de ${secondaryColor('SuiteCoffee')} corriendo en ${chalk.yellow(`http://localhost:${process.env.PORT}\n`)}` );
  console.log(chalk.grey(`Comprobando accesibilidad a la db ${chalk.green(process.env.DB_NAME)} del host ${chalk.white(`${process.env.DB_HOST}`)} ...`));
  verificarConexion();
});

app.get("/health", async (req, res) => {
  // Podés chequear DB aquí. 200 = healthy; 503 = not ready.
  res.status(200).json({ status: "ok" });
});