import { NotFoundException } from '@nestjs/common';

/**
 * Un asiento automático necesita un concepto que la empresa no mapeó (o mapeó a
 * una cuenta inutilizable). Nunca se cae a otra cuenta: el documento queda
 * pendiente y se avisa (ver AvisosMapeoService). Ver
 * docs/superpowers/specs/2026-10-13-mapeo-sin-decisiones-internas-design.md.
 *
 * El mensaje conserva el prefijo "No hay cuenta mapeada para el concepto": hay
 * código que lo reconoce por texto.
 */
export class FaltaMapeoError extends NotFoundException {
  constructor(
    readonly empresaId: string,
    readonly conceptos: string[],
    detalle?: string,
    /** SIN_MAPEO: no hay mapeo (crearlo). CUENTA_INUTILIZABLE: hay mapeo a una cuenta desactivada o de agrupación (reasignarlo). */
    readonly motivo: 'SIN_MAPEO' | 'CUENTA_INUTILIZABLE' = 'SIN_MAPEO',
    readonly cuentaCodigo?: string,
    /** La regla por dimensión que eligió la cuenta inutilizable (si no vino del mapeo por defecto). */
    readonly regla?: { id: string; orden: number },
    /**
     * Por concepto, el texto que nombra lo que hay que corregir cuando no es un
     * concepto del mapeo (p. ej. MEDIO_PAGO_COBRO → el medio y su cuenta). Va a la
     * constancia y a los avisos.
     */
    readonly detalles?: Record<string, string>,
  ) {
    super(
      `No hay cuenta mapeada para el concepto "${conceptos.join('", "')}"` +
        (detalle ? ` (${detalle})` : '') +
        '. Configurá el mapeo en Contabilidad → Mapeo de cuentas',
    );
  }
}

/** Regla que frenó el asiento, como queda en la constancia CONT_FALTA_MAPEO. */
export type ReglaDeFalta = { id: string; orden: number; concepto: string };

/**
 * Lo que la constancia y los avisos necesitan del error: los conceptos y, si la
 * cuenta existe pero no sirve, el motivo y la regla que la eligió (para decir
 * "la regla n.º X de {concepto} apunta a una cuenta que no sirve"); con
 * `detalles`, por concepto, el texto legible de lo que hay que corregir (medio de pago y cuenta).
 */
export function datosDeFalta(e: FaltaMapeoError): { conceptos: string[]; motivo?: 'CUENTA_INUTILIZABLE'; regla?: ReglaDeFalta; detalles?: Record<string, string> } {
  return {
    conceptos: e.conceptos,
    ...(e.motivo === 'CUENTA_INUTILIZABLE' ? { motivo: e.motivo } : {}),
    ...(e.regla ? { regla: { id: e.regla.id, orden: e.regla.orden, concepto: e.conceptos[0] } } : {}),
    ...(e.detalles && Object.keys(e.detalles).length ? { detalles: e.detalles } : {}),
  };
}
