import { MongoClient, ObjectId } from 'mongodb';
import bcrypt from 'bcryptjs';
const { compareSync, hashSync } = bcrypt;

export 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);
  });
}

function getMongoUri() {
  const envUri = (process.env.MONGODB_URI || '').trim();
  if (envUri.startsWith('mongodb://') || envUri.startsWith('mongodb+srv://')) {
    return envUri;
  }
  return 'mongodb://127.0.0.1:27017';
}

const DB_NAME = process.env.DB_NAME || 'hospital';

let client;
let db = null;

// Helper to create default admin object from env or fallback
function createDefaultAdminUser() {
  const adminDni = process.env.ADMIN_DNI || '12345678';
  const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
  const adminNombre = process.env.ADMIN_NOMBRE || 'Sistema';
  const adminApellido = process.env.ADMIN_APELLIDO || 'Administrador';
  const adminEmail = process.env.ADMIN_EMAIL || 'admin@hospital.local';
  
  return {
    id: 'admin-default',
    apellido: adminApellido,
    nombre: adminNombre,
    dni: adminDni,
    fechaNacimiento: '1990-01-01',
    email: adminEmail,
    rol: 'admin',
    passwordHash: hashSync(adminPassword, 10),
    fechaCreacion: new Date().toISOString().split('T')[0]
  };
}

// In-memory fallback store when DB is not connected
const memStore = {
  usuarios: [createDefaultAdminUser()],
  pacientes: [],
  areas: [],
  camas: [],
  internaciones: [],
  evoluciones: [],
  laboratorios: [],
  otrosLaboratorios: [],
  glucemias: [],
  acidosbase: [],
  cultivos: [],
  estudiosComplementarios: [],
  interconsultas: [],
  atb: [],
  indicaciones: [],
  movimientos_indicaciones: [],
  pendientes: [],
  kv: {}
};

export async function initDb() {
  try {
    const uri = getMongoUri();
    client = new MongoClient(uri, {
      connectTimeoutMS: 5000,
      serverSelectionTimeoutMS: 5000
    });
    await client.connect();
    db = client.db(DB_NAME);
    console.log(`Connected to MongoDB database: ${DB_NAME}`);

    // Create unique index for users and patients DNI
    await db.collection('usuarios').createIndex({ dni: 1 }, { unique: true });
    await db.collection('pacientes').createIndex({ dni: 1 }, { unique: true });
    await db.collection('areas').createIndex({ nombre: 1 }, { unique: true });
    
    // Check if default admin exists in MongoDB in production
    const adminDni = process.env.ADMIN_DNI || '12345678';
    const adminExists = await db.collection('usuarios').findOne({ dni: adminDni });
    
    if (!adminExists) {
      const defaultAdmin = createDefaultAdminUser();
      await db.collection('usuarios').insertOne(defaultAdmin);
      console.log(`Default admin created/ensured in database: DNI ${adminDni}`);
    }
  } catch (error) {
    console.error('Failed to initialize MongoDB (will use in-memory store):', error.message || error);
    db = null;
  }
}

// Helper to remove MongoDB's internal _id from returned objects to keep schema clean
function cleanDoc(doc) {
  if (!doc) return null;
  const { _id, ...rest } = doc;
  if (!rest.id && _id) {
    rest.id = _id.toString();
  }
  return rest;
}

function cleanDocs(docs) {
  if (!docs) return [];
  return docs.map(cleanDoc);
}

// ========== USUARIOS ==========
export async function getUsuarioByDni(dni) {
  const dniStr = String(dni).trim();

  if (db) {
    const user = await db.collection('usuarios').findOne({ dni: dniStr });
    return cleanDoc(user);
  }
  return memStore.usuarios.find(u => String(u.dni) === dniStr) || null;
}

export async function getUsuarioById(id) {
  if (db) {
    const user = await db.collection('usuarios').findOne({ id });
    return cleanDoc(user);
  }
  return memStore.usuarios.find(u => u.id === id) || null;
}

export async function getAllUsuarios() {
  if (db) {
    const users = await db.collection('usuarios').find().sort({ apellido: 1, nombre: 1 }).toArray();
    return cleanDocs(users);
  }
  return [...memStore.usuarios];
}

export async function createUsuario(usuario) {
  if (db) {
    await db.collection('usuarios').insertOne(usuario);
  } else {
    memStore.usuarios.push(usuario);
  }
}

export async function updateUsuario(id, datos) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(datos)) {
    if (val !== undefined) {
      updateDoc[key] = val;
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('usuarios').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.usuarios.findIndex(u => u.id === id);
    if (idx !== -1) {
      memStore.usuarios[idx] = { ...memStore.usuarios[idx], ...updateDoc };
    }
  }
}

export async function deleteUsuario(id) {
  if (db) {
    await db.collection('usuarios').deleteOne({ id });
  } else {
    memStore.usuarios = memStore.usuarios.filter(u => u.id !== id);
  }
}

export async function verifyPassword(dni, password) {
  const dniStr = String(dni).trim();

  if (db) {
    const user = await db.collection('usuarios').findOne({ dni: dniStr });
    if (!user || !user.passwordHash) return false;
    return compareSync(password, user.passwordHash);
  }
  const user = memStore.usuarios.find(u => String(u.dni) === dniStr);
  if (!user || !user.passwordHash) return false;
  return compareSync(password, user.passwordHash);
}

export function hashPassword(password) {
  return hashSync(password, 10);
}

// ========== PACIENTES ==========
export async function getAllPacientes() {
  if (db) {
    const pacientes = await db.collection('pacientes').find().toArray();
    return cleanDocs(pacientes);
  }
  return [...memStore.pacientes];
}

export async function getPacienteById(id) {
  if (db) {
    const paciente = await db.collection('pacientes').findOne({ id });
    return cleanDoc(paciente);
  }
  return memStore.pacientes.find(p => p.id === id) || null;
}

export async function createPaciente(paciente) {
  if (db) {
    await db.collection('pacientes').insertOne(paciente);
  } else {
    memStore.pacientes.push(paciente);
  }
}

export async function updatePaciente(id, datos) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(datos)) {
    if (key !== 'id' && val !== undefined) {
      updateDoc[key] = val;
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('pacientes').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.pacientes.findIndex(p => p.id === id);
    if (idx !== -1) {
      memStore.pacientes[idx] = { ...memStore.pacientes[idx], ...updateDoc };
    }
  }
}

export async function deletePaciente(id) {
  if (db) {
    await db.collection('pacientes').deleteOne({ id });
  } else {
    memStore.pacientes = memStore.pacientes.filter(p => p.id !== id);
  }
}

// ========== AREAS / GRUPOS ==========
export async function getAllAreas() {
  if (db) {
    const areas = await db.collection('areas').find().toArray();
    return cleanDocs(areas);
  }
  return [...memStore.areas];
}

export async function createArea(area) {
  if (db) {
    await db.collection('areas').insertOne(area);
  } else {
    memStore.areas.push(area);
  }
}

export async function updateArea(id, datos) {
  if (db) {
    if (datos.nombre !== undefined) {
      await db.collection('areas').updateOne({ id }, { $set: { nombre: datos.nombre } });
    }
  } else {
    const idx = memStore.areas.findIndex(a => a.id === id);
    if (idx !== -1) {
      memStore.areas[idx] = { ...memStore.areas[idx], ...datos };
    }
  }
}

export async function deleteArea(id) {
  if (db) {
    await db.collection('areas').deleteOne({ id });
  } else {
    memStore.areas = memStore.areas.filter(a => a.id !== id);
  }
}

// ========== CAMAS ==========
export async function getAllCamas() {
  if (db) {
    const camas = await db.collection('camas').find().toArray();
    return cleanDocs(camas);
  }
  return [...memStore.camas];
}

export async function getCamaById(id) {
  if (db) {
    const cama = await db.collection('camas').findOne({ id });
    return cleanDoc(cama);
  }
  return memStore.camas.find(c => c.id === id) || null;
}

export async function createCama(cama) {
  const id = cama.id || generateUUID();
  const doc = {
    id,
    numero: cama.numero,
    areaId: cama.areaId || cama.grupoId,
    grupoId: cama.grupoId || cama.areaId,
    tipo: cama.tipo || 'Estándar',
    estado: cama.estado || 'Disponible',
    pacienteId: cama.pacienteId || null,
    internacionId: cama.internacionId || null
  };
  if (db) {
    await db.collection('camas').insertOne(doc);
  } else {
    memStore.camas.push(doc);
  }
}

export async function updateCama(id, updates) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(updates)) {
    if (val !== undefined) {
      updateDoc[key] = val;
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('camas').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.camas.findIndex(c => c.id === id);
    if (idx !== -1) {
      memStore.camas[idx] = { ...memStore.camas[idx], ...updateDoc };
    }
  }
}

export async function deleteCama(id) {
  if (db) {
    await db.collection('camas').deleteOne({ id });
  } else {
    memStore.camas = memStore.camas.filter(c => c.id !== id);
  }
}

// ========== INTERNACIONES ==========
export async function getAllInternaciones() {
  if (db) {
    const internaciones = await db.collection('internaciones').find().toArray();
    return cleanDocs(internaciones).map(i => ({ ...i, activa: !!i.activa }));
  }
  return memStore.internaciones.map(i => ({ ...i, activa: !!i.activa }));
}

export async function getInternacionById(id) {
  if (!id) return null;
  const idStr = String(id).trim();
  if (db) {
    let internacion = await db.collection('internaciones').findOne({ id: idStr });
    if (!internacion && ObjectId.isValid(idStr)) {
      try {
        internacion = await db.collection('internaciones').findOne({ _id: new ObjectId(idStr) });
      } catch {
        // ignore invalid objectid
      }
    }
    if (internacion) internacion.activa = !!internacion.activa;
    return cleanDoc(internacion);
  }
  const internacion = memStore.internaciones.find(i => i.id === idStr || String(i.id).trim() === idStr);
  if (!internacion) return null;
  return { ...internacion, activa: !!internacion.activa };
}

export async function createInternacion(internacion) {
  const doc = {
    id: internacion.id,
    pacienteId: internacion.pacienteId,
    camaId: internacion.camaId || null,
    areaId: internacion.areaId || internacion.grupoId || null,
    grupoId: internacion.grupoId || internacion.areaId || null,
    fechaIngresoHospital: internacion.fechaIngresoHospital || null,
    fechaIngresoClinica: internacion.fechaIngresoClinica || null,
    fechaEgreso: internacion.fechaEgreso || null,
    diagnosticoIngreso: internacion.diagnosticoIngreso || null,
    motivoConsulta: internacion.motivoConsulta || null,
    enfermedadActual: internacion.enfermedadActual || null,
    antecedentesEnfermedadActual: internacion.antecedentesEnfermedadActual || null,
    diagnosticoEgreso: internacion.diagnosticoEgreso || null,
    medicoIngresante: internacion.medicoIngresante || null,
    motivoEgreso: internacion.motivoEgreso || null,
    servicioAlQuePasa: internacion.servicioAlQuePasa || null,
    activa: internacion.activa ? 1 : 0,
    apache: internacion.apache || null,
    derivacion: internacion.derivacion || null
  };
  if (db) {
    await db.collection('internaciones').insertOne(doc);
  } else {
    memStore.internaciones.push(doc);
  }
}

export async function updateInternacion(id, datos) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(datos)) {
    if (val !== undefined) {
      if (key === 'activa') {
        updateDoc.activa = val ? 1 : 0;
      } else {
        updateDoc[key] = val;
      }
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('internaciones').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.internaciones.findIndex(i => i.id === id);
    if (idx !== -1) {
      memStore.internaciones[idx] = { ...memStore.internaciones[idx], ...updateDoc };
    }
  }
}

export async function deleteInternacion(id) {
  if (db) {
    await db.collection('internaciones').deleteOne({ id });
  } else {
    memStore.internaciones = memStore.internaciones.filter(i => i.id !== id);
  }
}

// ========== EVOLUCIONES ==========
export async function getAllEvoluciones() {
  if (db) {
    const evoluciones = await db.collection('evoluciones').find().toArray();
    return cleanDocs(evoluciones);
  }
  return [...memStore.evoluciones];
}

export async function createEvolucion(evolucion) {
  const doc = {
    id: evolucion.id,
    internacionId: evolucion.internacionId,
    fecha: evolucion.fecha,
    hora: evolucion.hora || '',
    medico: evolucion.medico || '',
    signosVitales: typeof evolucion.signosVitales === 'string' ? evolucion.signosVitales : JSON.stringify(evolucion.signosVitales || {}),
    examenFisico: typeof evolucion.examenFisico === 'string' ? evolucion.examenFisico : JSON.stringify(evolucion.examenFisico || {}),
    novedades: evolucion.novedades || '',
    comentarios: evolucion.comentarios || evolucion.comentario || '',
    pendientes: evolucion.pendientes || ''
  };
  if (db) {
    await db.collection('evoluciones').insertOne(doc);
  } else {
    memStore.evoluciones.push(doc);
  }
}

export async function updateEvolucion(id, datos) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(datos)) {
    if (val !== undefined) {
      if (key === 'comentario') {
        updateDoc.comentarios = val;
      } else if (key === 'signosVitales' || key === 'examenFisico') {
        updateDoc[key] = typeof val === 'string' ? val : JSON.stringify(val);
      } else {
        updateDoc[key] = val;
      }
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('evoluciones').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.evoluciones.findIndex(e => e.id === id);
    if (idx !== -1) {
      memStore.evoluciones[idx] = { ...memStore.evoluciones[idx], ...updateDoc };
    }
  }
}

export async function deleteEvolucion(id) {
  if (db) {
    await db.collection('evoluciones').deleteOne({ id });
  } else {
    memStore.evoluciones = memStore.evoluciones.filter(e => e.id !== id);
  }
}

// ========== LABORATORIOS ==========
export async function getAllLaboratorios() {
  if (db) {
    const laboratorios = await db.collection('laboratorios').find().toArray();
    return cleanDocs(laboratorios);
  }
  return [...memStore.laboratorios];
}

export async function createLaboratorio(laboratorio) {
  const doc = {
    id: laboratorio.id,
    pacienteId: laboratorio.pacienteId,
    internacionId: laboratorio.internacionId || null,
    fecha: laboratorio.fecha,
    hora: laboratorio.hora || null,
    tipo: laboratorio.tipo,
    resultados: typeof laboratorio.resultados === 'string' ? laboratorio.resultados : JSON.stringify(laboratorio.resultados || {}),
    observaciones: laboratorio.observaciones || null,
    medicoSolicitante: laboratorio.medicoSolicitante || null
  };
  if (db) {
    await db.collection('laboratorios').insertOne(doc);
  } else {
    memStore.laboratorios.push(doc);
  }
}

export async function updateLaboratorio(id, datos) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(datos)) {
    if (val !== undefined) {
      if (key === 'resultados') {
        updateDoc.resultados = typeof val === 'string' ? val : JSON.stringify(val);
      } else {
        updateDoc[key] = val;
      }
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('laboratorios').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.laboratorios.findIndex(l => l.id === id);
    if (idx !== -1) {
      memStore.laboratorios[idx] = { ...memStore.laboratorios[idx], ...updateDoc };
    }
  }
}

export async function deleteLaboratorio(id) {
  if (db) {
    await db.collection('laboratorios').deleteOne({ id });
  } else {
    memStore.laboratorios = memStore.laboratorios.filter(l => l.id !== id);
  }
}

// ========== GLUCEMIAS ==========
export async function getAllGlucemias() {
  if (db) {
    const glucemias = await db.collection('glucemias').find().toArray();
    return cleanDocs(glucemias);
  }
  return [...memStore.glucemias];
}

export async function createGlucemia(glucemia) {
  if (db) {
    await db.collection('glucemias').insertOne(glucemia);
  } else {
    memStore.glucemias.push(glucemia);
  }
}

export async function updateGlucemia(id, datos) {
  if (db) {
    await db.collection('glucemias').updateOne({ id }, { $set: datos });
  } else {
    const idx = memStore.glucemias.findIndex(g => g.id === id);
    if (idx !== -1) {
      memStore.glucemias[idx] = { ...memStore.glucemias[idx], ...datos };
    }
  }
}

export async function deleteGlucemia(id) {
  if (db) {
    await db.collection('glucemias').deleteOne({ id });
  } else {
    memStore.glucemias = memStore.glucemias.filter(g => g.id !== id);
  }
}

// ========== ACIDOS BASE ==========
export async function getAllAcidosBase() {
  if (db) {
    const acidos = await db.collection('acidosbase').find().toArray();
    return cleanDocs(acidos);
  }
  return [...memStore.acidosbase];
}

export async function createAcidoBase(acido) {
  const doc = {
    id: acido.id,
    pacienteId: acido.pacienteId,
    internacionId: acido.internacionId || null,
    fecha: acido.fecha,
    hora: acido.hora || null,
    ph: acido.ph !== undefined ? Number(acido.ph) : null,
    pco2: acido.pco2 !== undefined ? Number(acido.pco2) : null,
    po2: acido.po2 !== undefined ? Number(acido.po2) : null,
    hco3: acido.hco3 !== undefined ? Number(acido.hco3) : null,
    be: acido.be !== undefined ? Number(acido.be) : null,
    sato2: acido.sato2 !== undefined ? Number(acido.sato2) : null,
    lactato: acido.lactato !== undefined ? Number(acido.lactato) : null,
    interpretacion: acido.interpretacion || null,
    fio2: acido.fio2 !== undefined ? Number(acido.fio2) : null
  };
  if (db) {
    await db.collection('acidosbase').insertOne(doc);
  } else {
    memStore.acidosbase.push(doc);
  }
}

export async function updateAcidoBase(id, datos) {
  if (db) {
    await db.collection('acidosbase').updateOne({ id }, { $set: datos });
  } else {
    const idx = memStore.acidosbase.findIndex(a => a.id === id);
    if (idx !== -1) {
      memStore.acidosbase[idx] = { ...memStore.acidosbase[idx], ...datos };
    }
  }
}

export async function deleteAcidoBase(id) {
  if (db) {
    await db.collection('acidosbase').deleteOne({ id });
  } else {
    memStore.acidosbase = memStore.acidosbase.filter(a => a.id !== id);
  }
}

// ========== CULTIVOS ==========
export async function getAllCultivos() {
  if (db) {
    const cultivos = await db.collection('cultivos').find().toArray();
    return cleanDocs(cultivos);
  }
  return [...memStore.cultivos];
}

export async function createCultivo(cultivo) {
  const doc = {
    id: cultivo.id,
    pacienteId: cultivo.pacienteId,
    internacionId: cultivo.internacionId,
    fechaToma: cultivo.fechaToma || null,
    protocolo: cultivo.protocolo || null,
    fechaResultado: cultivo.fechaResultado || null,
    tipoMuestra: cultivo.tipoMuestra || null,
    germen: cultivo.germen || null,
    sensible: cultivo.sensible || null,
    resistente: cultivo.resistente || null,
    estado: cultivo.estado || 'NAF/Pendiente',
    observaciones: cultivo.observaciones || null
  };
  if (db) {
    await db.collection('cultivos').insertOne(doc);
  } else {
    memStore.cultivos.push(doc);
  }
}

export async function updateCultivo(id, datos) {
  if (db) {
    const updateDoc = {};
    for (const [key, val] of Object.entries(datos)) {
      if (val !== undefined) {
        updateDoc[key] = val;
      }
    }
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('cultivos').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.cultivos.findIndex(c => c.id === id);
    if (idx !== -1) {
      memStore.cultivos[idx] = { ...memStore.cultivos[idx], ...datos };
    }
  }
}

export async function deleteCultivo(id) {
  if (db) {
    await db.collection('cultivos').deleteOne({ id });
  } else {
    memStore.cultivos = memStore.cultivos.filter(c => c.id !== id);
  }
}

// ========== ESTUDIOS COMPLEMENTARIOS ==========
export async function getAllEstudiosComplementarios() {
  if (db) {
    const estudios = await db.collection('estudiosComplementarios').find().toArray();
    return cleanDocs(estudios);
  }
  return [...memStore.estudiosComplementarios];
}

export async function createEstudioComplementario(estudio) {
  const doc = {
    id: estudio.id,
    pacienteId: estudio.pacienteId,
    internacionId: estudio.internacionId || null,
    fecha: estudio.fecha || null,
    tipo: estudio.tipo || null,
    resultado: estudio.resultado || null
  };
  if (db) {
    await db.collection('estudiosComplementarios').insertOne(doc);
  } else {
    memStore.estudiosComplementarios.push(doc);
  }
}

export async function updateEstudioComplementario(id, datos) {
  if (db) {
    await db.collection('estudiosComplementarios').updateOne({ id }, { $set: datos });
  } else {
    const idx = memStore.estudiosComplementarios.findIndex(e => e.id === id);
    if (idx !== -1) {
      memStore.estudiosComplementarios[idx] = { ...memStore.estudiosComplementarios[idx], ...datos };
    }
  }
}

export async function deleteEstudioComplementario(id) {
  if (db) {
    await db.collection('estudiosComplementarios').deleteOne({ id });
  } else {
    memStore.estudiosComplementarios = memStore.estudiosComplementarios.filter(e => e.id !== id);
  }
}

// ========== INTERCONSULTAS ==========
export async function getAllInterconsultas() {
  if (db) {
    const interconsultas = await db.collection('interconsultas').find().toArray();
    return cleanDocs(interconsultas).map(ic => ({ ...ic, realizada: !!ic.realizada }));
  }
  return memStore.interconsultas.map(ic => ({ ...ic, realizada: !!ic.realizada }));
}

export async function createInterconsulta(ic) {
  const doc = {
    id: ic.id,
    pacienteId: ic.pacienteId,
    internacionId: ic.internacionId,
    fecha: ic.fecha || null,
    servicioInterconsultado: ic.servicioInterconsultado,
    motivo: ic.motivo || null,
    respuestaInterconsulta: ic.respuestaInterconsulta || null,
    respuestaFecha: ic.respuestaFecha || null
  };
  if (db) {
    await db.collection('interconsultas').insertOne(doc);
  } else {
    memStore.interconsultas.push(doc);
  }
}

export async function updateInterconsulta(id, datos) {
  if (db) {
    const updateDoc = {};
    for (const [key, val] of Object.entries(datos)) {
      if (val !== undefined) {
        updateDoc[key] = val;
      }
    }
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('interconsultas').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.interconsultas.findIndex(i => i.id === id);
    if (idx !== -1) {
      memStore.interconsultas[idx] = { ...memStore.interconsultas[idx], ...datos };
    }
  }
}

export async function deleteInterconsulta(id) {
  if (db) {
    await db.collection('interconsultas').deleteOne({ id });
  } else {
    memStore.interconsultas = memStore.interconsultas.filter(i => i.id !== id);
  }
}

// ========== ATB ==========
export async function getAllAtb() {
  if (db) {
    const atb = await db.collection('atb').find().toArray();
    return cleanDocs(atb);
  }
  return [...memStore.atb];
}

export async function createAtb(atb) {
  const doc = {
    id: atb.id,
    pacienteId: atb.pacienteId,
    internacionId: atb.internacionId,
    antibiotico: atb.antibiotico,
    fechaInicio: atb.fechaInicio,
    fechaFinalizacion: atb.fechaFinalizacion || null
  };
  if (db) {
    await db.collection('atb').insertOne(doc);
  } else {
    memStore.atb.push(doc);
  }
}

export async function updateAtb(id, datos) {
  if (db) {
    await db.collection('atb').updateOne({ id }, { $set: datos });
  } else {
    const idx = memStore.atb.findIndex(a => a.id === id);
    if (idx !== -1) {
      memStore.atb[idx] = { ...memStore.atb[idx], ...datos };
    }
  }
}

export async function deleteAtb(id) {
  if (db) {
    await db.collection('atb').deleteOne({ id });
  } else {
    memStore.atb = memStore.atb.filter(a => a.id !== id);
  }
}

// ========== INDICACIONES ==========
export async function getAllIndicaciones() {
  if (db) {
    const indicaciones = await db.collection('indicaciones').find().toArray();
    return cleanDocs(indicaciones);
  }
  return [...memStore.indicaciones];
}

export async function createIndicacion(ind) {
  const doc = {
    id: ind.id,
    internacionId: ind.internacionId,
    tipo: ind.tipo,
    droga: ind.droga || null,
    dosis: ind.dosis || null,
    frecuenciaHoras: ind.frecuenciaHoras || null,
    via: ind.via || null,
    tipoPlan: ind.tipoPlan || null,
    tipoPlan2: ind.tipoPlan2 || null,
    cantidadMl: ind.cantidadMl || null,
    cantidadMl2: ind.cantidadMl2 || null,
    tiempoHoras: ind.tiempoHoras || null,
    estado: ind.estado || 'Activa',
    medicoCrea: ind.medicoCrea || null,
    fechaCrea: ind.fechaCrea || null,
    tipoInsulina: ind.tipoInsulina || null,
    unidadesDesayuno: ind.unidadesDesayuno || null,
    unidadesAlmuerzo: ind.unidadesAlmuerzo || null,
    unidadesNoche: ind.unidadesNoche || null,
    indicacionNoFco: ind.indicacionNoFco || null
  };
  if (db) {
    await db.collection('indicaciones').insertOne(doc);
  } else {
    memStore.indicaciones.push(doc);
  }
}

export async function updateIndicacion(id, datos) {
  const updateDoc = {};
  for (const [key, val] of Object.entries(datos)) {
    if (val !== undefined) {
      updateDoc[key] = val;
    }
  }
  if (db) {
    if (Object.keys(updateDoc).length > 0) {
      await db.collection('indicaciones').updateOne({ id }, { $set: updateDoc });
    }
  } else {
    const idx = memStore.indicaciones.findIndex(i => i.id === id);
    if (idx !== -1) {
      memStore.indicaciones[idx] = { ...memStore.indicaciones[idx], ...updateDoc };
    }
  }
}

export async function deleteIndicacion(id) {
  if (db) {
    await db.collection('indicaciones').deleteOne({ id });
  } else {
    memStore.indicaciones = memStore.indicaciones.filter(i => i.id !== id);
  }
}

// ========== MOVIMIENTOS INDICACIONES ==========
export async function getAllMovimientosIndicaciones() {
  if (db) {
    const movimientos = await db.collection('movimientos_indicaciones').find().toArray();
    return cleanDocs(movimientos);
  }
  return [...memStore.movimientos_indicaciones];
}

export async function createMovimientoIndicacion(mov) {
  const doc = {
    id: mov.id,
    indicacionId: mov.indicacionId,
    internacionId: mov.internacionId,
    tipo: mov.tipo,
    fecha: mov.fecha,
    profesional: mov.profesional,
    indicacionPrevia: mov.indicacionPrevia || null,
    indicacionNueva: mov.indicacionNueva || null
  };
  if (db) {
    await db.collection('movimientos_indicaciones').insertOne(doc);
  } else {
    memStore.movimientos_indicaciones.push(doc);
  }
}

// ========== PENDIENTES ==========
export async function getAllPendientes() {
  if (db) {
    const pendientes = await db.collection('pendientes').find().toArray();
    return cleanDocs(pendientes);
  }
  return [...memStore.pendientes];
}

export async function createPendiente(pendiente) {
  if (db) {
    await db.collection('pendientes').insertOne(pendiente);
  } else {
    memStore.pendientes.push(pendiente);
  }
}

export async function updatePendiente(id, datos) {
  if (db) {
    await db.collection('pendientes').updateOne({ id }, { $set: datos });
  } else {
    const idx = memStore.pendientes.findIndex(p => p.id === id);
    if (idx !== -1) {
      memStore.pendientes[idx] = { ...memStore.pendientes[idx], ...datos };
    }
  }
}

export async function deletePendiente(id) {
  if (db) {
    await db.collection('pendientes').deleteOne({ id });
  } else {
    memStore.pendientes = memStore.pendientes.filter(p => p.id !== id);
  }
}

// ========== KV STORE ==========
export async function getValue(key) {
  if (db) {
    const doc = await db.collection('kv').findOne({ key });
    return doc?.value ?? null;
  }
  return memStore.kv[key] ?? null;
}

export async function setValue(key, value) {
  if (db) {
    await db.collection('kv').updateOne(
      { key },
      { $set: { key, value } },
      { upsert: true }
    );
  } else {
    memStore.kv[key] = value;
  }
}

export function getDb() {
  return db;
}

export async function exportAllData() {
  const collections = [
    'usuarios', 'pacientes', 'areas', 'camas', 'internaciones',
    'evoluciones', 'laboratorios', 'glucemias', 'acidosbase',
    'cultivos', 'estudiosComplementarios', 'interconsultas', 'atb',
    'indicaciones', 'movimientos_indicaciones', 'pendientes', 'kv'
  ];
  const dump = {};
  if (db) {
    for (const name of collections) {
      const docs = await db.collection(name).find().toArray();
      dump[name] = docs;
    }
  } else {
    for (const name of collections) {
      dump[name] = [...(memStore[name] || [])];
    }
  }
  return dump;
}

export async function importAllData(dump) {
  const collections = [
    'usuarios', 'pacientes', 'areas', 'camas', 'internaciones',
    'evoluciones', 'laboratorios', 'glucemias', 'acidosbase',
    'cultivos', 'estudiosComplementarios', 'interconsultas', 'atb',
    'indicaciones', 'movimientos_indicaciones', 'pendientes', 'kv'
  ];
  if (db) {
    for (const name of collections) {
      if (Array.isArray(dump[name])) {
        try {
          await db.collection(name).deleteMany({});
        } catch (e) {
          console.warn(`Could not clear collection ${name}:`, e);
        }
        if (dump[name].length > 0) {
          const cleaned = dump[name].map(doc => {
            const copy = { ...doc };
            if (copy._id) {
              if (ObjectId.isValid(copy._id)) {
                copy._id = new ObjectId(copy._id);
              } else {
                delete copy._id;
              }
            }
            return copy;
          });
          await db.collection(name).insertMany(cleaned);
        }
      }
    }
  } else {
    for (const name of collections) {
      if (Array.isArray(dump[name])) {
        memStore[name] = [...dump[name]];
      }
    }
  }
}


export async function getAllOtrosLaboratorios() {
  if (db) {
    const records = await db.collection('otros-laboratorios').find().toArray();
    return cleanDocs(records);
  }
  return [...memStore.otrosLaboratorios];
}

export async function createOtroLaboratorio(record) {
  const doc = {
    id: record.id,
    pacienteId: record.pacienteId,
    internacionId: record.internacionId,
    fecha: record.fecha,
    hora: record.hora,
    observaciones: record.observaciones,
    createdAt: new Date().toISOString()
  };

  if (db) {
    await db.collection('otros-laboratorios').insertOne(doc);
    return cleanDoc(doc);
  }
  
  memStore.otrosLaboratorios.push(doc);
  return doc;
}

export async function updateOtroLaboratorio(id, updates) {
  if (db) {
    await db.collection('otros-laboratorios').updateOne(
      { id },
      { $set: { ...updates, updatedAt: new Date().toISOString() } }
    );
    return { success: true };
  }

  const idx = memStore.otrosLaboratorios.findIndex(x => x.id === id);
  if (idx !== -1) {
    memStore.otrosLaboratorios[idx] = { ...memStore.otrosLaboratorios[idx], ...updates, updatedAt: new Date().toISOString() };
    return { success: true };
  }
  return { success: false };
}

export async function deleteOtroLaboratorio(id) {
  if (db) {
    await db.collection('otros-laboratorios').deleteOne({ id });
    return { success: true };
  }

  const idx = memStore.otrosLaboratorios.findIndex(x => x.id === id);
  if (idx !== -1) {
    memStore.otrosLaboratorios.splice(idx, 1);
    return { success: true };
  }
  return { success: false };
}
