/**
 * Autenticacao Unificada — login/logout com bcrypt + express-session
 * Suporta roles: 'agente' | 'corporate' | 'admin'
 */
const bcrypt = require('bcrypt');
const db = require('./db-local');

const SALT_ROUNDS = 10;

/**
 * Cria um novo usuario (agente, corporate ou admin)
 */
async function createUser(email, senha, nome, role = 'agente', agenteId = 0, permissions = null) {
  const { DEFAULT_PERMISSIONS } = require('./panels');
  const hash = await bcrypt.hash(senha, SALT_ROUNDS);
  const perms = permissions || DEFAULT_PERMISSIONS[role] || DEFAULT_PERMISSIONS.agente;
  return db.prepare(
    'INSERT INTO agentes (email, senha_hash, agente_id, nome, role, permissions) VALUES (?, ?, ?, ?, ?, ?)'
  ).run(email, hash, agenteId, nome, role, JSON.stringify(perms));
}

/**
 * Cria agente (retrocompatibilidade)
 */
async function createAgente(email, senha, agenteId, nome) {
  return createUser(email, senha, nome, 'agente', agenteId);
}

/**
 * Autentica usuario por email/senha
 * Retorna usuario com role ou null se invalido
 */
async function authenticate(email, senha) {
  const row = db.prepare(
    'SELECT * FROM agentes WHERE email = ? AND ativo = 1'
  ).get(email);
  if (!row) return null;
  const match = await bcrypt.compare(senha, row.senha_hash);
  return match ? row : null;
}

/**
 * Middleware que verifica autenticacao e roles
 * Uso: requireRole() - qualquer usuario logado
 *      requireRole('admin') - apenas admins
 *      requireRole('corporate', 'admin') - corporate e admins
 *      requireRole('agente') - apenas agentes
 */
function requireRole(...roles) {
  return (req, res, next) => {
    if (!req.session?.user) {
      return res.redirect('/login');
    }
    if (roles.length && !roles.includes(req.session.user.role)) {
      return res.status(403).send('Acesso negado');
    }
    next();
  };
}

/**
 * Middleware que verifica permissao por painel
 * Uso: requirePermission('bi') - usuario deve ter painel 'bi' nas permissions
 */
function requirePermission(panelKey) {
  return (req, res, next) => {
    if (!req.session?.user) return res.redirect('/login');
    const perms = req.session.user.permissions || [];
    if (perms.includes(panelKey)) return next();
    return res.status(403).send('Acesso negado');
  };
}

/**
 * Middleware simples - apenas verifica se esta logado
 * Retrocompatibilidade com requireAuth
 */
function requireAuth(req, res, next) {
  if (req.session && req.session.user) return next();
  res.redirect('/login');
}

/**
 * Atualiza senha de usuario
 */
async function updatePassword(id, novaSenha) {
  const hash = await bcrypt.hash(novaSenha, SALT_ROUNDS);
  return db.prepare(
    'UPDATE agentes SET senha_hash = ? WHERE id = ?'
  ).run(hash, id);
}

module.exports = {
  createUser,
  createAgente,
  authenticate,
  requireAuth,
  requireRole,
  requirePermission,
  updatePassword
};
