import { ViajeCalculosService } from '../viaje-calculos.service';
import { ViajesService } from '../viajes.service';

describe('Notas de crédito en la propuesta (I6)', () => {
  it('sugeridos devuelve también las notas de crédito del período', async () => {
    const { ViajeDocumentosService } = require('../viaje-documentos.service');
    const prisma: any = {
      usuario: { findUnique: jest.fn().mockResolvedValue({ is_superadmin: true }) },
      empresas: { findUnique: jest.fn().mockResolvedValue({ type: 'subsidiary' }) },
      rubros: { findFirst: jest.fn().mockResolvedValue(null) },
      asignacion_sucursal_caja_usuario: { findMany: jest.fn().mockResolvedValue([]) },
      empresas_sucursales: { findMany: jest.fn().mockResolvedValue([]) },
      depositos: { findMany: jest.fn().mockResolvedValue([]) },
      viaje_documentos: { findMany: jest.fn().mockResolvedValue([]) },
      factura_cab: { findMany: jest.fn().mockResolvedValue([]) },
      nota_remision_cab: { findMany: jest.fn().mockResolvedValue([]) },
      recibos_cobro: { findMany: jest.fn().mockResolvedValue([]) },
      pedidos: { findMany: jest.fn().mockResolvedValue([]) },
      presupuesto_cab: { findMany: jest.fn().mockResolvedValue([]) },
      nota_credito_cab: {
        findMany: jest.fn().mockResolvedValue([
          { id: 'nc-1', dest: '001', dpunexp: '001', dnumdoc: '0000045', dfeemide: new Date('2026-09-21'),
            moneda: { codigo: 'PYG' }, clientes: { personas: { razon_social: 'CLI-1' } },
            nota_credito_subtotal: [{ dtotgralope: 200_000 }] },
        ]),
      },
    };
    const viajes: any = {
      findOne: jest.fn().mockResolvedValue({
        id: 'v-1', empresa_id: 'emp-1', vendedor_id: null,
        fecha_salida: new Date('2026-09-20'), fecha_retorno: new Date('2026-09-22'),
      }),
    };
    const service = Object.create(ViajeDocumentosService.prototype) as any;
    service.prisma = prisma;
    service.viajes = viajes;

    const r = await service.sugeridos('v-1', 'emp-1', 'usr-1');

    expect(r.notas_credito).toEqual([
      expect.objectContaining({ id: 'nc-1', tipo: 'NOTA_CREDITO', numero: '001-001-0000045', total: 200_000 }),
    ]);
  });
});

describe('Importes de lo planificado (I8)', () => {
  it('la matriz en modo planificado trae el importe del pedido', async () => {
    const prisma: any = {
      factura_det: { findMany: jest.fn().mockResolvedValue([]) },
      producto_presentaciones: { findMany: jest.fn().mockResolvedValue([]) },
    };
    const documentos: any = {
      idsPorTipo: jest.fn().mockImplementation((_i, tipo) => Promise.resolve(tipo === 'PEDIDO' ? ['ped-1'] : [])),
    };
    const service = Object.create(ViajeCalculosService.prototype) as any;
    service.prisma = prisma;
    // Los cálculos piden solo los vigentes; acá el filtro de bajas no es lo que se prueba.
    documentos.idsVigentes ??= documentos.idsPorTipo;
    service.documentos = documentos;
    service.viajes = { findOne: jest.fn().mockResolvedValue({ id: 'v-1', empresa_id: 'emp-1' }) };
    service.monedas = { getCotizacionVigente: jest.fn().mockResolvedValue({ tasa: 7500 }) };
    service.lineasPlanificadas = jest.fn().mockResolvedValue({
      origen: 'PEDIDO',
      lineas: [
        { producto_id: 'p-1', cliente_id: 'cli-1', cliente: 'CLI-1', cantidad_base: 480,
          producto: 'NARANJA', cod_producto: null, importe: 1_200_000, moneda: 'PYG' },
      ],
    });

    const m = await service.matriz('v-1', 'emp-1', 'planificado');

    expect(m.celdas['p-1::cli-1'].por_moneda).toEqual({ PYG: 1_200_000 });
    expect(m.totales_cliente['cli-1'].importe_base).toBe(1_200_000);
  });
});

describe('Transición PLANIFICADO → EN_RUTA (I9)', () => {
  const crear = (estado: string) => {
    const viaje = { id: 'v-1', empresa_id: 'emp-1', estado, documentos: [] };
    const prisma: any = {
      viajes: {
        findFirst: jest.fn().mockResolvedValue(viaje),
        update: jest.fn().mockImplementation(({ data }) => Promise.resolve({ ...viaje, ...data })),
      },
    };
    const service = Object.create(ViajesService.prototype) as any;
    service.prisma = prisma;
    return { service, prisma };
  };

  it('un viaje PLANIFICADO puede marcarse en ruta', async () => {
    const { service } = crear('PLANIFICADO');
    const r = await service.marcarEnRuta('v-1', 'emp-1', 'usr-1');
    expect(r.estado).toBe('EN_RUTA');
  });

  it('un viaje CERRADO no puede marcarse en ruta', async () => {
    const { service } = crear('CERRADO');
    await expect(service.marcarEnRuta('v-1', 'emp-1', 'usr-1')).rejects.toThrow(/planificado/i);
  });
});
