import { Prisma } from '@prisma/client';

/**
 * Estados de `factura_cab.estado` que dejan al documento sin valor de cobro.
 *
 * Los escribe más de un camino, y por eso hay que listarlos todos:
 * - `Anulado`     → aprobación del evento de cancelación (middleware-sifen.service.ts:1162)
 * - `Cancelado`   → cancelación vía middleware SIFEN (middleware-sifen.service.ts:2027, 2141)
 * - `Inutilizado` → inutilización vía middleware SIFEN (middleware-sifen.service.ts:2024, 2138)
 *
 * Las consultas de cuentas a cobrar filtraban solo `Anulado`, así que una
 * factura cancelada o inutilizada seguía figurando como pendiente de cobro
 * (reclamo de cliente: aparecían en el wizard del recibo multi).
 *
 * Se incluyen las variantes en femenino porque el valor se escribe a mano en
 * varios lugares del código y no hay un enum en la base que lo garantice.
 */
export const ESTADOS_FACTURA_NO_COBRABLE = [
  'anulado',
  'anulada',
  'cancelado',
  'cancelada',
  'inutilizado',
  'inutilizada',
];

/** Variantes capitalizadas, para los `where` de Prisma (que comparan exacto). */
export const ESTADOS_FACTURA_NO_COBRABLE_PRISMA = [
  ...ESTADOS_FACTURA_NO_COBRABLE,
  ...ESTADOS_FACTURA_NO_COBRABLE.map((e) => e.charAt(0).toUpperCase() + e.slice(1)),
  ...ESTADOS_FACTURA_NO_COBRABLE.map((e) => e.toUpperCase()),
];

/**
 * Fragmento SQL: la factura del alias dado sigue siendo cobrable.
 *
 * Compara en minúsculas porque el estado se escribe con distinta capitalización
 * según el camino.
 *
 * `estado` es nullable, y las consultas originales no coincidían en cómo
 * trataban el NULL: unas usaban `estado != 'Anulado'` (NULL queda fuera) y
 * otras `COALESCE(estado,'') NOT IN (...)` (NULL queda dentro). Este cambio
 * solo agrega los estados que faltaban, así que cada sitio conserva su
 * comportamiento previo ante NULL vía `nullEsCobrable`.
 *
 * @param alias alias de la tabla `factura_cab` en la consulta (ej. 'fc', 'cab')
 * @param nullEsCobrable true para los sitios que venían con COALESCE
 */
export const sqlFacturaCobrable = (alias: string, nullEsCobrable = false) => {
  const col = nullEsCobrable
    ? Prisma.sql`COALESCE(LOWER(${Prisma.raw(alias)}.estado), '')`
    : Prisma.sql`LOWER(${Prisma.raw(alias)}.estado)`;
  return Prisma.sql`${col} NOT IN (${Prisma.join(ESTADOS_FACTURA_NO_COBRABLE)})`;
};
