import express from 'express';
import cors from 'cors';
import { initDb, 
  getUsuarioByDni, getUsuarioById, getAllUsuarios, createUsuario, updateUsuario, deleteUsuario, verifyPassword, hashPassword,
  getAllPacientes, getPacienteById, createPaciente, updatePaciente, deletePaciente,
  getAllAreas, createArea, updateArea, deleteArea,
  getAllCamas, getCamaById, createCama, updateCama, deleteCama,
  getAllInternaciones, getInternacionById, createInternacion, updateInternacion, deleteInternacion,
  getAllEvoluciones, createEvolucion, updateEvolucion, deleteEvolucion,
  getAllLaboratorios, createLaboratorio, updateLaboratorio, deleteLaboratorio,
  getAllOtrosLaboratorios, createOtroLaboratorio, updateOtroLaboratorio, deleteOtroLaboratorio,
  getAllGlucemias, createGlucemia, updateGlucemia, deleteGlucemia,
  getAllAcidosBase, createAcidoBase, updateAcidoBase, deleteAcidoBase,
  getAllCultivos, createCultivo, updateCultivo, deleteCultivo,
  getAllEstudiosComplementarios, createEstudioComplementario, updateEstudioComplementario, deleteEstudioComplementario,
  getAllInterconsultas, createInterconsulta, updateInterconsulta, deleteInterconsulta,
  getAllAtb, createAtb, updateAtb, deleteAtb,
  getAllIndicaciones, createIndicacion, updateIndicacion, deleteIndicacion,
  getAllMovimientosIndicaciones, createMovimientoIndicacion,
  getAllPendientes, createPendiente, updatePendiente, deletePendiente,
  getValue, setValue,
  getDb, exportAllData, importAllData
} from './db-mongodb.js';

// Capture live logs in-memory
const logBuffer = [];
const originalLog = console.log;
const originalError = console.error;
const originalWarn = console.warn;

function addLog(type, args) {
  const message = args.map(arg => {
    if (typeof arg === 'object') {
      try { return JSON.stringify(arg); } catch { return String(arg); }
    }
    return String(arg);
  }).join(' ');
  const logEntry = `[${new Date().toISOString()}] [${type}] ${message}`;
  logBuffer.push(logEntry);
  if (logBuffer.length > 500) {
    logBuffer.shift();
  }
}

console.log = (...args) => {
  addLog('INFO', args);
  originalLog.apply(console, args);
};
console.error = (...args) => {
  addLog('ERROR', args);
  originalError.apply(console, args);
};
console.warn = (...args) => {
  addLog('WARN', args);
  originalWarn.apply(console, args);
};

const app = express();
app.use(cors({
  origin: true,
  credentials: true
}));
app.use(express.json({ limit: '50mb' }));

// UUID generator
function generateUUID() {
  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0;
    const v = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

// ========== STATE ENDPOINT (initial load) ==========
app.get('/api/state', async (req, res) => {
  try {
    const areasList = await getAllAreas();
    const usuariosList = await getAllUsuarios();
    const state = {
      pacientes: await getAllPacientes(),
      areas: areasList,
      grupos: areasList,
      camas: await getAllCamas(),
      internaciones: await getAllInternaciones(),
      evoluciones: (await getAllEvoluciones()).map(e => ({
        ...e,
        signosVitales: typeof e.signosVitales === 'string' ? JSON.parse(e.signosVitales) : e.signosVitales,
        examenFisico: typeof e.examenFisico === 'string' ? JSON.parse(e.examenFisico) : e.examenFisico
      })),
      laboratorios: (await getAllLaboratorios()).map(l => ({ ...l, resultados: typeof l.resultados === 'string' ? JSON.parse(l.resultados) : l.resultados })),
      otrosLaboratorios: await getAllOtrosLaboratorios(),
      glucemias: await getAllGlucemias(),
      acidosBase: await getAllAcidosBase(),
      cultivos: await getAllCultivos(),
      estudiosComplementarios: await getAllEstudiosComplementarios(),
      interconsultas: (await getAllInterconsultas()).map(ic => ({ ...ic, realizada: !!ic.realizada })),
      atb: await getAllAtb(),
      indicaciones: await getAllIndicaciones(),
      movimientosIndicaciones: await getAllMovimientosIndicaciones(),
      pendientes: await getAllPendientes(),
      usuarios: usuariosList.map(({ passwordHash, ...u }) => u),
      vistaActual: 'dashboard',
      currentInternacionId: null
    };
    res.json(state);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'failed to read state' });
  }
});

// ========== USUARIOS ==========
app.get('/api/usuarios', async (req, res) => {
  try {
    const usuarios = await getAllUsuarios();
    const usuariosSinPassword = usuarios.map(({ passwordHash, ...u }) => u);
    res.json(usuariosSinPassword);
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener usuarios' });
  }
});

app.post('/api/usuarios', async (req, res) => {
  try {
    const { apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, password, areaId } = req.body;
    
    if (!apellido || !nombre || !dni || !fechaNacimiento || !email || !rol || !password) {
      return res.status(400).json({ error: 'Todos los campos obligatorios deben estar presentes' });
    }
    
    const existente = await getUsuarioByDni(dni);
    if (existente) {
      return res.status(400).json({ error: 'Ya existe un usuario con ese DNI' });
    }
    
    const passwordHash = hashPassword(password);
    const usuario = {
      id: generateUUID(),
      apellido, nombre, dni, fechaNacimiento, email, rol,
      matriculaProfesional: matriculaProfesional || null,
      passwordHash,
      areaId: areaId || null,
      fechaCreacion: new Date().toISOString().split('T')[0]
    };
    
    await createUsuario(usuario);
    res.json({ ...usuario, passwordHash: undefined });
  } catch (err) {
    res.status(500).json({ error: 'Error al crear usuario' });
  }
});

app.put('/api/usuarios/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const { apellido, nombre, fechaNacimiento, email, rol, matriculaProfesional, areaId, password } = req.body;
    
    const usuario = await getUsuarioById(id);
    if (!usuario) {
      return res.status(404).json({ error: 'Usuario no encontrado' });
    }
    
    const datos = {};
    if (apellido !== undefined) datos.apellido = apellido;
    if (nombre !== undefined) datos.nombre = nombre;
    if (fechaNacimiento !== undefined) datos.fechaNacimiento = fechaNacimiento;
    if (email !== undefined) datos.email = email;
    if (rol !== undefined) datos.rol = rol;
    if (matriculaProfesional !== undefined) datos.matriculaProfesional = matriculaProfesional;
    if (areaId !== undefined) datos.areaId = areaId;
    if (password) datos.passwordHash = hashPassword(password);
    
    await updateUsuario(id, datos);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar usuario' });
  }
});

app.delete('/api/usuarios/:id', async (req, res) => {
  try {
    await deleteUsuario(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar usuario' });
  }
});

// ========== PACIENTES ==========
app.get('/api/pacientes', async (req, res) => {
  try {
    res.json(await getAllPacientes());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener pacientes' });
  }
});

app.post('/api/pacientes', async (req, res) => {
  try {
    const paciente = { ...req.body, id: req.body.id || generateUUID() };
    await createPaciente(paciente);
    res.json(paciente);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear paciente' });
  }
});

app.put('/api/pacientes/:id', async (req, res) => {
  try {
    await updatePaciente(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar paciente' });
  }
});

app.delete('/api/pacientes/:id', async (req, res) => {
  try {
    await deletePaciente(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar paciente' });
  }
});

// ========== AREAS & GRUPOS ==========
app.get(['/api/areas', '/api/grupos'], async (req, res) => {
  try {
    res.json(await getAllAreas());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener áreas/grupos' });
  }
});

app.post(['/api/areas', '/api/grupos'], async (req, res) => {
  try {
    const area = { ...req.body, id: req.body.id || generateUUID() };
    await createArea(area);
    res.json(area);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear área/grupo' });
  }
});

app.put(['/api/areas/:id', '/api/grupos/:id'], async (req, res) => {
  try {
    await updateArea(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar área/grupo' });
  }
});

app.delete(['/api/areas/:id', '/api/grupos/:id'], async (req, res) => {
  try {
    await deleteArea(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar área/grupo' });
  }
});

// ========== CAMAS ==========
app.get('/api/camas', async (req, res) => {
  try {
    res.json(await getAllCamas());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener camas' });
  }
});

app.put('/api/camas/:id', async (req, res) => {
  try {
    await updateCama(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar cama' });
  }
});

app.post('/api/camas', async (req, res) => {
  try {
    const cama = req.body;
    if (!cama.id) {
      cama.id = generateUUID();
    }
    await createCama(cama);
    res.json(cama);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear cama' });
  }
});

app.delete('/api/camas/:id', async (req, res) => {
  try {
    await deleteCama(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar cama' });
  }
});

// ========== INTERNACIONES ==========
app.get('/api/internaciones', async (req, res) => {
  try {
    res.json(await getAllInternaciones());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener internaciones' });
  }
});

app.post('/api/internaciones', async (req, res) => {
  try {
    const internacion = { ...req.body, id: req.body.id || generateUUID(), activa: req.body.activa !== undefined ? req.body.activa : true };
    await createInternacion(internacion);
    res.json(internacion);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear internacion' });
  }
});

app.put('/api/internaciones/:id', async (req, res) => {
  try {
    await updateInternacion(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar internacion' });
  }
});

app.delete('/api/internaciones/:id', async (req, res) => {
  try {
    await deleteInternacion(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar internacion' });
  }
});

// ========== EVOLUCIONES ==========
app.get('/api/evoluciones', async (req, res) => {
  try {
    res.json(await getAllEvoluciones());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener evoluciones' });
  }
});

app.post('/api/evoluciones', async (req, res) => {
  try {
    const evolucion = { ...req.body, id: req.body.id || generateUUID() };
    await createEvolucion(evolucion);
    res.json(evolucion);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear evolucion' });
  }
});

app.put('/api/evoluciones/:id', async (req, res) => {
  try {
    await updateEvolucion(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar evolucion' });
  }
});

app.delete('/api/evoluciones/:id', async (req, res) => {
  try {
    await deleteEvolucion(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar evolucion' });
  }
});

// ========== LABORATORIOS ==========
app.get('/api/laboratorios', async (req, res) => {
  try {
    res.json(await getAllLaboratorios());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener laboratorios' });
  }
});

app.post('/api/laboratorios', async (req, res) => {
  try {
    const laboratorio = { ...req.body, id: req.body.id || generateUUID() };
    await createLaboratorio(laboratorio);
    res.json(laboratorio);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear laboratorio' });
  }
});

app.put('/api/laboratorios/:id', async (req, res) => {
  try {
    await updateLaboratorio(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar laboratorio' });
  }
});

app.delete('/api/laboratorios/:id', async (req, res) => {
  try {
    await deleteLaboratorio(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar laboratorio' });
  }
});


// ========== OTROS LABORATORIOS ==========
app.get('/api/otros-laboratorios', async (req, res) => {
  try {
    const records = await getAllOtrosLaboratorios();
    res.json(records);
  } catch (error) {
    console.error('Error fetching otros-laboratorios:', error);
    res.status(500).json({ error: 'Failed to fetch otros-laboratorios' });
  }
});

app.post('/api/otros-laboratorios', async (req, res) => {
  try {
    const { pacienteId, fecha } = req.body;
    if (!pacienteId || !fecha) {
      return res.status(400).json({ error: 'pacienteId and fecha are required' });
    }

    const record = {
      id: generateUUID(),
      observaciones: '',
      ...req.body
    };

    const newRecord = await createOtroLaboratorio(record);
    res.status(201).json(newRecord);
  } catch (error) {
    console.error('Error creating otro laboratorio:', error);
    res.status(500).json({ error: 'Failed to create otro laboratorio' });
  }
});

app.put('/api/otros-laboratorios/:id', async (req, res) => {
  try {
    const result = await updateOtroLaboratorio(req.params.id, req.body);
    if (!result.success) return res.status(404).json({ error: 'Record not found' });
    res.json(result);
  } catch (error) {
    console.error('Error updating otro laboratorio:', error);
    res.status(500).json({ error: 'Failed to update otro laboratorio' });
  }
});

app.delete('/api/otros-laboratorios/:id', async (req, res) => {
  try {
    const result = await deleteOtroLaboratorio(req.params.id);
    if (!result.success) return res.status(404).json({ error: 'Record not found' });
    res.json({ message: 'Deleted successfully' });
  } catch (error) {
    console.error('Error deleting otro laboratorio:', error);
    res.status(500).json({ error: 'Failed to delete otro laboratorio' });
  }
});

// ========== GLUCEMIAS ==========
app.get('/api/glucemias', async (req, res) => {
  try {
    res.json(await getAllGlucemias());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener glucemias' });
  }
});

app.post('/api/glucemias', async (req, res) => {
  try {
    const glucemia = { ...req.body, id: req.body.id || generateUUID() };
    await createGlucemia(glucemia);
    res.json(glucemia);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear glucemia' });
  }
});

app.put('/api/glucemias/:id', async (req, res) => {
  try {
    await updateGlucemia(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar glucemia' });
  }
});

app.delete('/api/glucemias/:id', async (req, res) => {
  try {
    await deleteGlucemia(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar glucemia' });
  }
});

// ========== ACIDOS BASE ==========
app.get('/api/acid-os-base', async (req, res) => {
  try {
    res.json(await getAllAcidosBase());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener acidos base' });
  }
});

app.post('/api/acid-os-base', async (req, res) => {
  try {
    const acido = { ...req.body, id: req.body.id || generateUUID() };
    await createAcidoBase(acido);
    res.json(acido);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear acido base' });
  }
});

app.put('/api/acid-os-base/:id', async (req, res) => {
  try {
    await updateAcidoBase(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar acido base' });
  }
});

app.delete('/api/acid-os-base/:id', async (req, res) => {
  try {
    await deleteAcidoBase(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar acido base' });
  }
});

// ========== CULTIVOS ==========
app.get('/api/cultivos', async (req, res) => {
  try {
    res.json(await getAllCultivos());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener cultivos' });
  }
});

app.post('/api/cultivos', async (req, res) => {
  try {
    const cultivo = { ...req.body, id: req.body.id || generateUUID() };
    await createCultivo(cultivo);
    res.json(cultivo);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear cultivo' });
  }
});

app.put('/api/cultivos/:id', async (req, res) => {
  try {
    await updateCultivo(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar cultivo' });
  }
});

app.delete('/api/cultivos/:id', async (req, res) => {
  try {
    await deleteCultivo(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar cultivo' });
  }
});

// ========== ESTUDIOS COMPLEMENTARIOS ==========
app.get('/api/estudios-complementarios', async (req, res) => {
  try {
    res.json(await getAllEstudiosComplementarios());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener estudios' });
  }
});

app.post('/api/estudios-complementarios', async (req, res) => {
  try {
    const estudio = { ...req.body, id: req.body.id || generateUUID() };
    await createEstudioComplementario(estudio);
    res.json(estudio);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear estudio' });
  }
});

app.put('/api/estudios-complementarios/:id', async (req, res) => {
  try {
    await updateEstudioComplementario(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar estudio' });
  }
});

app.delete('/api/estudios-complementarios/:id', async (req, res) => {
  try {
    await deleteEstudioComplementario(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar estudio' });
  }
});

// ========== INTERCONSULTAS ==========
app.get('/api/interconsultas', async (req, res) => {
  try {
    res.json(await getAllInterconsultas());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener interconsultas' });
  }
});

app.post('/api/interconsultas', async (req, res) => {
  try {
    const interconsulta = { ...req.body, id: req.body.id || generateUUID() };
    await createInterconsulta(interconsulta);
    res.json(interconsulta);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear interconsulta' });
  }
});

app.put('/api/interconsultas/:id', async (req, res) => {
  try {
    await updateInterconsulta(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar interconsulta' });
  }
});

app.delete('/api/interconsultas/:id', async (req, res) => {
  try {
    await deleteInterconsulta(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar interconsulta' });
  }
});

// ========== ATB ==========
app.get('/api/atb', async (req, res) => {
  try {
    res.json(await getAllAtb());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener ATB' });
  }
});

app.post('/api/atb', async (req, res) => {
  try {
    const atb = { ...req.body, id: req.body.id || generateUUID() };
    await createAtb(atb);
    res.json(atb);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear ATB' });
  }
});

app.put('/api/atb/:id', async (req, res) => {
  try {
    await updateAtb(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar ATB' });
  }
});

app.delete('/api/atb/:id', async (req, res) => {
  try {
    await deleteAtb(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar ATB' });
  }
});

// ========== INDICACIONES ==========
app.get('/api/indicaciones', async (req, res) => {
  try {
    res.json(await getAllIndicaciones());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener indicaciones' });
  }
});

app.post('/api/indicaciones', async (req, res) => {
  try {
    const indicacion = { ...req.body, id: req.body.id || generateUUID() };
    await createIndicacion(indicacion);
    res.json(indicacion);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear indicacion' });
  }
});

app.put('/api/indicaciones/:id', async (req, res) => {
  try {
    await updateIndicacion(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar indicacion' });
  }
});

app.delete('/api/indicaciones/:id', async (req, res) => {
  try {
    await deleteIndicacion(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar indicacion' });
  }
});

// ========== MOVIMIENTOS INDICACIONES ==========
app.get('/api/movimientos-indicaciones', async (req, res) => {
  try {
    res.json(await getAllMovimientosIndicaciones());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener movimientos' });
  }
});

app.post('/api/movimientos-indicaciones', async (req, res) => {
  try {
    const movimiento = { ...req.body, id: req.body.id || generateUUID() };
    console.log('Creating movimiento:', movimiento);
    await createMovimientoIndicacion(movimiento);
    res.json(movimiento);
  } catch (err) {
    console.error('Error creating movimiento:', err);
    res.status(500).json({ error: err.message || 'Error al crear movimiento' });
  }
});

// ========== PENDIENTES ==========
app.get('/api/pendientes', async (req, res) => {
  try {
    res.json(await getAllPendientes());
  } catch (err) {
    res.status(500).json({ error: 'Error al obtener pendientes' });
  }
});

app.post('/api/pendientes', async (req, res) => {
  try {
    const pendiente = { ...req.body, id: req.body.id || generateUUID() };
    await createPendiente(pendiente);
    res.json(pendiente);
  } catch (err) {
    res.status(500).json({ error: 'Error al crear pendiente' });
  }
});

app.put('/api/pendientes/:id', async (req, res) => {
  try {
    await updatePendiente(req.params.id, req.body);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar pendiente' });
  }
});

app.delete('/api/pendientes/:id', async (req, res) => {
  try {
    await deletePendiente(req.params.id);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al eliminar pendiente' });
  }
});

// ========== AUTH ==========
app.post('/api/auth/login', async (req, res) => {
  try {
    const { dni, password } = req.body;
    if (!dni || !password) {
      return res.status(400).json({ error: 'DNI y contraseña requeridos' });
    }

    const usuario = await getUsuarioByDni(dni);
    if (!usuario) {
      return res.status(401).json({ error: 'Usuario no encontrado' });
    }
    
    const validPassword = await verifyPassword(dni, password);
    if (!validPassword) {
      return res.status(401).json({ error: 'Contraseña incorrecta' });
    }
    
    const { passwordHash, ...userWithoutPassword } = usuario;
    res.json(userWithoutPassword);
  } catch (err) {
    res.status(500).json({ error: 'Error en autenticación' });
  }
});

app.post('/api/auth/change-password', async (req, res) => {
  try {
    const { dni, oldPassword, newPassword } = req.body;
    if (!dni || !oldPassword || !newPassword) {
      return res.status(400).json({ error: 'Todos los campos son requeridos' });
    }
    
    const validPassword = await verifyPassword(dni, oldPassword);
    if (!validPassword) {
      return res.status(401).json({ error: 'Contraseña actual incorrecta' });
    }
    
    const newHash = hashPassword(newPassword);
    const usuario = await getUsuarioByDni(dni);
    if (usuario) {
      await updateUsuario(usuario.id, { passwordHash: newHash });
    }
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al cambiar contraseña' });
  }
});

app.put('/api/auth/update-email', async (req, res) => {
  try {
    const { dni, newEmail } = req.body;
    if (!dni || !newEmail) {
      return res.status(400).json({ error: 'DNI y email son requeridos' });
    }
    
    const usuario = await getUsuarioByDni(dni);
    if (usuario) {
      await updateUsuario(usuario.id, { email: newEmail });
    }
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al actualizar email' });
  }
});

// ========== ADMIN SYSTEM ENDPOINTS ==========

app.post('/api/admin/mongosh', async (req, res) => {
  try {
    const { command } = req.body;
    if (!command) {
      return res.status(400).json({ error: 'Comando requerido' });
    }

    const dbInstance = getDb();
    if (!dbInstance) {
      return res.json({ result: 'Advertencia: MongoDB no está conectado. Utilizando store en memoria. Las consultas de mongosh no están disponibles.', isMemStore: true });
    }

    const dbProxy = new Proxy(dbInstance, {
      get(target, prop) {
        if (typeof target[prop] !== 'undefined') {
          if (typeof target[prop] === 'function') {
            return target[prop].bind(target);
          }
          return target[prop];
        }
        return target.collection(prop);
      }
    });

    const { ObjectId } = await import('mongodb');

    const evalFn = new Function('db', 'ObjectId', `
      return (async () => {
        ${command.trim().includes('return') || command.trim().startsWith('{') || command.trim().includes(';') ? command : 'return (' + command + ')'}
      })();
    `);

    let finalResult = await evalFn(dbProxy, ObjectId);
    
    // Si el resultado es un cursor de MongoDB (ej. db.collection.find()), lo convertimos a array
    if (finalResult && typeof finalResult === 'object' && typeof finalResult.toArray === 'function') {
      finalResult = await finalResult.toArray();
    }
    
    res.json({ result: finalResult });
  } catch (err) {
    res.status(400).json({ error: err.message || String(err) });
  }
});

app.get('/api/admin/db/export', async (req, res) => {
  try {
    const dump = await exportAllData();
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Content-Disposition', 'attachment; filename=hospital_backup.json');
    res.json(dump);
  } catch (err) {
    res.status(500).json({ error: 'Error al exportar base de datos: ' + err.message });
  }
});

app.post('/api/admin/db/import', async (req, res) => {
  try {
    const dump = req.body;
    if (!dump || typeof dump !== 'object') {
      return res.status(400).json({ error: 'Formato de importación inválido' });
    }
    await importAllData(dump);
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: 'Error al importar base de datos: ' + err.message });
  }
});

app.get('/api/admin/logs', async (req, res) => {
  try {
    let fileLogs = '';
    try {
      const fs = await import('fs/promises');
      fileLogs = await fs.readFile('server_log.txt', 'utf8');
    } catch {
      // ignore
    }
    
    const memoryLogs = logBuffer.join('\n');
    const combined = [fileLogs, '\n--- LOGS DE LA SESION EN VIVO ---', memoryLogs].filter(Boolean).join('\n');
    res.setHeader('Content-Type', 'text/plain; charset=utf-8');
    res.send(combined);
  } catch (err) {
    res.status(500).send('Error al leer logs: ' + err.message);
  }
});

// Initialize DB and start server
const PORT = process.env.PORT || 4000;
const HOST = process.env.HOST || '0.0.0.0';

if (import.meta.url === `file://${process.argv[1]}`) {
  initDb()
    .then(() => {
      app.listen(PORT, HOST, () => {
        console.log(`Backend API running on http://${HOST}:${PORT}`);
      });
    })
    .catch((err) => {
      console.error('Failed to initialize MongoDB in standalone mode:', err);
      process.exit(1);
    });
}

export { initDb };
export default app;
