import {
  buildOperationalFlow,
  canReportIncidencia,
  effectiveWorkflowState,
  nextWorkflowStates,
  normalizeWorkflowConfig,
} from './ecommerce-workflow';

describe('ecommerce workflow', () => {
  it('separa el cierre de retiro del cierre de delivery', () => {
    const config = normalizeWorkflowConfig({ preset: 'completo' });

    expect(buildOperationalFlow('pickup', config)).toEqual([
      'pago_confirmado',
      'en_verificacion',
      'verificado',
      'preparando',
      'empaquetado',
      'listo_retiro',
      'retirado',
    ]);
    expect(buildOperationalFlow('delivery', config)).toEqual([
      'pago_confirmado',
      'en_verificacion',
      'verificado',
      'preparando',
      'empaquetado',
      'listo_despacho',
      'en_camino',
      'entregado',
    ]);
  });

  it('el preset simple omite verificación, empaque y tránsito', () => {
    const config = normalizeWorkflowConfig({ preset: 'simple' });

    expect(buildOperationalFlow('pickup', config)).toEqual([
      'pago_confirmado',
      'preparando',
      'listo_retiro',
      'retirado',
    ]);
    expect(buildOperationalFlow('delivery', config)).toEqual([
      'pago_confirmado',
      'preparando',
      'listo_despacho',
      'entregado',
    ]);
  });

  it('nunca ofrece estados de delivery a un retiro', () => {
    const next = nextWorkflowStates('empaquetado', 'pickup', { preset: 'completo' });
    expect(next).toContain('listo_retiro');
    expect(next).not.toContain('listo_despacho');
    expect(next).not.toContain('en_camino');
    expect(next).not.toContain('entregado');
  });

  it('interpreta estados históricos según el tipo de entrega', () => {
    expect(effectiveWorkflowState('listo', 'pickup')).toBe('listo_retiro');
    expect(effectiveWorkflowState('listo', 'delivery')).toBe('listo_despacho');
    expect(effectiveWorkflowState('pedido_creado', 'delivery')).toBe('pago_confirmado');
  });

  it('respeta la política de cancelar sólo antes de preparar', () => {
    const config = { preset: 'completo', cancellationPolicy: 'before_preparation' };
    expect(nextWorkflowStates('verificado', 'delivery', config)).toContain('cancelado');
    expect(nextWorkflowStates('preparando', 'delivery', config)).not.toContain('cancelado');
  });

  it('una incidencia sólo se reencauza a preparación o se cancela', () => {
    expect(nextWorkflowStates('incidencia', 'delivery', { preset: 'completo' })).toEqual([
      'preparando',
      'cancelado',
    ]);
    expect(nextWorkflowStates('incidencia', 'pickup', { preset: 'simple' })).toEqual([
      'preparando',
      'cancelado',
    ]);
  });

  it('permite reportar incidencia sólo en estados operativos activos', () => {
    expect(canReportIncidencia('preparando', 'delivery')).toBe(true);
    expect(canReportIncidencia('en_camino', 'delivery')).toBe(true);
    expect(canReportIncidencia('listo', 'pickup')).toBe(true);
    expect(canReportIncidencia('pendiente_pago', 'delivery')).toBe(false);
    expect(canReportIncidencia('entregado', 'delivery')).toBe(false);
    expect(canReportIncidencia('retirado', 'pickup')).toBe(false);
    expect(canReportIncidencia('incidencia', 'delivery')).toBe(false);
  });
});
