/**
 * API Versioning module — unit tests.
 */

import { describe, it, expect } from 'vitest';
import {
  CreateApiVersionSchema,
  UpdateApiVersionSchema,
  PinClientVersionSchema,
  UpdateClientPinSchema,
} from './types.js';

describe('CreateApiVersionSchema', () => {
  it('validates minimal version', () => {
    const result = CreateApiVersionSchema.safeParse({
      version: 'v1',
      label: 'Initial Release',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.status).toBe('draft');
      expect(result.data.breakingChanges).toEqual([]);
    }
  });

  it('validates with all fields', () => {
    const result = CreateApiVersionSchema.safeParse({
      version: '2024-01-15',
      label: 'January 2024 Release',
      status: 'active',
      releasedAt: '2024-01-15T00:00:00.000Z',
      migrationGuide: '# Migration from v1\n\n- Rename field X to Y',
      breakingChanges: ['Renamed /users to /accounts', 'Changed auth flow'],
      addedEndpoints: ['POST /api/widgets', 'GET /api/widgets/:id'],
      removedEndpoints: ['DELETE /api/legacy'],
      modifiedEndpoints: ['PATCH /api/users → PATCH /api/accounts'],
    });
    expect(result.success).toBe(true);
  });

  it('rejects invalid version chars', () => {
    expect(CreateApiVersionSchema.safeParse({ version: 'v1 beta', label: 'Test' }).success).toBe(
      false
    );
  });

  it('rejects empty version', () => {
    expect(CreateApiVersionSchema.safeParse({ version: '', label: 'Test' }).success).toBe(false);
  });

  it('rejects invalid status', () => {
    expect(
      CreateApiVersionSchema.safeParse({ version: 'v1', label: 'Test', status: 'archived' }).success
    ).toBe(false);
  });

  it('validates date-based version', () => {
    const result = CreateApiVersionSchema.safeParse({
      version: '2025-06-01',
      label: 'June 2025',
    });
    expect(result.success).toBe(true);
  });
});

describe('UpdateApiVersionSchema', () => {
  it('validates partial update', () => {
    const result = UpdateApiVersionSchema.safeParse({
      status: 'deprecated',
      deprecatedAt: '2024-06-01T00:00:00.000Z',
      sunsetAt: '2024-12-01T00:00:00.000Z',
    });
    expect(result.success).toBe(true);
  });

  it('validates migration guide update', () => {
    expect(
      UpdateApiVersionSchema.safeParse({
        migrationGuide: '# New migration steps\n\nFollow these steps...',
      }).success
    ).toBe(true);
  });

  it('validates null deprecatedAt (to clear)', () => {
    expect(UpdateApiVersionSchema.safeParse({ deprecatedAt: null }).success).toBe(true);
  });
});

describe('PinClientVersionSchema', () => {
  it('validates minimal pin', () => {
    const result = PinClientVersionSchema.safeParse({
      clientId: 'app-ios-v3',
      pinnedVersion: 'v1',
      reason: 'Legacy iOS app needs v1 until next release',
    });
    expect(result.success).toBe(true);
  });

  it('validates with auto-upgrade', () => {
    const result = PinClientVersionSchema.safeParse({
      clientId: 'api-key-xyz',
      pinnedVersion: '2024-01-15',
      reason: 'Partner integration locked to January version',
      autoUpgradeAt: '2025-01-01T00:00:00.000Z',
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty clientId', () => {
    expect(
      PinClientVersionSchema.safeParse({
        clientId: '',
        pinnedVersion: 'v1',
        reason: 'test',
      }).success
    ).toBe(false);
  });

  it('rejects empty reason', () => {
    expect(
      PinClientVersionSchema.safeParse({
        clientId: 'app-1',
        pinnedVersion: 'v1',
        reason: '',
      }).success
    ).toBe(false);
  });
});

describe('UpdateClientPinSchema', () => {
  it('validates version change', () => {
    expect(UpdateClientPinSchema.safeParse({ pinnedVersion: 'v2' }).success).toBe(true);
  });

  it('validates reason change', () => {
    expect(UpdateClientPinSchema.safeParse({ reason: 'Updated integration' }).success).toBe(true);
  });

  it('validates null autoUpgradeAt (to clear)', () => {
    expect(UpdateClientPinSchema.safeParse({ autoUpgradeAt: null }).success).toBe(true);
  });
});
