import { EcommerceCreditoService } from './ecommerce-credito.service';
import { EcommerceStockReservaService } from '../stock/ecommerce-stock-reserva.service';

function armar(estado = 'pendiente_pago') {
  const prisma: any = {
    ecommerce_checkout_session: {
      findFirst: jest.fn().mockResolvedValue({ id: 's1', codigo: 'ECOM-1', estado, notas: null }),
      update: jest.fn().mockResolvedValue({}),
    },
    ecommerce_pedido_evento: { create: jest.fn().mockResolvedValue({}) },
  };
  const reservas = { liberar: jest.fn().mockResolvedValue(1) };
  const notifications = { onOrderInvoicedSesion: jest.fn(), onOrderCancelled: jest.fn() };
  const service = new EcommerceCreditoService(prisma, reservas as any, notifications as any);
  return { service, prisma, reservas, notifications };
}

describe('EcommerceCreditoService', () => {
  it('solicitud facturada: pedido pagado, reserva liberada y mail de facturado', async () => {
    const { service, prisma, reservas, notifications } = armar();
    await service.onSolicitudFacturada('e1', 'sol-1', 'fac-1');
    expect(reservas.liberar).toHaveBeenCalledWith('s1');
    expect(prisma.ecommerce_checkout_session.update.mock.calls[0][0].data.estado).toBe('pago_confirmado');
    expect(notifications.onOrderInvoicedSesion).toHaveBeenCalledWith('e1', 's1');
  });

  it('solicitud rechazada: pedido cancelado y stock liberado', async () => {
    const { service, prisma, reservas, notifications } = armar();
    await service.onSolicitudCerrada('e1', 'sol-1', 'rechazada', 'sin ingresos');
    expect(reservas.liberar).toHaveBeenCalledWith('s1');
    expect(prisma.ecommerce_checkout_session.update.mock.calls[0][0].data.estado).toBe('cancelado');
    expect(notifications.onOrderCancelled).toHaveBeenCalledWith('e1', 's1');
  });

  it('no toca un pedido que ya avanzó', async () => {
    const { service, prisma } = armar('preparando');
    await service.onSolicitudCerrada('e1', 'sol-1', 'cancelada');
    expect(prisma.ecommerce_checkout_session.update).not.toHaveBeenCalled();
  });
});

describe('EcommerceStockReservaService.expirarVencidas con compra en cuotas', () => {
  it('renueva la reserva mientras el crédito está en trámite en vez de expirar', async () => {
    const prisma: any = {
      ecommerce_stock_reserva: {
        findMany: jest.fn().mockResolvedValue([{ session_id: 's1' }]),
        updateMany: jest.fn().mockResolvedValue({ count: 1 }),
      },
      ecommerce_checkout_session: {
        findUnique: jest.fn().mockResolvedValue({ id: 's1', estado: 'pendiente_pago', codigo: 'ECOM-1', solicitud_credito_id: 'sol-1' }),
        update: jest.fn(),
      },
      solicitud_credito: { findUnique: jest.fn().mockResolvedValue({ estado: 'aprobada' }) },
    };
    const service = new EcommerceStockReservaService(prisma);
    const r = await service.expirarVencidas();
    expect(r).toEqual({ sesiones: 0, reservas: 0 });
    expect(prisma.ecommerce_checkout_session.update).not.toHaveBeenCalled();
    expect(prisma.ecommerce_stock_reserva.updateMany.mock.calls[0][0].data.expira_at).toBeInstanceOf(Date);
  });
});
