import type { PrismaService } from '../prisma/prisma.service';

/** Prefijo que el "Corregir asiento" anterior le ponía al asiento manual que lo reemplazaba. */
export const PREFIJO_CORRECCION = 'CORRECCIÓN: ';

export interface CorreccionManual {
  asiento_id: string;
  numero: number;
}

/**
 * Registros cuyo asiento se revirtió con el "Corregir asiento" anterior y que ya
 * tienen el asiento manual de reemplazo.
 *
 * Ese flujo revertía el asiento (el documento queda REVERTIDO) y abría un asiento
 * manual sin documento, con la glosa `CORRECCIÓN: <glosa original>`. Si el usuario
 * lo guardó, el registro está asentado aunque no tenga documento CONFIRMADO, y
 * regenerarlo lo duplicaría. Si no lo guardó, el registro quedó sin asiento y sí
 * hay que regenerarlo. El "Corregir" de hoy edita el asiento en el lugar, así que
 * esto sólo aplica a correcciones de antes.
 */
export async function correccionesManuales(
  prisma: Pick<PrismaService, 'cont_documentos' | 'cont_asientos'>,
  empresaId: string,
  origenTipo: string,
  origenIds?: string[],
): Promise<Map<string, CorreccionManual>> {
  const revertidos = await prisma.cont_documentos.findMany({
    where: {
      empresa_id: empresaId,
      origen_tipo: origenTipo,
      estado: 'REVERTIDO',
      ...(origenIds ? { origen_id: { in: origenIds } } : { origen_id: { not: null } }),
    },
    select: { origen_id: true, asiento: { select: { glosa: true, updated_at: true } } },
  });
  const porGlosa = new Map<string, { origenId: string; revertidoEl: Date | null }>();
  for (const d of revertidos) {
    if (d.origen_id && d.asiento?.glosa) {
      porGlosa.set(PREFIJO_CORRECCION + d.asiento.glosa, { origenId: d.origen_id, revertidoEl: d.asiento.updated_at ?? null });
    }
  }
  const resultado = new Map<string, CorreccionManual>();
  if (porGlosa.size === 0) return resultado;

  const manuales = await prisma.cont_asientos.findMany({
    where: { empresa_id: empresaId, documento_id: null, estado: 'CONFIRMADO', glosa: { in: [...porGlosa.keys()] } },
    select: { id: true, numero: true, glosa: true, created_at: true },
    orderBy: { created_at: 'asc' },
  });
  for (const m of manuales) {
    const rev = m.glosa ? porGlosa.get(m.glosa) : undefined;
    if (!rev || resultado.has(rev.origenId)) continue;
    // La corrección se carga después de revertir; uno anterior con la misma glosa es otra cosa.
    if (rev.revertidoEl && m.created_at && m.created_at < rev.revertidoEl) continue;
    resultado.set(rev.origenId, { asiento_id: m.id, numero: m.numero });
  }
  return resultado;
}
