/**
 * Interface agnóstica de origen de cartera.
 *
 * Cualquier consumidor del módulo Cartera Inteligente lee/escribe via esta
 * interfaz sin saber si los datos vienen del ERP Novasis, un Excel importado,
 * una API externa del cliente o un conector nativo (FITBANK, etc.).
 *
 * Esto permite vender el módulo a entidades crediticias que no usan el ERP
 * sin tener que refactorizar la lógica de cobranza/worklist/IA.
 *
 * Implementaciones planeadas:
 *  - ErpNovasisFuente          (Sprint 0+)   lee de factura_cab + cuotas
 *  - CarteraImportadaFuente    (Sprint 1-2)  lee de tabla cartera_importada
 *  - ApiExternaFuente          (Mes 7-8)     el cliente envía via REST
 *  - ConectorFitbankFuente     (Mes 9+)      conector nativo
 */

export type ModoOperativo = 'operacional' | 'co-pilot' | 'hibrido';

export type OrigenCartera =
  | 'erp-novasis'
  | 'cartera-importada'
  | 'api-externa'
  | string; // permite `conector-fitbank`, etc.

export interface CuentasFilter {
  empresa_id: string;
  cliente_id?: string;
  cobrador_id?: string;
  con_saldo?: boolean;
  vencido_desde?: Date;
  page?: number;
  page_size?: number;
}

export interface CuentaPendiente {
  id: string;                  // id estable del documento que origina la cuenta
  cliente_id: string;
  cliente_nombre: string;
  documento_numero: string;    // FAC-001-2026 / EXT-12345
  monto_total: number;
  saldo_pendiente: number;
  fecha_emision: Date;
  fecha_vencimiento: Date | null;
  dias_mora: number;
  moneda_codigo: string;
}

export interface CuentaDetalle extends CuentaPendiente {
  cuotas: Cuota[];
}

export interface Cuota {
  id: string;
  numero: number;
  monto: number;
  saldo: number;
  fecha_vencimiento: Date;
  estado: 'pendiente' | 'parcial' | 'pagada' | 'anulada';
}

export interface Recibo {
  id: string;
  fecha: Date;
  monto: number;
  moneda_codigo: string;
  medio_pago: string;
}

export interface RegistrarCobroInput {
  empresa_id: string;
  cliente_id: string;
  cuotas: Array<{ cuota_id: string; monto: number }>;
  medio_pago: string;
  fecha: Date;
  observacion?: string;
}

export interface ReciboCobro {
  id: string;
  numero: string;
  monto_total: number;
  fecha: Date;
}

export interface IFuenteCartera {
  // Lectura
  listarCuentasPendientes(filtros: CuentasFilter): Promise<CuentaPendiente[]>;
  obtenerCuenta(id: string): Promise<CuentaDetalle>;
  listarCuotas(cuentaId: string): Promise<Cuota[]>;
  obtenerSaldoVencido(clienteId: string): Promise<number>;
  obtenerHistorialCobros(clienteId: string): Promise<Recibo[]>;

  // Escritura — solo válida si modo === 'operacional' o si la feature está
  // habilitada en modo 'hibrido'. Las implementaciones deben lanzar
  // ForbiddenException si el modo no permite escritura.
  registrarCobro(input: RegistrarCobroInput): Promise<ReciboCobro>;

  // Metadatos
  getModo(): ModoOperativo;
  getOrigen(): OrigenCartera;
}

export const FUENTE_CARTERA_TOKEN = Symbol('IFuenteCartera');
