import { describe, it, expect } from 'vitest';
import { initialForm, toRequest, validateStep } from './form-state';

describe('initialForm', () => {
  it('defaults to env-wide ROUTE_METRIC with safe intervals', () => {
    const f = initialForm();
    expect(f.scopeKind).toBe('env');
    expect(f.conditionKind).toBe('ROUTE_METRIC');
    expect(f.evaluationIntervalSeconds).toBeGreaterThanOrEqual(5);
    expect(f.enabled).toBe(true);
  });
});

describe('toRequest', () => {
  it('strips empty scope fields for env-wide rules', () => {
    const f = initialForm();
    f.name = 'test';
    const req = toRequest(f);
    const scope = (req.condition as unknown as { scope: Record<string, string | undefined> }).scope;
    expect(scope.appSlug).toBeUndefined();
    expect(scope.routeId).toBeUndefined();
    expect(scope.agentId).toBeUndefined();
  });

  it('includes appSlug for app/route/agent scopes', () => {
    const f = initialForm();
    f.scopeKind = 'app';
    f.appSlug = 'orders';
    const req = toRequest(f);
    const scope = (req.condition as unknown as { scope: Record<string, string | undefined> }).scope;
    expect(scope.appSlug).toBe('orders');
  });
});

describe('validateStep', () => {
  it('flags blank name on scope step', () => {
    expect(validateStep('scope', initialForm())).toContain('Name is required.');
  });
  it('flags app requirement for app-scope', () => {
    const f = initialForm();
    f.name = 'x';
    f.scopeKind = 'app';
    expect(validateStep('scope', f).some((e) => /App is required/.test(e))).toBe(true);
  });
  it('flags intervals below floor on trigger step', () => {
    const f = initialForm();
    f.evaluationIntervalSeconds = 1;
    expect(validateStep('trigger', f).some((e) => /Evaluation interval/.test(e))).toBe(true);
  });

  it('flags missing fireMode on EXCHANGE_MATCH condition step', () => {
    const f = initialForm();
    f.conditionKind = 'EXCHANGE_MATCH';
    // Simulate the old bug: condition payload without a fireMode.
    f.condition = { kind: 'EXCHANGE_MATCH', scope: {} } as typeof f.condition;
    expect(validateStep('condition', f).some((e) => /Fire mode is required/.test(e))).toBe(true);
  });

  it('flags missing threshold/window on COUNT_IN_WINDOW', () => {
    const f = initialForm();
    f.conditionKind = 'EXCHANGE_MATCH';
    f.condition = {
      kind: 'EXCHANGE_MATCH',
      scope: {},
      fireMode: 'COUNT_IN_WINDOW',
    } as unknown as typeof f.condition;
    const errs = validateStep('condition', f);
    expect(errs.some((e) => /Threshold is required/.test(e))).toBe(true);
    expect(errs.some((e) => /Window/.test(e))).toBe(true);
  });

  it('passes when EXCHANGE_MATCH PER_EXCHANGE has linger seconds', () => {
    const f = initialForm();
    f.conditionKind = 'EXCHANGE_MATCH';
    f.condition = {
      kind: 'EXCHANGE_MATCH',
      scope: {},
      fireMode: 'PER_EXCHANGE',
      perExchangeLingerSeconds: 300,
    } as unknown as typeof f.condition;
    expect(validateStep('condition', f)).toEqual([]);
  });
});
