import { isStructureKind, STRUCTURE_KINDS, type StructureKind } from './structure-kind';

describe('STRUCTURE_KINDS', () => {
  it('contains the seven cascade-aligned kinds per ADR-0027', () => {
    expect(STRUCTURE_KINDS).toEqual([
      'medico_social',
      'antenne',
      'dispositif',
      'entreprise_adaptee',
      'mouvement',
      'administratif',
      'siege',
    ]);
  });

  it('has no duplicate entries', () => {
    expect(new Set(STRUCTURE_KINDS).size).toBe(STRUCTURE_KINDS.length);
  });
});

describe('isStructureKind', () => {
  it('returns true for every catalogue value', () => {
    for (const kind of STRUCTURE_KINDS) {
      expect(isStructureKind(kind)).toBe(true);
    }
  });

  it('returns false for values outside the catalogue', () => {
    // common typos / cascade kinds not adopted by the portal
    expect(isStructureKind('medical_social')).toBe(false);
    expect(isStructureKind('sanitaire')).toBe(false); // cascade has it, portal doesn't ship it in v1
    expect(isStructureKind('autre')).toBe(false); // escape hatch deliberately excluded
    expect(isStructureKind('')).toBe(false);
    expect(isStructureKind('Medico_Social')).toBe(false); // case-sensitive
  });

  it('narrows the type at the call site', () => {
    // Round-trip through `String()` to widen the literal to `string`.
    // Without this the inferred type is `'medico_social'`, already a
    // StructureKind subtype — the narrowing check would be vacuous.
    const candidate = String('medico_social');
    if (!isStructureKind(candidate)) {
      throw new Error('unreachable — candidate is a known kind');
    }
    const narrowed: StructureKind = candidate;
    expect(narrowed).toBe('medico_social');
  });
});
