import { validate } from 'class-validator';
import { SaveAiConfigDto, TestAiConfigDto } from './ai-config.dto';
import { AiProvider } from '../ai-config.entity';

describe('SaveAiConfigDto', () => {
  it('validates a correct OPENAI config', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('validates a correct DEEPSEEK config', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.DEEPSEEK;
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('fixed provider can omit baseUrl', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('fixed provider can provide baseUrl (valid string)', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    dto.baseUrl = 'https://api.openai.com/v1';
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('OPENAI_COMPATIBLE must provide baseUrl', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI_COMPATIBLE;
    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    expect(errors[0].constraints).toHaveProperty('isNotEmpty');
  });

  it('OPENAI_COMPATIBLE with baseUrl passes', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI_COMPATIBLE;
    dto.baseUrl = 'https://custom.api.com/v1';
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('OPENAI_COMPATIBLE with empty baseUrl fails', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI_COMPATIBLE;
    dto.baseUrl = '';
    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    expect(errors[0].constraints).toHaveProperty('isNotEmpty');
  });

  it('invalid provider fails', async () => {
    const dto = new SaveAiConfigDto();
    (dto as Record<string, unknown>).provider = 'INVALID';
    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    expect(errors[0].constraints).toHaveProperty('isIn');
  });

  it('timeoutMs outside range fails', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    dto.timeoutMs = 500;
    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
  });

  it('apiKey is optional string', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    dto.apiKey = 'sk-test-1234';
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('defaultModel is optional string', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    dto.defaultModel = 'gpt-4';
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('enabled is optional boolean', async () => {
    const dto = new SaveAiConfigDto();
    dto.provider = AiProvider.OPENAI;
    dto.enabled = true;
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });
});

describe('TestAiConfigDto', () => {
  it('empty DTO is valid (all fields optional)', async () => {
    const dto = new TestAiConfigDto();
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('partial fields validate', async () => {
    const dto = new TestAiConfigDto();
    dto.provider = AiProvider.OPENAI_COMPATIBLE;
    dto.baseUrl = 'https://custom.api.com/v1';
    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('invalid provider fails', async () => {
    const dto = new TestAiConfigDto();
    (dto as Record<string, unknown>).provider = 'INVALID';
    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
  });

  it('timeoutMs outside range fails', async () => {
    const dto = new TestAiConfigDto();
    dto.timeoutMs = 0;
    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
  });
});
