import { describe, it, expect } from 'vitest';
import {
  parseAanvraagStatus,
  parseApplicationSummary,
  parseApplications,
  parseApplicationDetail,
} from './applications.adapter';

const concept = {
  id: 'a1',
  type: 'registratie',
  status: { tag: 'Concept', stepIndex: 1, stepCount: 4 },
  documentIds: [],
  createdAt: '2026-07-01T10:00:00Z',
  updatedAt: '2026-07-01T10:05:00Z',
};

describe('parseAanvraagStatus', () => {
  it('parses each tag with its required fields', () => {
    expect(parseAanvraagStatus({ tag: 'Concept', stepIndex: 2, stepCount: 4 })).toEqual({
      ok: true,
      value: { tag: 'Concept', stepIndex: 2, stepCount: 4 },
    });
    expect(
      parseAanvraagStatus({ tag: 'InBehandeling', referentie: 'BIG-1', manual: true }).ok,
    ).toBe(true);
    expect(parseAanvraagStatus({ tag: 'Goedgekeurd', referentie: 'BIG-1' }).ok).toBe(true);
    expect(
      parseAanvraagStatus({ tag: 'Afgewezen', referentie: 'BIG-1', reden: 'geen uren' }).ok,
    ).toBe(true);
  });

  it('rejects a missing status, unknown tag, and wrong-typed fields', () => {
    expect(parseAanvraagStatus(undefined).ok).toBe(false);
    expect(parseAanvraagStatus({ tag: 'Onzin' }).ok).toBe(false);
    expect(parseAanvraagStatus({ tag: 'InBehandeling', referentie: 'BIG-1' }).ok).toBe(false); // manual missing
    expect(parseAanvraagStatus({ tag: 'Concept', stepIndex: 1 }).ok).toBe(false); // stepCount missing
  });
});

describe('parseApplicationSummary', () => {
  it('maps a valid DTO to domain', () => {
    const r = parseApplicationSummary(concept);
    expect(r.ok && r.value.type).toBe('registratie');
    expect(r.ok && r.value.status.tag).toBe('Concept');
  });

  it('rejects a bad type and non-objects', () => {
    expect(parseApplicationSummary({ ...concept, type: 'onbekend' }).ok).toBe(false);
    expect(parseApplicationSummary(null).ok).toBe(false);
    expect(parseApplicationSummary({ ...concept, id: 42 }).ok).toBe(false);
  });
});

describe('parseApplications / parseApplicationDetail', () => {
  it('parses a list and fails fast on a bad element', () => {
    expect(parseApplications([concept, concept]).ok).toBe(true);
    expect(parseApplications([concept, { ...concept, status: { tag: 'x' } }]).ok).toBe(false);
    expect(parseApplications({}).ok).toBe(false);
  });

  it('carries the opaque draft through detail', () => {
    const r = parseApplicationDetail({ ...concept, draft: { beroep: 'arts' } });
    expect(r.ok && (r.value.draft as { beroep: string }).beroep).toBe('arts');
  });
});
