/**
 * Tests for VisionTool vision model selection — catalog-driven.
 * Uses recommended_for and tier from the catalog instead of name lists.
 */

import { describe, test, expect } from '@jest/globals';

function selectVisionModel(models, context = {}) {
  const visionModels = (models || []).filter(m => m.supportsVision === true);
  if (visionModels.length === 0) return null;

  // 1. Model recommended for vision
  const recommended = visionModels.find(m => m.recommended_for?.includes('vision'));
  if (recommended) return recommended.name;

  // 2. Budget-tier vision model
  const budget = visionModels.find(m => m.tier === 'budget');
  if (budget) return budget.name;

  // 3. Agent's current model
  const agentModel = context.currentModel;
  if (agentModel && visionModels.some(m => m.name === agentModel)) return agentModel;

  // 4. First available
  return visionModels[0].name;
}

const ALL_MODELS = [
  { name: 'o4-mini', supportsVision: true, recommended_for: ['vision', 'reasoning', 'default'], tier: 'budget' },
  { name: 'gpt-5-mini', supportsVision: true, recommended_for: ['vision', 'default'], tier: 'budget' },
  { name: 'Kimi-K2.5', supportsVision: true, recommended_for: ['vision'], tier: 'budget' },
  { name: 'gpt-5.4', supportsVision: false, recommended_for: ['creative'], tier: 'standard' },
  { name: 'grok-4', supportsVision: true, recommended_for: [], tier: 'standard' },
  { name: 'DeepSeek-V3.2', supportsVision: false, recommended_for: [], tier: 'budget' },
  { name: 'gpt-5.3-codex', supportsVision: false, recommended_for: ['coding'], tier: 'standard' },
];

describe('VisionTool model selection (catalog-driven)', () => {

  test('selects model recommended for vision', () => {
    expect(selectVisionModel(ALL_MODELS)).toBe('o4-mini');
  });

  test('selects budget vision model when no recommended_for match', () => {
    const models = ALL_MODELS.map(m => ({ ...m, recommended_for: [] }));
    expect(selectVisionModel(models)).toBe('o4-mini'); // still budget + vision
  });

  test('skips non-vision models even if recommended', () => {
    const models = [
      { name: 'non-vision', supportsVision: false, recommended_for: ['vision'], tier: 'budget' },
      { name: 'actual-vision', supportsVision: true, recommended_for: [], tier: 'standard' },
    ];
    expect(selectVisionModel(models)).toBe('actual-vision');
  });

  test('uses agent current model when no recommended/budget match', () => {
    const models = [
      { name: 'premium-vision', supportsVision: true, recommended_for: [], tier: 'premium' },
      { name: 'agent-model', supportsVision: true, recommended_for: [], tier: 'premium' },
    ];
    expect(selectVisionModel(models, { currentModel: 'agent-model' })).toBe('agent-model');
  });

  test('falls back to first available', () => {
    const models = [
      { name: 'only-option', supportsVision: true, recommended_for: [], tier: 'premium' },
    ];
    expect(selectVisionModel(models)).toBe('only-option');
  });

  test('returns null when no vision models', () => {
    expect(selectVisionModel([{ name: 'text-only', supportsVision: false }])).toBeNull();
    expect(selectVisionModel([])).toBeNull();
    expect(selectVisionModel(null)).toBeNull();
  });

  test('no hardcoded model names in selection logic', () => {
    // All models are fictional — proves zero name dependence
    const models = [
      { name: 'xyz-model-alpha', supportsVision: true, recommended_for: ['vision'], tier: 'budget' },
      { name: 'abc-model-beta', supportsVision: true, recommended_for: [], tier: 'standard' },
    ];
    expect(selectVisionModel(models)).toBe('xyz-model-alpha');
  });
});
