/**
 * Tests for Provider Profile Data Structure Types
 * Story 4.4: Provider Switching
 */

import { describe, it, expect } from 'vitest';
import {
  ProviderProfile,
  SavedProviders,
  ProviderMigrationState,
} from './settings';

describe('Provider Profile Data Structure', () => {
  describe('ProviderProfile interface', () => {
    it('should have required fields for a complete profile', () => {
      const profile: ProviderProfile = {
        id: 'provider-123',
        name: 'Test Provider',
        baseUrl: 'https://api.example.com/v1',
        apiKey: 'sk-test-key',
        modelName: 'test-model',
        createdAt: '2024-01-01T00:00:00.000Z',
        updatedAt: '2024-01-01T00:00:00.000Z',
      };

      expect(profile.id).toBe('provider-123');
      expect(profile.name).toBe('Test Provider');
      expect(profile.baseUrl).toBe('https://api.example.com/v1');
      expect(profile.apiKey).toBe('sk-test-key');
      expect(profile.modelName).toBe('test-model');
      expect(profile.createdAt).toBe('2024-01-01T00:00:00.000Z');
      expect(profile.updatedAt).toBe('2024-01-01T00:00:00.000Z');
    });

    it('should accept ISO 8601 timestamp strings for dates', () => {
      const now = new Date().toISOString();
      const profile: ProviderProfile = {
        id: 'test',
        name: 'Test',
        baseUrl: 'https://api.test.com/v1',
        apiKey: 'key',
        modelName: 'model',
        createdAt: now,
        updatedAt: now,
      };

      expect(profile.createdAt).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
      expect(profile.updatedAt).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
    });
  });

  describe('SavedProviders interface', () => {
    it('should contain profiles array and activeProviderId', () => {
      const savedProviders: SavedProviders = {
        profiles: [
          {
            id: 'provider-1',
            name: 'OpenAI',
            baseUrl: 'https://api.openai.com/v1',
            apiKey: 'sk-key1',
            modelName: 'gpt-4o',
            createdAt: '2024-01-01T00:00:00.000Z',
            updatedAt: '2024-01-01T00:00:00.000Z',
          },
          {
            id: 'provider-2',
            name: 'DeepSeek',
            baseUrl: 'https://api.deepseek.com/v1',
            apiKey: 'sk-key2',
            modelName: 'deepseek-chat',
            createdAt: '2024-01-01T00:00:00.000Z',
            updatedAt: '2024-01-01T00:00:00.000Z',
          },
        ],
        activeProviderId: 'provider-1',
      };

      expect(savedProviders.profiles).toHaveLength(2);
      expect(savedProviders.activeProviderId).toBe('provider-1');
    });

    it('should allow null activeProviderId when no provider is active', () => {
      const savedProviders: SavedProviders = {
        profiles: [],
        activeProviderId: null,
      };

      expect(savedProviders.profiles).toHaveLength(0);
      expect(savedProviders.activeProviderId).toBeNull();
    });

    it('should allow empty profiles array', () => {
      const savedProviders: SavedProviders = {
        profiles: [],
        activeProviderId: null,
      };

      expect(savedProviders.profiles).toEqual([]);
    });
  });

  describe('ProviderMigrationState interface', () => {
    it('should track migration status with timestamp', () => {
      const migrationState: ProviderMigrationState = {
        hasMigrated: true,
        migratedAt: '2024-01-24T12:00:00.000Z',
      };

      expect(migrationState.hasMigrated).toBe(true);
      expect(migrationState.migratedAt).toBe('2024-01-24T12:00:00.000Z');
    });

    it('should allow migratedAt to be undefined when not migrated', () => {
      const migrationState: ProviderMigrationState = {
        hasMigrated: false,
      };

      expect(migrationState.hasMigrated).toBe(false);
      expect(migrationState.migratedAt).toBeUndefined();
    });

    it('should default to not migrated', () => {
      const migrationState: ProviderMigrationState = {
        hasMigrated: false,
      };

      expect(migrationState.hasMigrated).toBe(false);
    });
  });

  describe('Type compatibility', () => {
    it('should allow omitting id, createdAt, updatedAt for creating new profiles', () => {
      // This tests that Omit<ProviderProfile, 'id' | 'createdAt' | 'updatedAt'> works
      type NewProviderProfile = Omit<ProviderProfile, 'id' | 'createdAt' | 'updatedAt'>;

      const newProfile: NewProviderProfile = {
        name: 'New Provider',
        baseUrl: 'https://api.new.com/v1',
        apiKey: 'sk-new-key',
        modelName: 'new-model',
      };

      expect(newProfile.name).toBe('New Provider');
      expect(newProfile.baseUrl).toBe('https://api.new.com/v1');
      expect(newProfile.apiKey).toBe('sk-new-key');
      expect(newProfile.modelName).toBe('new-model');
    });

    it('should allow partial updates to profiles', () => {
      // This tests that Partial<Omit<ProviderProfile, 'id' | 'createdAt'>> works
      type ProfileUpdate = Partial<Omit<ProviderProfile, 'id' | 'createdAt'>>;

      const update: ProfileUpdate = {
        name: 'Updated Name',
        modelName: 'updated-model',
      };

      expect(update.name).toBe('Updated Name');
      expect(update.modelName).toBe('updated-model');
    });
  });
});
