import { describe, expect, it } from 'vitest';
import { CONTENT_PACK } from '../content/pack';
import { classify } from './classify';
import { deriveObligations, nextDeadline } from './obligations';
import type { AssessmentAnswers } from './types';

const base: AssessmentAnswers = {
  isAISystem: true,
  role: 'deployer',
  isGPAIModel: false,
  prohibitedPractices: [],
  annexIIICategories: [],
  art63Exception: false,
  involvesProfiling: false,
  isAnnexISafetyComponent: false,
  transparencyTriggers: [],
};

function obligationsFor(answers: AssessmentAnswers): readonly string[] {
  const classification = classify(answers, CONTENT_PACK);
  return deriveObligations(classification, answers, CONTENT_PACK).map((o) => o.id);
}

describe('deriveObligations', () => {
  it('liefert keine Pflichten für verbotene Systeme', () => {
    expect(obligationsFor({ ...base, prohibitedPractices: ['proh-social-scoring'] })).toEqual([]);
  });

  it('liefert keine Pflichten für out-of-scope', () => {
    expect(obligationsFor({ ...base, isAISystem: false })).toEqual([]);
  });

  it('liefert Anbieter-Pflichten für Hochrisiko-Anbieter (Art. 9–17, 43 ff.)', () => {
    const ids = obligationsFor({
      ...base,
      role: 'provider',
      annexIIICategories: ['a3-employment'],
    });
    expect(ids).toContain('ob-risk-mgmt');
    expect(ids).toContain('ob-tech-doc');
    expect(ids).toContain('ob-conformity');
    expect(ids).not.toContain('ob-deployer-oversight');
  });

  it('liefert Betreiber-Pflichten für Hochrisiko-Betreiber (Art. 26)', () => {
    const ids = obligationsFor({ ...base, annexIIICategories: ['a3-employment'] });
    expect(ids).toContain('ob-deployer-oversight');
    expect(ids).toContain('ob-deployer-workers');
    expect(ids).not.toContain('ob-risk-mgmt');
  });

  it('liefert Transparenzpflicht für Chatbots (limited)', () => {
    const ids = obligationsFor({ ...base, transparencyTriggers: ['tr-chatbot'] });
    expect(ids).toContain('ob-transparency-art50');
    expect(ids).toContain('ob-ai-literacy');
  });

  it('liefert GPAI-Pflichten nur für Anbieter mit GPAI-Flag', () => {
    expect(obligationsFor({ ...base, role: 'provider', isGPAIModel: true })).toContain('ob-gpai');
    expect(obligationsFor({ ...base, isGPAIModel: true })).not.toContain('ob-gpai');
    expect(obligationsFor({ ...base, role: 'provider' })).not.toContain('ob-gpai');
  });

  it('sortiert Pflichten nach Frist aufsteigend', () => {
    const answers: AssessmentAnswers = {
      ...base,
      annexIIICategories: ['a3-employment'],
      transparencyTriggers: ['tr-chatbot'],
    };
    const classification = classify(answers, CONTENT_PACK);
    const deadlines = deriveObligations(classification, answers, CONTENT_PACK).map(
      (o) => o.deadline,
    );
    expect(deadlines).toEqual([...deadlines].sort());
  });
});

describe('nextDeadline', () => {
  it('findet die nächste bevorstehende Frist', () => {
    const answers: AssessmentAnswers = { ...base, annexIIICategories: ['a3-employment'] };
    const classification = classify(answers, CONTENT_PACK);
    const obligations = deriveObligations(classification, answers, CONTENT_PACK);
    expect(nextDeadline(obligations, '2026-07-04')).toBe('2027-12-02');
  });

  it('liefert null, wenn alle Fristen verstrichen sind', () => {
    const answers: AssessmentAnswers = { ...base, annexIIICategories: ['a3-employment'] };
    const classification = classify(answers, CONTENT_PACK);
    const obligations = deriveObligations(classification, answers, CONTENT_PACK);
    expect(nextDeadline(obligations, '2030-01-01')).toBeNull();
  });
});
