import { describe, expect, it } from 'vitest';
import {
  LAST_STEP,
  stepOfError,
  validateAll,
  validateBasic,
  validateSettings,
  validateStep,
  type ExamFormValues,
} from './validation';

const complete: ExamFormValues = {
  certificationId: 'cert-1',
  titleEn: 'Master Mariner',
  titleAm: 'ካፒቴን',
  directionEn: '',
  directionAm: '',
  date: '2026-09-10',
  venue: 'Addis Ababa',
  type: 'WRITTEN',
  form: 'CHOICE',
  adminMethod: 'ONLINE',
  evalMethod: 'SUM',
  cuttingPoint: 50,
};

const basicOnly: ExamFormValues = {
  ...complete,
  type: null,
  form: null,
  adminMethod: null,
  evalMethod: null,
  cuttingPoint: 0,
};

/**
 * Clicking "Create Exam" from Basic Info used to report the Settings fields as
 * missing — a correct error the user could not act on, since that step had not
 * been shown yet. Each step now answers only for its own fields.
 */
describe('exam form step validation', () => {
  it('keeps an incomplete Basic Info on its own step', () => {
    const error = validateStep(0, { ...basicOnly, venue: '' });

    expect(error).toBe('exam.form.fillRequiredBasic');
    expect(stepOfError(error!)).toBe(0);
  });

  it('does not fault Basic Info for Settings fields that are still empty', () => {
    expect(validateStep(0, basicOnly)).toBeNull();
  });

  it('wants a direction in both languages or in neither', () => {
    expect(validateBasic({ ...complete, directionEn: 'Answer all' })).toBe(
      'exam.form.directionBothLanguages',
    );
    expect(validateBasic({ ...complete, directionEn: 'Answer all', directionAm: 'ሁሉንም' })).toBeNull();
  });

  it('keeps an incomplete Settings on its own step', () => {
    const error = validateStep(1, basicOnly);

    expect(error).toBe('exam.form.fillRequiredSettings');
    expect(stepOfError(error!)).toBe(1);
  });

  it('lets a complete Settings through to the review step', () => {
    expect(validateStep(1, complete)).toBeNull();
  });

  it('asks nothing of the review step itself — it has no fields', () => {
    expect(validateStep(LAST_STEP, basicOnly)).toBeNull();
  });

  it('checks the whole payload on submit, not just the last step', () => {
    // Reachable: the stepper header can be clicked back to a visited step, so
    // arriving at Review is no proof everything is still filled in.
    expect(validateAll(basicOnly)).toBe('exam.form.fillRequiredSettings');
    expect(validateAll({ ...complete, titleAm: '' })).toBe('exam.form.fillRequiredBasic');
    expect(validateAll(complete)).toBeNull();
  });

  it('treats a zero cutting point as unset — a paper nobody can fail', () => {
    expect(validateSettings({ ...complete, cuttingPoint: 0 })).toBe(
      'exam.form.fillRequiredSettings',
    );
  });
});
